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
vnext
Paul Schneider 9 years ago
parent 0a91d3935b
commit d9d5bb308e
42 changed files with 441 additions and 275 deletions

@ -1,3 +1,12 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* NpgsqlMembershipProvider.cs: xmldoc
* NpgsqlProfileProvider.cs: use default values from
configuration
* NpgsqlUserNameProvider.cs: Fixes the username detection
2015-10-28 Paul Schneider <paul@pschneider.fr>
* NpgsqlProfileProvider.cs: Fixes the defaultValue

@ -951,11 +951,13 @@ namespace Npgsql.Web
//
// MembershipProvider.ValidateUser
//
/// <Docs>To be added.</Docs>
/// <Docs>Validates an user identification by password,
/// and, when he's approuved, updates its last login date and
/// returns true.</Docs>
/// <summary>
/// Validates the user.
/// Validates the user at login time.
/// </summary>
/// <returns><c>true</c>, if user was validated, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if user was approuved and its password is valid, <c>false</c> otherwise.</returns>
/// <param name="username">Username.</param>
/// <param name="password">Password.</param>
public override bool ValidateUser (string username, string password)

@ -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);
}
}
/// <summary>
/// Sets the property values.
/// </summary>

@ -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);

@ -1,3 +1,8 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* test-domain-TestAPI.config: profile dates must be returned
as DateTime
2015-10-17 Paul Schneider <paul@pschneider.fr>
* AllTests.cs:

@ -92,8 +92,8 @@
<add name="gtoken" />
<add name="grefreshtoken" />
<add name="gtokentype" />
<add name="gtokenexpir" />
<add name="gcalapi" />
<add name="gtokenexpir" type="System.DateTime"/>
<add name="gcalapi" type="System.Boolean"/>
<add name="gcalid" />
<add name="gregid" />
</properties>

@ -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,

@ -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;}

@ -1,3 +1,72 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* 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 <paul@pschneider.fr>
* 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 <paul@pschneider.fr>
* packages.config:

@ -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
/// <returns>The login.</returns>
/// <param name="model">Model.</param>
/// <param name="returnUrl">Return URL.</param>
[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
/// <param name="AvatarFile">Avatar file.</param>
[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);
}

@ -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.
/// </summary>
/// <param name="gat">Gat.</param>
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 ();
}
/// <summary>
@ -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.
/// </summary>
/// <returns>The query.</returns>
[Authorize]
[HttpGet]
[Authorize,HttpGet]
public ActionResult Book ()
{
return View (new BookQuery ());
@ -308,42 +308,50 @@ namespace Yavsc.Controllers
/// </summary>
/// <returns>The query.</returns>
/// <param name="model">Model.</param>
[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}<br><pre>{2}</pre>",
ex.Status.ToString(),
ex.Message,
response));
}
}
}
return View (model);

@ -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+"' });}");
}

@ -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 (

@ -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;

@ -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));

@ -33,10 +33,10 @@ namespace Yavsc.Helpers
/// </summary>
/// <param name="helper">Helper.</param>
/// <param name="text">Text.</param>
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)));
}
}

@ -20,7 +20,6 @@ using Yavsc.Model.Messaging;
namespace Yavsc.Helpers
{
/// <summary>
/// Yavsc helpers.
/// </summary>
@ -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
/// <param name="user">User.</param>
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);
}
/// <summary>
/// Notify the specified helper and message.
/// </summary>
/// <param name="helper">Helper.</param>
/// <param name="message">Message.</param>
public static void Notify (this HtmlHelper helper, string message) {
Notify (helper.ViewData, message);
}
/// <summary>
/// Notify the specified viewData and message.
/// </summary>
/// <param name="viewData">View data.</param>
/// <param name="message">Message.</param>
public static void Notify(ViewDataDictionary viewData, string message, string click_action=null) {
if (viewData ["Notifications"] == null)
viewData ["Notifications"] = new List<Notification> ();
(viewData ["Notifications"] as List<Notification>).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<Notification> ();
(ViewData ["Notifications"] as List<Notification>).Add (
new Notification { body = YavscAjaxHelper.QuoteJavascriptString(message),
click_action = click_action } ) ;
}
/// <summary>
@ -339,7 +329,7 @@ namespace Yavsc.Helpers
}
}
if (ResultCount == 0) {
writer.Write (none);
writer.WriteEncodedText(none);
}
return new MvcHtmlString(strwr.ToString());
}

@ -40,8 +40,8 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
<script>
$(document).ready(function(){
<% foreach (Notification note in (IEnumerable<Notification>) ViewData ["Notifications"] ) {
if (note.click_action == null) {%> Yavsc.notice('<%=note.body%>'); <% }
else {%> Yavsc.notice('<%=note.body%>', <%=note.click_action%>); <% } %>
if (note.click_action == null) {%> Yavsc.notice(<%=note.body%>); <% }
else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %>
<% } %>
});
</script>

@ -36,11 +36,12 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder>
<div id="notifications"></div>
<%if (ViewData ["Notifications"]!=null) { %>
<% if (ViewData ["Notifications"]!=null) { %>
<script>
$(document).ready(function(){
<% foreach (string note in (IEnumerable<string>) ViewData ["Notifications"] ) { %>
Yavsc.notice('<%=note%>');
<% foreach (Notification note in (IEnumerable<Notification>) ViewData ["Notifications"] ) {
if (note.click_action == null) {%> Yavsc.notice(<%=note.body%>); <% }
else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %>
<% } %>
});
</script>

@ -1,65 +1,69 @@
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<% ViewState["orgtitle"] = Html.Translate(Page.Title); %>
<% Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName; %>
<asp:ContentPlaceHolder id="init" runat="server">
</asp:ContentPlaceHolder><%
ViewState["orgtitle"] = T.GetString(Page.Title);
Page.Title = ViewState["orgtitle"] + " - " + YavscHelpers.SiteName;
%><head runat="server">
</asp:ContentPlaceHolder><head runat="server">
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/App_Themes/style.css" />
<link rel="stylesheet" href="<%=Url.Content("~/App_Themes/style.css")%>" />
<link rel="stylesheet" href="<%=Url.Content("~/App_Themes/font-awesome.css")%>" />
<link rel="stylesheet" href="<%=Url.Content("~/App_Themes/jquery-ui.css")%>" />
<link rel="stylesheet" href="<%=Url.Content("~/App_Themes/prettify.css")%>" />
<link rel="stylesheet" href="<%=Url.Content("~/App_Themes/doxy.css")%>" />
<link rel="icon" type="image/png" href="/favicon.png?v=3" />
<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-2.1.4.min.js")%>"></script>
<script src="<%=Url.Content("~/Scripts/jquery-2.1.4.min.js")%>"></script>
<script src="<%=Url.Content("~/Scripts/jquery-ui-1.11.4.js")%>"></script>
<script src="<%=Url.Content("~/Scripts/parallax.js")%>"></script>
<script src="<%=Url.Content("~/Scripts/Prettify/run_prettify.js")%>"></script>
<script type="text/javascript">
var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
</script>
<script src="<%=Url.Content("~/Scripts/yavsc.js")%>"></script>
<script src="<%=Url.Content("~/Scripts/yavsc.tags.js")%>"></script>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href='http://fonts.googleapis.com/css?family=Dancing+Script:400,700' rel='stylesheet' type='text/css'/>
</head>
<body>
<header>
<header data-type="background" data-speed="8" >
<asp:ContentPlaceHolder ID="overHeaderOne" runat="server">
<h1><a href="<%= Html.Encode(Request.Url.AbsoluteUri.ToString()) %>"> <%=ViewState["orgtitle"]%> </a> -
<a href="<%=Request.Url.Scheme + "://" + Request.Url.Authority%>"><%= YavscHelpers.SiteName %></a>
</h1>
</asp:ContentPlaceHolder><asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder><%
if (ViewData["Error"]!=null) {
%><div class="error"><%= Html.Encode(ViewData["Error"]) %>
</div><% }
if (ViewData["Message"]!=null) {
%><div class="message"><%= Html.Encode(ViewData["Message"]) %></div><% }
%>
<h1><a href="<%= Url.RouteUrl("Default") %>">
<%=ViewState["orgtitle"]%></a>
- <a href="<%= Url.RouteUrl("Default", new {controller = "Home" , action = "Index" }) %>"><%= YavscHelpers.SiteName %></a>
</h1>
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="header" runat="server"></asp:ContentPlaceHolder>
<div id="notifications"></div>
<% if (ViewData ["Notifications"]!=null) { %>
<script>
$(document).ready(function(){
<% foreach (Notification note in (IEnumerable<Notification>) ViewData ["Notifications"] ) {
if (note.click_action == null) {%> Yavsc.notice(<%=note.body%>); <% }
else {%> Yavsc.notice(<%=note.body%>, <%=note.click_action%>); <% } %>
<% } %>
});
</script>
<% } %>
</header>
<main>
<main data-type="background" data-speed="10" data-emheight="10" data-posx="0" data-posy="22" >
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</main>
<asp:ContentPlaceHolder ID="MASContent" runat="server">
</asp:ContentPlaceHolder>
<footer>
<script src="https://apis.google.com/js/platform.js" async defer>
{lang: 'fr'}
</script>
<%= Html.ActionLink("Contact","Contact","Home",null, new { @class="thanks" }) %>
<footer data-type="background" data-speed="5" >
<div id="copyr">
<a href="http://yavsc.pschneider.fr/Blogs/UserPost/paul/License">© 2015 GNU GENERAL PUBLIC LICENSE <i>Version 3, 29 June 2007</i></a>
</div>
<%= Html.ActionLink("Formulaire de contact","Contact","Home",null, new { @class="thanks" }) %>
<% foreach ( Link link in Html.Thanks()) { %>
<a class="thanks" href="<%=link.Url%>"><% if (link.Image !=null) {
%><img src="<%= link.Image %>" alt="<%= link.Text %>"/></a><%
} else { %><a class="thanks" href="<%=link.Url%>"><%= link.Text %></a><% }} %>
<div class="g-plusone" data-annotation="inline" data-width="230"></div>
</footer>
<script type="text/javascript">
var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';
</script> <script>
$( ".bshd" ).on("click",function(e) {
if (e.target == "[object HTMLElement]") {
var panel = $(this).children(".bshpanel");
if (panel.hasClass("hidden")) panel.css("cursor","zoom-out");
else panel.css("cursor","zoom-in");
panel.toggleClass("hidden");
$(this).children(".bsh").toggleClass("hidden");
} });
</script>
%><img src="<%= link.Image %>" alt="<%= link.Text %>"/></a>
<% } else { %>
<a class="thanks" href="<%=link.Url%>"><%= link.Text %></a>
<% }} %>
</footer><div class="modal"></div>
</body>
</html>

@ -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()

@ -16,6 +16,7 @@
<%= Html.CheckBox("RememberMe") %>
<%= Html.ValidationMessage("RememberMe", "") %><br/>
<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %>
<%= Html.AntiForgeryToken() %>
<!-- Html.AntiForgeryToken() -->
<input type="submit"/>
<% } %></div>

@ -1,4 +1,4 @@
<%@ Page Title="Profile_edition" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<Profile>" %>
<%@ Page Title="Profile_edition" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<ProfileEdition>" %>
<asp:Content ContentPlaceHolderID="init" ID="init1" runat="server">
<% Title = ViewData["UserName"] + " : " +Html.Translate("Profile_edition"); %>
@ -18,9 +18,9 @@ table.layout TR TD { max-width:40%; }
<fieldset><legend>Informations publiques</legend>
<%= Html.LabelFor(model => model.Name) %> :
<%= Html.TextBox("Name") %>
<%= Html.ValidationMessage("Name", "*") %>
<%= Html.LabelFor(model => model.NewUserName) %> :
<%= Html.TextBox("NewUserName") %>
<%= Html.ValidationMessage("NewUserName", "*") %>
<br>
<%= Html.LabelFor(model => model.WebSite) %> :
@ -34,7 +34,11 @@ Avatar : <img src="<%=Url.AvatarUrl(HttpContext.Current.User.Identity.Name)%>" a
<%= Html.ValidationMessage("AvatarFile", "*") %>
</fieldset>
<fieldset><legend>Informations administratives</legend>
<%= Html.LabelFor(model => model.Name) %> :
<%= Html.TextBox("Name") %>
<%= Html.ValidationMessage("Name", "*") %>
</fieldset>
<fieldset><legend>Blog</legend>
<div class="spanel">
<%= Html.LabelFor(model => model.BlogVisible) %> :
@ -117,7 +121,7 @@ Avatar : <img src="<%=Url.AvatarUrl(HttpContext.Current.User.Identity.Name)%>" a
<% } %>
<aside>
<%= Html.ActionLink("Changer de mot de passe","ChangePassword", "Account",null, new { @class="actionlink" })%>
<%= Html.ActionLink("Désincription","Unregister", "Account", new { id=ViewData["UserName"] } , new { @class="actionlink" })%>
<%= Html.ActionLink("Désincription", "Unregister", "Account", new { id = ViewData["UserName"] } , new { @class="actionlink" })%>
</aside>
<aside>
<% if (Roles.IsUserInRole((string)ViewData ["UserName"],"Admin")) { %>

@ -308,11 +308,7 @@ function addRow(){
message(false);
},
statusCode: {
400: function(data) {
$.each(data.responseJSON, function (key, value) {
document.getElementById("Err_wr_" + value.key).innerHTML=value.errors.join("<br/>");
});
}
400: Yavsc.onAjaxBadInput
},
error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status!=400)

@ -1,73 +0,0 @@
<%@ Page Title="Booking" Language="C#" Inherits="System.Web.Mvc.ViewPage<BookQuery>" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="head" ID="headContent" runat="server">
<link rel='stylesheet' href='/Scripts/fullcalendar/fullcalendar.css' />
<script type="text/javascript" src="/Scripts/jquery.mousewheel.js"></script>
<link rel="stylesheet" type="text/css" href="/App_Themes/jquery.timepicker.css" />
<script type="text/javascript" src="/Scripts/globalize/globalize.js"></script>
<script type="text/javascript" src="/Scripts/globalize/cultures/globalize.culture.fr.js"></script>
<script type="text/javascript" src="/Scripts/datepicker-fr.js"></script>
<script type="text/javascript" src="/Scripts/datepicker-en-GB.js"></script>
<script type="text/javascript" src="/Scripts/datepair.js"></script>
<script type="text/javascript" src="/Scripts/jquery.timepicker.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery.datepair.min.js"></script>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
<% using ( Html.BeginForm("Book","Google") ) { %>
<div id="book" ><fieldset>
<legend>Date d'intervention</legend>
Intervention souhaitée entre le
<input type="text" id="StartDate" class="start date" value="<%= DateTime.Now.ToString("yyyy/MM/dd")%>">
<%= Html.ValidationMessageFor(model=>model.StartDate) %>
et le
<input type="text" id="EndDate" class="end date" value="<%= DateTime.Now.AddDays(2).ToString("yyyy/MM/dd")%>">
<%= Html.ValidationMessageFor(model=>model.EndDate) %>
</fieldset>
<fieldset >
<legend>Heure et durée d'intervention souhaitée</legend>
<%= Html.LabelFor(model=>model.StartHour) %>
<input type="text" id="StartHour" class="start time" value="<%= DateTime.Now.ToString("H:mm")%>">
<%= Html.ValidationMessageFor(model=>model.StartHour) %>
<%= Html.LabelFor(model=>model.EndHour) %>
<input type="text" id="EndHour" class="end time" value="<%= DateTime.Now.AddMinutes(30).ToString("H:mm")%>">
<%= Html.ValidationMessageFor(model=>model.EndHour) %>
</fieldset>
</div>
<fieldset>
<legend>Intervenant</legend>
<%= Html.LabelFor(model=>model.Role) %>:
<%= Html.TextBoxFor(model=>model.Role) %>
<%= Html.ValidationMessageFor(model=>model.Role) %>
<br>
<%= Html.LabelFor(model=>model.Person) %>:
<%= Html.TextBoxFor(model=>model.Person) %>
<%= Html.ValidationMessageFor(model=>model.Person) %>
</fieldset>
<script>
$(function() {
var tpconfig = {
'timeFormat': 'H:i',
'showDuration': true,
'disableTimeRanges': [
['17:01pm', '24:01pm'],
['0am', '9am']
]};
// $.datepicker.setDefaults($.datepicker.regional[ "fr" ] );
var dpconfig = {
'format': 'yy/mm/dd',
'autoclose': true } ;
$('#book .time').timepicker(tpconfig);
$('#book .date').datepicker(dpconfig);
$('#book').datepair();
});
</script>
<input type="submit">
<% } %>
<pre><%= Html.Encode(ViewData["json"]) %></pre>
</asp:Content>

@ -16,19 +16,19 @@
<% using ( Html.BeginForm("Book","Google") ) { %>
<div id="book" >Date d'intervention :
Intervention souhaitée entre le
<input type="text" id="StartDate" class="start date" >
<input type="text" id="StartDate" name="StartDate" class="start date" value="<%=Model.StartDate.ToString("yyyy/MM/dd")%>">
<%= Html.ValidationMessageFor(model=>model.StartDate) %>
et le
<input type="text" id="EndDate" class="end date" >
<input type="text" id="EndDate" name="EndDate" class="end date" value="<%=Model.StartDate.ToString("yyyy/MM/dd")%>">
<%= Html.ValidationMessageFor(model=>model.EndDate) %>
<br>
Heure et durée d'intervention souhaitée
<%= Html.LabelFor(model=>model.StartHour) %>
<input type="text" id="StartHour" class="start time" >
<input type="text" id="StartHour" name="StartHour" class="start time" value="<%=Model.StartHour%>">
<%= Html.ValidationMessageFor(model=>model.StartHour) %>
<%= Html.LabelFor(model=>model.EndHour) %>
<input type="text" id="EndHour" class="end time" >
<input type="text" id="EndHour" name="EndHour" class="end time" value="<%=Model.EndHour%>">
<%= Html.ValidationMessageFor(model=>model.EndHour) %>
</div>

@ -23,7 +23,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<sectionGroup name="system.web">
<section name="blog" type="Yavsc.Model.DataProviderConfigurationSection, YavscModel" allowLocation="true" requirePermission="false" allowDefinition="Everywhere" />
<section name="thanks" type="Yavsc.ThanksConfigurationSection, Yavsc" allowLocation="true" requirePermission="false" allowDefinition="Everywhere" />
<section name="catalog" type="Yavsc.Model.FrontOffice.Configuration.CatalogProvidersConfigurationSection, YavscModel" allowLocation="true" requirePermission="false" allowDefinition="Everywhere" />
<section name="catalog" type="Yavsc.Model.FrontOffice.Catalog.Configuration.CatalogProvidersConfigurationSection, YavscModel" allowLocation="true" requirePermission="false" allowDefinition="Everywhere" />
<section name="workflow" type="Yavsc.Model.DataProviderConfigurationSection, YavscModel" allowLocation="true" requirePermission="false" allowDefinition="Everywhere" />
<section name="circleProviders" type="Yavsc.Model.DataProviderConfigurationSection, YavscModel" />
<section name="userNameManager" type="Yavsc.Model.DataProviderConfigurationSection, YavscModel" />
@ -121,7 +121,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="Phone" />
<add name="Mobile" />
<add name="Avatar" />
<add name="BlogVisible" type="System.Boolean" />
<add name="BlogVisible" type="System.Boolean" defaultValue="false" />
<add name="BlogTitle" />
<add name="WebSite" />
<add name="Address" />
@ -133,12 +133,12 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="BIC" />
<add name="WicketCode" />
<add name="AccountNumber" />
<add name="BankedKey" />
<add name="BankedKey" type="System.Int32" defaultValue="0"/>
<add name="gtoken" />
<add name="grefreshtoken" />
<add name="gtokentype" />
<add name="gtokenexpir" />
<add name="gcalapi" />
<add name="gtokenexpir" type="System.DateTime" defaultValue="2008-05-01 7:34:42Z" />
<add name="gcalapi" type="System.Boolean" defaultValue="false" />
<add name="gcalid" />
<add name="gregid" />
<add name="allowcookies" type="System.Boolean" allowAnonymous="true" defaultValue="false"/>
@ -167,6 +167,11 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<!-- <machineKey validationKey="13CA2E37A5A99AD8CE4A6B895BAF0ED3A022AA584B8D922256BA072189CEB085EEB4E573CA833D9B34FBF68687F6A6B3E008FB4EB67585A4D90551B9D36D42A1" decryptionKey="DA89CC83F6FB2EB12D5929DABC89299AC3928E0751705D33D02DB4162ED56536" validation="SHA1" decryption="AES" /> -->
<!--- <sessionState cookieless="true" regenerateExpiredSessionId="true" timeout="120"/> -->
<trust level="High" />
<catalog defaultProvider="XmlCatalogProvider">
<providers>
<add name="XmlCatalogProvider" connection="~/Catalog.xml" applicationName="/" type="SalesCatalog.XmlImplementation.XmlCatalogProvider, SalesCatalog" />
</providers>
</catalog>
</system.web>
<system.codedom>
<compilers>
@ -193,11 +198,6 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql" />
</DbProviderFactories>
</system.data>
<catalog defaultProvider="XmlCatalogProvider">
<providers>
<add name="XmlCatalogProvider" connection="~/Catalog.xml" applicationName="/" type="SalesCatalog.XmlImplementation.XmlCatalogProvider, SalesCatalog" />
</providers>
</catalog>
<system.net>
<!-- not supported: <defaultProxy enabled="true" /> -->
<settings>

@ -206,6 +206,7 @@
<Compile Include="ApiControllers\PaypalController.cs" />
<Compile Include="ApiControllers\AuthorizationDenied.cs" />
<Compile Include="ApiControllers\YavscController.cs" />
<Compile Include="Helpers\YavscAjaxHelper.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Web.config" />
@ -467,7 +468,6 @@
<Content Include="Scripts\jquery.datepair.js" />
<Content Include="Scripts\jquery.datepair.min.js" />
<Content Include="Scripts\jquery-1.11.3.min.js" />
<Content Include="Views\Google\Book-next.aspx" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

@ -45,6 +45,7 @@ namespace Yavsc.Model.Calendar
/// <value>The minimum time.</value>
[RegularExpression("\\d\\d:\\d\\d")]
[Display(ResourceType=typeof(LocalizedText),Name="StartHour")]
[Required(ErrorMessage= "S'il vous plait, saisissez une heure de début d'intervention")]
public string StartHour { get; set; }
/// <summary>
@ -62,7 +63,7 @@ namespace Yavsc.Model.Calendar
/// </summary>
/// <value>The duration.</value>
[RegularExpression("\\d\\d:\\d\\d")]
[Required(ErrorMessage= "S'il vous plait, saisissez une durée minimale d'intervention")]
[Required(ErrorMessage= "S'il vous plait, saisissez une heure de fin d'intervention")]
[Display(Name="EndHour",ResourceType=typeof(LocalizedText))]
public string EndHour { get; set; }
@ -77,6 +78,7 @@ namespace Yavsc.Model.Calendar
/// Gets or sets the role.
/// </summary>
/// <value>The role.</value>
[Required(ErrorMessage= "S'il vous plait, saisissez le type d'intervention souhaité")]
[Display(Name="Role",ResourceType=typeof(LocalizedText))]
public string Role { get; set; }
}

@ -1,3 +1,39 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* 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 <paul@pschneider.fr>
* LocalizedText.resx:
* OtherWebException.cs:
* BookQuery.cs:
* LocalizedText.fr.resx:
* LocalizedText.Designer.cs:
* LocalizedText.fr.Designer.cs:
2015-10-30 Paul Schneider <paul@pschneider.fr>
* LocalizedText.resx:

@ -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);
}
}
}
}

@ -52,21 +52,21 @@ namespace Yavsc.Model {
}
}
public static string ProviderId {
public static string StartDateAfterEndDate {
get {
return ResourceManager.GetString("ProviderId", resourceCulture);
return ResourceManager.GetString("StartDateAfterEndDate", resourceCulture);
}
}
public static string Pdf_version {
public static string ProviderId {
get {
return ResourceManager.GetString("Pdf_version", resourceCulture);
return ResourceManager.GetString("ProviderId", resourceCulture);
}
}
public static string Location {
public static string Pdf_version {
get {
return ResourceManager.GetString("Location", resourceCulture);
return ResourceManager.GetString("Pdf_version", 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);
}
}
}
}

@ -36,6 +36,7 @@
<data name="Estimate_not_found"><value>Devis non trouvé</value></data>
<data name="EventWebPage"><value>Page web de l'événement</value></data>
<data name="ExistantDB"><value>Base de données éxistante</value></data>
<data name="FillInAFutureDate"><value>Veuilliez, s'il vous plait, utiliser une date future.</value></data>
<data name="Google_calendar"><value>Agenda Google</value></data>
<data name="Google_error"><value>Erreur Google : {0}</value></data>
<data name="Hide_source"><value>Cacher le texte source du billet</value></data>
@ -75,6 +76,7 @@
<data name="Remove"><value>Supprimer</value></data>
<data name="role_created"><value>Rôle créé</value></data>
<data name="StartDate"><value>Date de début</value></data>
<data name="StartDateAfterEndDate"><value>La date de fin doit être postérieure à la date de début.</value></data>
<data name="StartHour"><value>Heure de début</value></data>
<data name="Submit"><value>Soumettre</value></data>
<data name="Tag_name"><value>Nom du tag</value></data>

@ -36,6 +36,7 @@
<data name="Estimate_not_found"><value>Estimate not found</value></data>
<data name="EventWebPage"><value>Event Web page</value></data>
<data name="ExistantDB"><value>Existant data base</value></data>
<data name="FillInAFutureDate"><value>Please, use a date in the future as starting date.</value></data>
<data name="Home"><value>Home</value></data>
<data name="Hide"><value>Hide</value></data>
<data name="Hide_source"><value>Hide the bill source text</value></data>
@ -80,6 +81,7 @@
<data name="Submit"><value>Submit</value></data>
<data name="StartHour"><value>Start hour</value></data>
<data name="StartDate"><value>Start date</value></data>
<data name="StartDateAfterEndDate"><value>The ending date must be later than the starting one.</value></data>
<data name="Tag_name"><value>Tag name</value></data>
<data name="Tex_version"><value>LaTeX version</value></data>
<data name="ThisSiteUsesCookies"><value>This site uses cookies</value></data>

@ -28,7 +28,7 @@ namespace Yavsc.Model
/// <summary>
/// Google error exception.
/// </summary>
public class OtherWebException : Exception
public class OtherWebException : WebException
{
/// <summary>
/// Gets or sets the title.

@ -12,7 +12,7 @@ namespace Yavsc.Model.RolesAndMembers
/// Gets or sets the username.
/// </summary>
/// <value>The username.</value>
[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; }
/// <summary>

@ -15,7 +15,7 @@ namespace Yavsc.Model.RolesAndMembers
/// <value>The name of the user.</value>
[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; }
/// <summary>
@ -23,8 +23,7 @@ namespace Yavsc.Model.RolesAndMembers
/// </summary>
/// <value>The password.</value>
[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; }
/// <summary>

@ -219,7 +219,11 @@ namespace Yavsc.Model.RolesAndMembers
/// Gets or sets the name of the user.
/// </summary>
/// <value>The name of the user.</value>
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;
}

@ -0,0 +1,46 @@
//
// ProfileEdition.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// 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 <http://www.gnu.org/licenses/>.
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; }
}
}

@ -35,7 +35,8 @@ namespace Yavsc.Model.RolesAndMembers
/// </summary>
/// <value>The full name.</value>
[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; }
/// <summary>
/// Gets or sets the address.

@ -15,6 +15,12 @@ namespace Yavsc.Model.RolesAndMembers
/// <param name="oldName">Old name.</param>
/// <param name="newName">New name.</param>
public static void ChangeName (string oldName, string newName) {
if (!IsAvailable (newName))
throw new Exception (
string.Format(
LocalizedText.DuplicateUserName,
newName
));
Provider.ChangeName (oldName, newName);
}

@ -179,6 +179,7 @@
<Compile Include="Calendar\ICalendarManager.cs" />
<Compile Include="Messaging\Notification.cs" />
<Compile Include="FileSystem\WebFileSystemManager.cs" />
<Compile Include="RolesAndMembers\ProfileEdition.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Loading…