From d9d5bb308e215bb16ee450d306fe87bd19176b6a Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sun, 1 Nov 2015 01:47:42 +0100 Subject: [PATCH] Many fixes * Profile.aspx: * ProfileEdition.cs: Fixes the username modification * Book-next.aspx: pollution * NpgsqlMembershipProvider.cs: xmldoc * NpgsqlProfileProvider.cs: use default values from configuration * NpgsqlUserNameProvider.cs: Fixes the username detection * test-domain-TestAPI.config: profile dates must be returned as DateTime * instdbws.sql: The conversion to a valid .Net DateTime requires a credible date time as source value, the null one is not supported. * style.css: Fixes the new notification style * AccountController.cs: Fixes the profile edition. Now using the anti forgery key at login time * Book.aspx: * LocalizedText.resx: * LocalizedText.fr.resx: * CalendarApi.cs: * GoogleController.cs: * LocalizedText.Designer.cs: * LocalizedText.fr.Designer.cs: WIP booking * HomeController.cs: code prettying * Global.asax.cs: Limits the usage of titles in a route to the blog controller * OAuth2.cs: Profile values may be of type DBNull ... * T.cs: All translated strings will be Html encoded, as expected from an html helper * YavscHelpers.cs: A new method to build a javascript string... * App.master: * AppAdmin.master: Notification.body is now a js string literal * NoLogin.master: sync with the true master * Login.aspx: Permits the anti forgery key usage * Estimate.aspx: refactoring * Web.config: Fixes a later commit on the catalog name space * Web.csproj: An ajax helper to notify * ChangePasswordModel.cs: * RegisterClientModel.cs: A regexp for user name * LoginModel.cs: A regexp for user name and password * Profile.cs: A regexp for user name, and profile usage fixes * UserManager.cs: Checks for username availability before trying to modify it * YavscModel.csproj: `ProfileEdition` class addition * ChangeLog: should not be indexed * ChangeLog: useless here * ValidateAjaxAttribute.cs: Fixes usage of HtmlFieldPrefix * BookQuery.cs: Start, end hour and role are required * OtherWebException.cs: useless --- NpgsqlMRPProviders/ChangeLog | 9 ++ .../NpgsqlMembershipProvider.cs | 8 +- NpgsqlMRPProviders/NpgsqlProfileProvider.cs | 20 ++++- NpgsqlMRPProviders/NpgsqlUserNameProvider.cs | 2 +- TestAPI/ChangeLog | 5 ++ TestAPI/test-domain-TestAPI.config | 4 +- web/App_Data/instdbws.sql | 4 +- web/App_Themes/style.css | 16 ++-- web/ChangeLog | 69 +++++++++++++++ web/Controllers/AccountController.cs | 50 ++++++----- web/Controllers/GoogleController.cs | 76 +++++++++------- web/Controllers/HomeController.cs | 3 +- web/Global.asax.cs | 4 +- web/Helpers/Google/CalendarApi.cs | 8 +- web/Helpers/Google/OAuth2.cs | 7 +- web/Helpers/T.cs | 4 +- web/Helpers/YavscHelpers.cs | 36 +++----- web/Models/App.master | 4 +- web/Models/AppAdmin.master | 7 +- web/Models/NoLogin.master | 88 ++++++++++--------- web/ValidateAjaxAttribute.cs | 3 +- web/Views/Account/Login.aspx | 1 + web/Views/Account/Profile.aspx | 16 ++-- web/Views/FrontOffice/Estimate.aspx | 6 +- web/Views/Google/Book-next.aspx | 73 --------------- web/Views/Google/Book.aspx | 8 +- web/Web.config | 20 ++--- web/Web.csproj | 2 +- yavscModel/Calendar/BookQuery.cs | 4 +- yavscModel/ChangeLog | 36 ++++++++ yavscModel/LocalizedText.Designer.cs | 12 +++ yavscModel/LocalizedText.fr.Designer.cs | 28 ++++-- yavscModel/LocalizedText.fr.resx | 2 + yavscModel/LocalizedText.resx | 2 + yavscModel/OtherWebException.cs | 2 +- .../RolesAndMembers/ChangePasswordModel.cs | 2 +- yavscModel/RolesAndMembers/LoginModel.cs | 5 +- yavscModel/RolesAndMembers/Profile.cs | 14 +-- yavscModel/RolesAndMembers/ProfileEdition.cs | 46 ++++++++++ .../RolesAndMembers/RegisterClientModel.cs | 3 +- yavscModel/RolesAndMembers/UserManager.cs | 6 ++ yavscModel/YavscModel.csproj | 1 + 42 files changed, 441 insertions(+), 275 deletions(-) delete mode 100644 web/Views/Google/Book-next.aspx create mode 100644 yavscModel/RolesAndMembers/ProfileEdition.cs diff --git a/NpgsqlMRPProviders/ChangeLog b/NpgsqlMRPProviders/ChangeLog index 93838543..1dc6a850 100644 --- a/NpgsqlMRPProviders/ChangeLog +++ b/NpgsqlMRPProviders/ChangeLog @@ -1,3 +1,12 @@ +2015-11-01 Paul Schneider + + * NpgsqlMembershipProvider.cs: xmldoc + + * NpgsqlProfileProvider.cs: use default values from + configuration + + * NpgsqlUserNameProvider.cs: Fixes the username detection + 2015-10-28 Paul Schneider * NpgsqlProfileProvider.cs: Fixes the defaultValue diff --git a/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs b/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs index 4e6a8240..72b9d9d0 100644 --- a/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs +++ b/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs @@ -951,11 +951,13 @@ namespace Npgsql.Web // // MembershipProvider.ValidateUser // - /// To be added. + /// Validates an user identification by password, + /// and, when he's approuved, updates its last login date and + /// returns true. /// - /// Validates the user. + /// Validates the user at login time. /// - /// true, if user was validated, false otherwise. + /// true, if user was approuved and its password is valid, false otherwise. /// Username. /// Password. public override bool ValidateUser (string username, string password) diff --git a/NpgsqlMRPProviders/NpgsqlProfileProvider.cs b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs index 0340c589..96bc17c3 100644 --- a/NpgsqlMRPProviders/NpgsqlProfileProvider.cs +++ b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs @@ -221,7 +221,7 @@ namespace Npgsql.Web } else { foreach (SettingsProperty p in collection) { SettingsPropertyValue v = new SettingsPropertyValue (p); - v.PropertyValue = p.DefaultValue; + v.PropertyValue = GetDefaultValue(p); c.Add (v); } } @@ -230,6 +230,24 @@ namespace Npgsql.Web return c; } + + private object GetDefaultValue(SettingsProperty setting) + { + if (setting.PropertyType.IsEnum) + return Enum.Parse(setting.PropertyType, setting.DefaultValue.ToString()); + + // Return the default value if it is set + // Return the default value if it is set + if (setting.DefaultValue != null) + { + System.ComponentModel.TypeConverter tc = System.ComponentModel.TypeDescriptor.GetConverter(setting.PropertyType); + return tc.ConvertFromString(setting.DefaultValue.ToString()); + } + else // If there is no default value return the default object + { + return Activator.CreateInstance(setting.PropertyType); + } + } /// /// Sets the property values. /// diff --git a/NpgsqlMRPProviders/NpgsqlUserNameProvider.cs b/NpgsqlMRPProviders/NpgsqlUserNameProvider.cs index 49692be4..d7298077 100644 --- a/NpgsqlMRPProviders/NpgsqlUserNameProvider.cs +++ b/NpgsqlMRPProviders/NpgsqlUserNameProvider.cs @@ -91,7 +91,7 @@ namespace Npgsql.Web.RolesAndMembers using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { conn.Open (); using (NpgsqlCommand cmd = new NpgsqlCommand ( - "SELECT count(*)>0 FROM users " + + "SELECT count(*)=0 FROM users " + "WHERE username = :uname AND ApplicationName = :appname", conn)) { cmd.Parameters.AddWithValue ("uname", name); cmd.Parameters.AddWithValue ("appname", this.applicationName); diff --git a/TestAPI/ChangeLog b/TestAPI/ChangeLog index 62d6bb37..10bc3ce1 100644 --- a/TestAPI/ChangeLog +++ b/TestAPI/ChangeLog @@ -1,3 +1,8 @@ +2015-11-01 Paul Schneider + + * test-domain-TestAPI.config: profile dates must be returned + as DateTime + 2015-10-17 Paul Schneider * AllTests.cs: diff --git a/TestAPI/test-domain-TestAPI.config b/TestAPI/test-domain-TestAPI.config index dcc7e6c2..5829b40d 100644 --- a/TestAPI/test-domain-TestAPI.config +++ b/TestAPI/test-domain-TestAPI.config @@ -92,8 +92,8 @@ - - + + diff --git a/web/App_Data/instdbws.sql b/web/App_Data/instdbws.sql index 4803e91a..e8a0c2ad 100644 --- a/web/App_Data/instdbws.sql +++ b/web/App_Data/instdbws.sql @@ -118,7 +118,7 @@ CREATE TABLE profiledata grefreshtoken character varying(512), -- Google refresh token gtokentype character varying(256), -- Google access token type gcalid character varying(255), -- Google calendar identifier - gtokenexpir timestamp with time zone, -- Google access token expiration date + gtokenexpir timestamp with time zone NOT NULL DEFAULT now(), -- Google access token expiration date avatar character varying(512), -- url for an avatar gcalapi boolean NOT NULL DEFAULT false, gregid character varying(1024), -- Google Cloud Message registration identifier @@ -211,7 +211,7 @@ CREATE TABLE commandes id bigserial NOT NULL, -- Identifiant unique de commande e, cours validation date, -- Date de validation prdref character varying(255) NOT NULL, -- Product reference from the unique valid catalog at the validation date - creation timestamp with time zone, -- creation date + creation timestamp with time zone NOT NULL, -- creation date clientname character varying(255), -- user who created the command, client of this command applicationname character varying(255), -- application concerned by this command params json, diff --git a/web/App_Themes/style.css b/web/App_Themes/style.css index 9e91e974..def6e990 100644 --- a/web/App_Themes/style.css +++ b/web/App_Themes/style.css @@ -34,8 +34,7 @@ body { z-index: 1000; top: 0; left: 0; - height: 100%; - width: 100%; + right: 0; overflow: scroll; } @@ -60,7 +59,7 @@ header { transition: margin 2s, padding 2s; padding: 0; margin: 0; - padding-top: 201px; + padding-top: 2em; padding-bottom:2em; display: block; background: url("/images/star-939235_1280.jpg") -3em -3em no-repeat fixed; @@ -145,8 +144,8 @@ aside { border-radius:1em; } .postpreview video, .postpreview img { - max-width:100%; - max-height:5em; + max-width: 100%; + padding: 1em; } .post { display:block; @@ -266,7 +265,7 @@ a { .actionlink, .menuitem, a { display:inline-block; - color: white; + color: yellow; border-radius:1em; border: solid black 1px; background-color: rgba(20,20,20,.8); @@ -340,6 +339,7 @@ a:active { @media all and (max-width: 640px) { header { + padding-top:1em; padding-bottom:1em; background: url("/images/star-939235_1280.s.jpg") 0 0 no-repeat fixed; } @@ -394,8 +394,8 @@ header h1, header a , .actionlink, .menuitem, a { padding:.5em;} @media all and (max-width: 350px) { header { - padding-top: 101px; - padding-bottom:1em; + padding-top:.5em; + padding-bottom:.5em; background: url("/images/star-939235_1280.xxs.jpg") 0 0 no-repeat fixed; } header h1, header a { padding:.2em;} diff --git a/web/ChangeLog b/web/ChangeLog index cdda226f..07581992 100644 --- a/web/ChangeLog +++ b/web/ChangeLog @@ -1,3 +1,72 @@ +2015-11-01 Paul Schneider + + * Book-next.aspx: pollution + + * instdbws.sql: The conversion to a valid .Net DateTime + requires a credible date time as source value, the null one is + not supported. + + * style.css: Fixes the new notification style + + * AccountController.cs: Fixes the profile edition. + Now using the anti forgery key at login time + + * Book.aspx: + * CalendarApi.cs: + * GoogleController.cs: WIP booking + + * HomeController.cs: code prettying + + * Global.asax.cs: Limits the usage of titles in a route to the + blog controller + + * OAuth2.cs: Profile values may be of type DBNull ... + + * T.cs: All translated strings will be Html encoded, as + expected from an html helper + + * YavscHelpers.cs: A new method to build a javascript + string... + + * App.master: + * AppAdmin.master: Notification.body is now a js string + literal + + * NoLogin.master: sync with the true master + + * Login.aspx: Permits the anti forgery key usage + + * Profile.aspx: Fixes the username modification + + * Estimate.aspx: refactoring + + * Web.config: Fixes a later commit on the catalog name space + + * Web.csproj: An ajax helper to notify + + * ChangeLog: should not be indexed + + * ValidateAjaxAttribute.cs: Fixes usage of HtmlFieldPrefix + +2015-10-31 Paul Schneider + + * Web.csproj: + * Web.config: + * T.cs: + * Global.asax.cs: + * App.master: + * Book.aspx: + * YavscHelpers.cs: + * OAuth2.cs: + * Profile.aspx: + * YavscAjaxHelper.cs: + * Book-next.aspx: + * CalendarApi.cs: + * HomeController.cs: + * GoogleController.cs: + * Estimate.aspx: + * AccountController.cs: + 2015-10-30 Paul Schneider * packages.config: diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs index 7f4d7321..53ed2338 100644 --- a/web/Controllers/AccountController.cs +++ b/web/Controllers/AccountController.cs @@ -16,6 +16,7 @@ using System.Collections.Specialized; using System.Text; using System.Net; using System.Configuration; +using Yavsc.Model; namespace Yavsc.Controllers { @@ -61,7 +62,7 @@ namespace Yavsc.Controllers /// The login. /// Model. /// Return URL. - [HttpPost] + [HttpPost,ValidateAntiForgeryToken] public ActionResult Login (LoginModel model, string returnUrl) { if (ModelState.IsValid) { @@ -187,7 +188,7 @@ namespace Yavsc.Controllers ViewData ["UserName"] = id; if (!confirmed) return View (); - string logged = Membership.GetUser ().UserName; + string logged = this.User.Identity.Name; if (logged != id) if (!Roles.IsUserInRole ("Admin")) throw new Exception ("Unregister another user"); @@ -250,7 +251,7 @@ namespace Yavsc.Controllers if (id == null) id = Membership.GetUser ().UserName; ViewData ["UserName"] = id; - Profile model = new Profile (ProfileBase.Create (id)); + ProfileEdition model = new ProfileEdition (ProfileBase.Create (id)); model.RememberMe = FormsAuthentication.GetAuthCookie (id, true) == null; return View (model); } @@ -265,20 +266,32 @@ namespace Yavsc.Controllers /// Avatar file. [Authorize] [HttpPost] - public ActionResult Profile (string id, Profile model, HttpPostedFileBase AvatarFile) + public ActionResult Profile (string id, ProfileEdition model, HttpPostedFileBase AvatarFile) { - // ASSERT("Membership.GetUser ().UserName is made of simple characters, no slash nor backslash" - - string logdu = Membership.GetUser ().UserName; - if (string.IsNullOrWhiteSpace (id)) - id = logdu; + string logdu = User.Identity.Name; + if (string.IsNullOrWhiteSpace (id)) { + if (string.IsNullOrWhiteSpace (model.UserName)) { + model.UserName = logdu; + return View (model); + } else { + id = logdu; + } + } ViewData ["UserName"] = id; - bool editsMyName = (string.Compare(id,logdu)==0); - if (!editsMyName) + bool editsTheUserName = model.NewUserName!=null&&(string.Compare(id,model.NewUserName)!=0); + // Checks authorisation + if (logdu!=id) if (!Roles.IsUserInRole ("Admin")) if (!Roles.IsUserInRole ("FrontOffice")) throw new UnauthorizedAccessException ("Your are not authorized to modify this profile"); - + // checks availability of a new username + if (editsTheUserName) + if (!UserManager.IsAvailable (model.NewUserName)) + ModelState.AddModelError ("UserName", + string.Format ( + LocalizedText.DuplicateUserName, + model.NewUserName + )); if (AvatarFile != null) { // if said valid, move as avatar file // else invalidate the model @@ -295,10 +308,6 @@ namespace Yavsc.Controllers string.Format ("Image type {0} is not supported (suported formats : {1})", AvatarFile.ContentType, "image/png")); } - /* Sync the property in the Profile model to display : - * string cAvat = HttpContext.Profile.GetPropertyValue ("Avatar") as string; - if (cAvat != null) if (model.avatar == null) model.avatar = cAvat; - */ if (ModelState.IsValid) { ProfileBase prf = ProfileBase .Create (id); prf.SetPropertyValue ("Name", model.Name); @@ -328,11 +337,12 @@ namespace Yavsc.Controllers prf.SetPropertyValue ("gcalid", model.GoogleCalendar); prf.Save (); - if (editsMyName) { - UserManager.ChangeName (id, model.Name); - FormsAuthentication.SetAuthCookie (model.Name, model.RememberMe); + if (editsTheUserName) { + UserManager.ChangeName (id, model.NewUserName); + FormsAuthentication.SetAuthCookie (model.NewUserName, model.RememberMe); + model.UserName = model.NewUserName; } - YavscHelpers.Notify(ViewData, "Profile enregistré"+((editsMyName)?", nom public inclu.":"")); + YavscHelpers.Notify(ViewData, "Profile enregistré"+((editsTheUserName)?", nom public inclu.":"")); } return View (model); } diff --git a/web/Controllers/GoogleController.cs b/web/Controllers/GoogleController.cs index b8092d61..5fefd126 100644 --- a/web/Controllers/GoogleController.cs +++ b/web/Controllers/GoogleController.cs @@ -112,7 +112,7 @@ namespace Yavsc.Controllers YavscHelpers.Notify(ViewData, msg); return View ("Auth"); } - SaveToken (gat); + SaveToken (HttpContext.Profile,gat); HttpContext.Profile.SetPropertyValue ("gcalapi", true); string returnUrl = (string)Session ["returnUrl"]; Session ["returnUrl"] = null; @@ -126,14 +126,14 @@ namespace Yavsc.Controllers /// order to save a descent value as expiration date. /// /// Gat. - private void SaveToken (AuthToken gat) + private void SaveToken (ProfileBase pr, AuthToken gat) { - HttpContext.Profile.SetPropertyValue ("gtoken", gat.access_token); + pr.SetPropertyValue ("gtoken", gat.access_token); if (gat.refresh_token != null) - HttpContext.Profile.SetPropertyValue ("grefreshtoken", gat.refresh_token); - HttpContext.Profile.SetPropertyValue ("gtokentype", gat.token_type); - HttpContext.Profile.SetPropertyValue ("gtokenexpir", DateTime.Now.AddSeconds (gat.expires_in)); - HttpContext.Profile.Save (); + pr.SetPropertyValue ("grefreshtoken", gat.refresh_token); + pr.SetPropertyValue ("gtokentype", gat.token_type); + pr.SetPropertyValue ("gtokenexpir", DateTime.Now.AddSeconds (gat.expires_in)); + pr.Save (); } /// @@ -161,7 +161,9 @@ namespace Yavsc.Controllers // just set this user as logged on foreach (MembershipUser u in mbrs) { string username = u.UserName; - FormsAuthentication.SetAuthCookie (username, true); + FormsAuthentication.SetAuthCookie (username, true); + /* var upr = ProfileBase.Create (username); + SaveToken (upr,gat); */ } Session ["returnUrl"] = null; return Redirect (returnUrl); @@ -230,7 +232,7 @@ namespace Yavsc.Controllers } if (me.url != null) HttpContext.Profile.SetPropertyValue ("WebSite", me.url); - SaveToken (gat); + SaveToken (HttpContext.Profile,gat); // already done in SaveToken: HttpContext.Profile.Save (); return Redirect (returnUrl); } @@ -256,7 +258,6 @@ namespace Yavsc.Controllers [HttpGet] public ActionResult ChooseCalendar (string returnUrl) { - bool hasCalAuth = (bool)HttpContext.Profile.GetPropertyValue ("gcalapi"); if (!hasCalAuth) { Session ["returnUrl"] = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/ChooseCalendar"; @@ -296,8 +297,7 @@ namespace Yavsc.Controllers /// Dates the query. /// /// The query. - [Authorize] - [HttpGet] + [Authorize,HttpGet] public ActionResult Book () { return View (new BookQuery ()); @@ -308,42 +308,50 @@ namespace Yavsc.Controllers /// /// The query. /// Model. - [Authorize] - [HttpPost] + [Authorize,HttpPost] public ActionResult Book (BookQuery model) { if (ModelState.IsValid) { DateTime mindate = DateTime.Now; - if (model.StartDate < mindate) - model.StartDate = mindate; - if (model.EndDate < mindate) - model.EndDate = mindate.AddYears (1).Date; + if (model.StartDate < mindate){ + ModelState.AddModelError ("StartDate", LocalizedText.FillInAFutureDate); + } + if (model.EndDate < model.StartDate) + ModelState.AddModelError ("EndDate", LocalizedText.StartDateAfterEndDate); var muc = Membership.FindUsersByName (model.Person); if (muc.Count == 0) { ModelState.AddModelError ("Person", LocalizedText.Non_existent_user); - return View (model); } if (!Roles.IsUserInRole (model.Role)) { ModelState.AddModelError ("Role", LocalizedText.UserNotInThisRole); - return View (model); } - ProfileBase upr = ProfileBase.Create (model.Person); - - string calid = (string)upr.GetPropertyValue ("gcalid"); - if (string.IsNullOrWhiteSpace (calid)) { + var gcalid = upr.GetPropertyValue ("gcalid"); + if (gcalid is DBNull) ModelState.AddModelError ("Person", LocalizedText.No_calendar_for_this_user); - return View (model); - } - DateTime maxdate = model.EndDate; - CalendarApi c = new CalendarApi (); - CalendarEventList res; - try { - var events = c.GetCalendar (calid, mindate, maxdate, upr); - - } catch (OtherWebException ex) { - return View ("OtherWebException", ex); + if (ModelState.IsValid) { + string calid = (string) gcalid; + DateTime maxdate = model.EndDate; + CalendarApi c = new CalendarApi (); + CalendarEventList events; + try { + events = c.GetCalendar (calid, mindate, maxdate, upr); + YavscHelpers.Notify (ViewData, "Google calendar API call success"); + } catch (WebException ex) { + string response; + using (var stream = ex.Response.GetResponseStream()) + using (var reader = new StreamReader(stream)) + { + response = reader.ReadToEnd(); + } + YavscHelpers.Notify (ViewData, + string.Format( + "Google calendar API exception {0} : {1}
{2}
", + ex.Status.ToString(), + ex.Message, + response)); + } } } return View (model); diff --git a/web/Controllers/HomeController.cs b/web/Controllers/HomeController.cs index c06d9aa4..9a1d6c9a 100644 --- a/web/Controllers/HomeController.cs +++ b/web/Controllers/HomeController.cs @@ -92,7 +92,8 @@ namespace Yavsc.Controllers if (!Request.IsAuthenticated) { ProfileBase anonymousProfile = ProfileBase.Create(anonid); object ac = anonymousProfile.GetPropertyValue ("allowcookies"); - if (ac is string && ac!="true") + + if (ac is string && ((string)ac)!="true") YavscHelpers.Notify (ViewData, LocalizedText.ThisSiteUsesCookies, "function(){Yavsc.ajax(\"/Yavsc/AllowCookies\", { id:'"+anonid+"' });}"); } diff --git a/web/Global.asax.cs b/web/Global.asax.cs index 300bbfa7..460e8337 100644 --- a/web/Global.asax.cs +++ b/web/Global.asax.cs @@ -77,8 +77,8 @@ namespace Yavsc ); routes.MapRoute ( "BackCompat", - "{controller}/{action}/{user}/{title}", - new { controller = "Home", action = "Index", user = UrlParameter.Optional, title = UrlParameter.Optional } + "Blogs/{action}/{user}/{title}", + new { controller = "Blogs", action = "Index", user = UrlParameter.Optional, title = UrlParameter.Optional } ); routes.MapRoute ( diff --git a/web/Helpers/Google/CalendarApi.cs b/web/Helpers/Google/CalendarApi.cs index a947d68f..1f686936 100644 --- a/web/Helpers/Google/CalendarApi.cs +++ b/web/Helpers/Google/CalendarApi.cs @@ -106,18 +106,18 @@ namespace Yavsc.Helpers.Google using (Stream respstream = resp.GetResponseStream ()) { try { res = (CalendarEventList) new DataContractJsonSerializer(typeof(CalendarEventList)).ReadObject (respstream); - } catch (Exception ex) { + } catch (Exception ) { respstream.Close (); resp.Close (); webreq.Abort (); - throw ex; + throw ; } } resp.Close (); } - } catch (WebException ex) { + } catch (WebException ) { webreq.Abort (); - throw new OtherWebException (ex); + throw; } webreq.Abort (); return res; diff --git a/web/Helpers/Google/OAuth2.cs b/web/Helpers/Google/OAuth2.cs index 559b7d2d..f1a5bffc 100644 --- a/web/Helpers/Google/OAuth2.cs +++ b/web/Helpers/Google/OAuth2.cs @@ -226,16 +226,15 @@ namespace Yavsc.Helpers.Google public static string GetFreshGoogleCredential (ProfileBase pr) { string token = (string)pr.GetPropertyValue ("gtoken"); - string token_type = (string)pr.GetPropertyValue ("gtokentype"); - DateTime token_exp = (DateTime)pr.GetPropertyValue ("gtokenexpir"); + string token_type = (string) pr.GetPropertyValue ("gtokentype"); + DateTime token_exp = (DateTime) pr.GetPropertyValue ("gtokenexpir"); if (token_exp < DateTime.Now) { object ort = pr.GetPropertyValue ("grefreshtoken"); - if (ort == null) { + if (ort == null || ort is DBNull) { throw new InvalidOAuth2RefreshToken ("Google"); } else { string refresh_token = ort as string; - AuthToken gat = OAuth2.GetTokenPosting ( string.Format ("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}", CLIENT_ID, CLIENT_SECRET, refresh_token)); diff --git a/web/Helpers/T.cs b/web/Helpers/T.cs index fd22098b..36428a98 100644 --- a/web/Helpers/T.cs +++ b/web/Helpers/T.cs @@ -33,10 +33,10 @@ namespace Yavsc.Helpers /// /// Helper. /// Text. - public static string Translate(this HtmlHelper helper, string text) + public static IHtmlString Translate(this HtmlHelper helper, string text) { // Just call the other one, to avoid having two copies (we don't use the HtmlHelper). - return GetString(text); + return new MvcHtmlString(helper.Encode(GetString(text))); } } diff --git a/web/Helpers/YavscHelpers.cs b/web/Helpers/YavscHelpers.cs index 2813c4af..a0d7abcc 100644 --- a/web/Helpers/YavscHelpers.cs +++ b/web/Helpers/YavscHelpers.cs @@ -20,7 +20,6 @@ using Yavsc.Model.Messaging; namespace Yavsc.Helpers { - /// /// Yavsc helpers. /// @@ -62,7 +61,7 @@ namespace Yavsc.Helpers { SendActivationMessage (helper.Route("Default", new { controller="Account", action = "Validate", - key=user.ProviderUserKey.ToString() } ) + key=user.ProviderUserKey.ToString(), id = user.UserName } ) , WebConfigurationManager.AppSettings ["RegistrationMessage"], user); } @@ -73,7 +72,12 @@ namespace Yavsc.Helpers /// User. public static void SendActivationMessage(this System.Web.Mvc.UrlHelper helper, MembershipUser user) { - SendActivationMessage (helper.Content("~/Account/Validate/"+user.UserName+"/?key="+user.ProviderUserKey.ToString()) + SendActivationMessage ( + string.Format("{2}://{3}/Account/Validate/{1}?key={0}", + user.ProviderUserKey.ToString(), user.UserName , + helper.RequestContext.HttpContext.Request.Url.Scheme, + helper.RequestContext.HttpContext.Request.Url.Authority + ) , WebConfigurationManager.AppSettings ["RegistrationMessage"], user); } @@ -221,25 +225,11 @@ namespace Yavsc.Helpers JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(obj); } - - /// - /// Notify the specified helper and message. - /// - /// Helper. - /// Message. - public static void Notify (this HtmlHelper helper, string message) { - Notify (helper.ViewData, message); - } - /// - /// Notify the specified viewData and message. - /// - /// View data. - /// Message. - public static void Notify(ViewDataDictionary viewData, string message, string click_action=null) { - if (viewData ["Notifications"] == null) - viewData ["Notifications"] = new List (); - (viewData ["Notifications"] as List).Add ( - new Notification { body = message.Replace("\'","\\\'"), + public static void Notify(ViewDataDictionary ViewData, string message, string click_action=null) { + if (ViewData ["Notifications"] == null) + ViewData ["Notifications"] = new List (); + (ViewData ["Notifications"] as List).Add ( + new Notification { body = YavscAjaxHelper.QuoteJavascriptString(message), click_action = click_action } ) ; } /// @@ -339,7 +329,7 @@ namespace Yavsc.Helpers } } if (ResultCount == 0) { - writer.Write (none); + writer.WriteEncodedText(none); } return new MvcHtmlString(strwr.ToString()); } diff --git a/web/Models/App.master b/web/Models/App.master index 1cec7333..ba05644f 100644 --- a/web/Models/App.master +++ b/web/Models/App.master @@ -40,8 +40,8 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>'; diff --git a/web/Models/AppAdmin.master b/web/Models/AppAdmin.master index 830cc89d..e5d62343 100644 --- a/web/Models/AppAdmin.master +++ b/web/Models/AppAdmin.master @@ -36,11 +36,12 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
-<%if (ViewData ["Notifications"]!=null) { %> +<% if (ViewData ["Notifications"]!=null) { %> diff --git a/web/Models/NoLogin.master b/web/Models/NoLogin.master index 2cb237ac..0e88e45a 100644 --- a/web/Models/NoLogin.master +++ b/web/Models/NoLogin.master @@ -1,65 +1,69 @@ <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> +<% ViewState["orgtitle"] = Html.Translate(Page.Title); %> +<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %> -<% -ViewState["orgtitle"] = T.GetString(Page.Title); - Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; - %> + - +" /> +" /> +" /> +" /> +" /> - + + + + + + + - -
+
-

<%=ViewState["orgtitle"]%> - -"><%= YavscHelpers.SiteName %> -

-
<% - if (ViewData["Error"]!=null) { - %>
<%= Html.Encode(ViewData["Error"]) %> -
<% } - if (ViewData["Message"]!=null) { - %>
<%= Html.Encode(ViewData["Message"]) %>
<% } - %> +

"> +<%=ViewState["orgtitle"]%> +- "><%= YavscHelpers.SiteName %> +

+ + +
+<% if (ViewData ["Notifications"]!=null) { %> + +<% } %>
-
+
- -
- - <%= Html.ActionLink("Contact","Contact","Home",null, new { @class="thanks" }) %> + - + %><%= link.Text %> + <% } else { %> + <%= link.Text %> + <% }} %> +
- diff --git a/web/ValidateAjaxAttribute.cs b/web/ValidateAjaxAttribute.cs index 62d6b39b..66b51ec6 100644 --- a/web/ValidateAjaxAttribute.cs +++ b/web/ValidateAjaxAttribute.cs @@ -43,7 +43,8 @@ namespace Yavsc where modelState[x].Errors.Count > 0 select new { - key = x, + // FIXME why? + key = x.Replace(".","_"), errors = modelState[x].Errors. Select(y => y.ErrorMessage). ToArray() diff --git a/web/Views/Account/Login.aspx b/web/Views/Account/Login.aspx index 8e9dcc93..f3a00936 100644 --- a/web/Views/Account/Login.aspx +++ b/web/Views/Account/Login.aspx @@ -16,6 +16,7 @@ <%= Html.CheckBox("RememberMe") %> <%= Html.ValidationMessage("RememberMe", "") %>
<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %> +<%= Html.AntiForgeryToken() %> <% } %> diff --git a/web/Views/Account/Profile.aspx b/web/Views/Account/Profile.aspx index e783b526..b6ba4bae 100644 --- a/web/Views/Account/Profile.aspx +++ b/web/Views/Account/Profile.aspx @@ -1,4 +1,4 @@ -<%@ Page Title="Profile_edition" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> +<%@ Page Title="Profile_edition" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> <% Title = ViewData["UserName"] + " : " +Html.Translate("Profile_edition"); %> @@ -18,9 +18,9 @@ table.layout TR TD { max-width:40%; }
Informations publiques -<%= Html.LabelFor(model => model.Name) %> : -<%= Html.TextBox("Name") %> -<%= Html.ValidationMessage("Name", "*") %> +<%= Html.LabelFor(model => model.NewUserName) %> : +<%= Html.TextBox("NewUserName") %> +<%= Html.ValidationMessage("NewUserName", "*") %>
<%= Html.LabelFor(model => model.WebSite) %> : @@ -34,7 +34,11 @@ Avatar :
- +
Informations administratives +<%= Html.LabelFor(model => model.Name) %> : +<%= Html.TextBox("Name") %> +<%= Html.ValidationMessage("Name", "*") %> +
Blog
<%= Html.LabelFor(model => model.BlogVisible) %> : @@ -117,7 +121,7 @@ Avatar :
/// The role. + [Required(ErrorMessage= "S'il vous plait, saisissez le type d'intervention souhaité")] [Display(Name="Role",ResourceType=typeof(LocalizedText))] public string Role { get; set; } } diff --git a/yavscModel/ChangeLog b/yavscModel/ChangeLog index ff4ae535..2dfdca51 100644 --- a/yavscModel/ChangeLog +++ b/yavscModel/ChangeLog @@ -1,3 +1,39 @@ +2015-11-01 Paul Schneider + + * ProfileEdition.cs: Fixes the username modification + + * LocalizedText.resx: + * LocalizedText.fr.resx: + * LocalizedText.Designer.cs: + * LocalizedText.fr.Designer.cs: WIP booking + + * ChangePasswordModel.cs: + * RegisterClientModel.cs: A regexp for user name + + * LoginModel.cs: A regexp for user name and password + + * Profile.cs: A regexp for user name, and profile usage fixes + + * UserManager.cs: Checks for username availability before + trying to modify it + + * YavscModel.csproj: `ProfileEdition` class addition + + * ChangeLog: useless here + + * BookQuery.cs: Start, end hour and role are required + + * OtherWebException.cs: useless + +2015-10-31 Paul Schneider + + * LocalizedText.resx: + * OtherWebException.cs: + * BookQuery.cs: + * LocalizedText.fr.resx: + * LocalizedText.Designer.cs: + * LocalizedText.fr.Designer.cs: + 2015-10-30 Paul Schneider * LocalizedText.resx: diff --git a/yavscModel/LocalizedText.Designer.cs b/yavscModel/LocalizedText.Designer.cs index aa63b8b5..36d28cab 100644 --- a/yavscModel/LocalizedText.Designer.cs +++ b/yavscModel/LocalizedText.Designer.cs @@ -52,6 +52,12 @@ namespace Yavsc.Model { } } + public static string StartDateAfterEndDate { + get { + return ResourceManager.GetString("StartDateAfterEndDate", resourceCulture); + } + } + public static string ProviderId { get { return ResourceManager.GetString("ProviderId", resourceCulture); @@ -519,5 +525,11 @@ namespace Yavsc.Model { return ResourceManager.GetString("Non_existent_user", resourceCulture); } } + + public static string FillInAFutureDate { + get { + return ResourceManager.GetString("FillInAFutureDate", resourceCulture); + } + } } } diff --git a/yavscModel/LocalizedText.fr.Designer.cs b/yavscModel/LocalizedText.fr.Designer.cs index 014568c3..df72f280 100644 --- a/yavscModel/LocalizedText.fr.Designer.cs +++ b/yavscModel/LocalizedText.fr.Designer.cs @@ -52,6 +52,12 @@ namespace Yavsc.Model { } } + public static string StartDateAfterEndDate { + get { + return ResourceManager.GetString("StartDateAfterEndDate", resourceCulture); + } + } + public static string ProviderId { get { return ResourceManager.GetString("ProviderId", resourceCulture); @@ -64,12 +70,6 @@ namespace Yavsc.Model { } } - public static string Location { - get { - return ResourceManager.GetString("Location", resourceCulture); - } - } - public static string Circles { get { return ResourceManager.GetString("Circles", resourceCulture); @@ -286,9 +286,9 @@ namespace Yavsc.Model { } } - public static string StartHour { + public static string Location { get { - return ResourceManager.GetString("StartHour", resourceCulture); + return ResourceManager.GetString("Location", resourceCulture); } } @@ -460,6 +460,12 @@ namespace Yavsc.Model { } } + public static string StartHour { + get { + return ResourceManager.GetString("StartHour", resourceCulture); + } + } + public static string Unitary_cost { get { return ResourceManager.GetString("Unitary_cost", resourceCulture); @@ -507,5 +513,11 @@ namespace Yavsc.Model { return ResourceManager.GetString("Non_existent_user", resourceCulture); } } + + public static string FillInAFutureDate { + get { + return ResourceManager.GetString("FillInAFutureDate", resourceCulture); + } + } } } diff --git a/yavscModel/LocalizedText.fr.resx b/yavscModel/LocalizedText.fr.resx index 66f4161c..af84326b 100644 --- a/yavscModel/LocalizedText.fr.resx +++ b/yavscModel/LocalizedText.fr.resx @@ -36,6 +36,7 @@ Devis non trouvé Page web de l'événement Base de données éxistante + Veuilliez, s'il vous plait, utiliser une date future. Agenda Google Erreur Google : {0} Cacher le texte source du billet @@ -75,6 +76,7 @@ Supprimer Rôle créé Date de début + La date de fin doit être postérieure à la date de début. Heure de début Soumettre Nom du tag diff --git a/yavscModel/LocalizedText.resx b/yavscModel/LocalizedText.resx index f585ce78..04318867 100644 --- a/yavscModel/LocalizedText.resx +++ b/yavscModel/LocalizedText.resx @@ -36,6 +36,7 @@ Estimate not found Event Web page Existant data base + Please, use a date in the future as starting date. Home Hide Hide the bill source text @@ -80,6 +81,7 @@ Submit Start hour Start date + The ending date must be later than the starting one. Tag name LaTeX version This site uses cookies diff --git a/yavscModel/OtherWebException.cs b/yavscModel/OtherWebException.cs index bf02865c..28305a83 100644 --- a/yavscModel/OtherWebException.cs +++ b/yavscModel/OtherWebException.cs @@ -28,7 +28,7 @@ namespace Yavsc.Model /// /// Google error exception. /// - public class OtherWebException : Exception + public class OtherWebException : WebException { /// /// Gets or sets the title. diff --git a/yavscModel/RolesAndMembers/ChangePasswordModel.cs b/yavscModel/RolesAndMembers/ChangePasswordModel.cs index 9669524d..2fc2dbbe 100644 --- a/yavscModel/RolesAndMembers/ChangePasswordModel.cs +++ b/yavscModel/RolesAndMembers/ChangePasswordModel.cs @@ -12,7 +12,7 @@ namespace Yavsc.Model.RolesAndMembers /// Gets or sets the username. /// /// The username. - [Required(ErrorMessage = "Please, enter your user name")] + [Required(ErrorMessage = "Please, enter your user name"),RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+")] public string Username { get; set; } /// diff --git a/yavscModel/RolesAndMembers/LoginModel.cs b/yavscModel/RolesAndMembers/LoginModel.cs index fd165da1..13f8e76c 100644 --- a/yavscModel/RolesAndMembers/LoginModel.cs +++ b/yavscModel/RolesAndMembers/LoginModel.cs @@ -15,7 +15,7 @@ namespace Yavsc.Model.RolesAndMembers /// The name of the user. [DisplayName("Nom d'utilisateur"), Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur ([a-z]|[A-Z]|[-_.~]|[0-9])+"), - RegularExpression("([a-z]|[A-Z]|[-_.~]|[0-9])+")] + RegularExpression("([a-z]|[A-Z]|[0-9])+")] public string UserName { get; set; } /// @@ -23,8 +23,7 @@ namespace Yavsc.Model.RolesAndMembers /// /// The password. [DisplayName("Mot de passe"), - Required(ErrorMessage = "S'il vous plait, entez un mot de passe"), - RegularExpression("([a-z]|[A-Z]|[0-9]|[-_.~#{}`'\\^])+")] + RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+")] public string Password { get; set; } /// diff --git a/yavscModel/RolesAndMembers/Profile.cs b/yavscModel/RolesAndMembers/Profile.cs index cb11cb74..44fd02bd 100644 --- a/yavscModel/RolesAndMembers/Profile.cs +++ b/yavscModel/RolesAndMembers/Profile.cs @@ -219,7 +219,11 @@ namespace Yavsc.Model.RolesAndMembers /// Gets or sets the name of the user. /// /// The name of the user. - public string UserName { get { return userName; } } + [Localizable(true), Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur valide") + ,Display(ResourceType=typeof(LocalizedText),Name="User_name"), + RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+") + ] + public string UserName { get { return userName; } set { userName=value; } } public Profile () : base () { @@ -276,7 +280,6 @@ namespace Yavsc.Model.RolesAndMembers userName = profile.UserName; - s = profile.GetPropertyValue ("BankCode"); BankCode = (s is DBNull) ? null : (string)s; @@ -290,11 +293,10 @@ namespace Yavsc.Model.RolesAndMembers WicketCode = (s is DBNull) ? null : (string)s; s = profile.GetPropertyValue ("AccountNumber"); - this.AccountNumber = (s is DBNull) ? null : (string)s; - - s = profile.GetPropertyValue ("BankedKey"); - BankedKey = (s == null) ? 0 : (s is DBNull)? 0 : (int)s; + AccountNumber = (s is DBNull) ? null : (string)s; + object o = profile.GetPropertyValue ("BankedKey"); + BankedKey = (int)0; s = profile.GetPropertyValue ("gcalid"); GoogleCalendar = (s is DBNull)? null : (string) s; } diff --git a/yavscModel/RolesAndMembers/ProfileEdition.cs b/yavscModel/RolesAndMembers/ProfileEdition.cs new file mode 100644 index 00000000..3f45bb1b --- /dev/null +++ b/yavscModel/RolesAndMembers/ProfileEdition.cs @@ -0,0 +1,46 @@ +// +// ProfileEdition.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Web.Profile; + +namespace Yavsc.Model.RolesAndMembers +{ + public class ProfileEdition : Profile + { + public ProfileEdition() + {} + + + public ProfileEdition(ProfileBase pr): base(pr) + { + NewUserName = UserName; + } + + [Localizable(true), Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur valide") + ,Display(ResourceType=typeof(LocalizedText),Name="User_name"), + RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+") + ] + public string NewUserName { get; set; } + } +} + diff --git a/yavscModel/RolesAndMembers/RegisterClientModel.cs b/yavscModel/RolesAndMembers/RegisterClientModel.cs index 5a41fa39..b36ea829 100644 --- a/yavscModel/RolesAndMembers/RegisterClientModel.cs +++ b/yavscModel/RolesAndMembers/RegisterClientModel.cs @@ -35,7 +35,8 @@ namespace Yavsc.Model.RolesAndMembers /// /// The full name. [DisplayName("Nom complet")] - [Required(ErrorMessage="S'il vous plait, saisissez le nom complet")] + [Required(ErrorMessage="S'il vous plait, saisissez le nom complet"), + RegularExpression("([a-z]|[A-Z]|[\\s-_.~]|[0-9])+")] public string Name { get; set; } /// /// Gets or sets the address. diff --git a/yavscModel/RolesAndMembers/UserManager.cs b/yavscModel/RolesAndMembers/UserManager.cs index b3822b45..449fda82 100644 --- a/yavscModel/RolesAndMembers/UserManager.cs +++ b/yavscModel/RolesAndMembers/UserManager.cs @@ -15,6 +15,12 @@ namespace Yavsc.Model.RolesAndMembers /// Old name. /// New name. public static void ChangeName (string oldName, string newName) { + if (!IsAvailable (newName)) + throw new Exception ( + string.Format( + LocalizedText.DuplicateUserName, + newName + )); Provider.ChangeName (oldName, newName); } diff --git a/yavscModel/YavscModel.csproj b/yavscModel/YavscModel.csproj index 827d687a..c9db0b94 100644 --- a/yavscModel/YavscModel.csproj +++ b/yavscModel/YavscModel.csproj @@ -179,6 +179,7 @@ +