diff --git a/Banner.xcf b/Banner.xcf new file mode 100644 index 00000000..10ccdb14 Binary files /dev/null and b/Banner.xcf differ diff --git a/ITContent/IITContent.cs b/ITContent/IITContent.cs new file mode 100644 index 00000000..eeaab5d2 --- /dev/null +++ b/ITContent/IITContent.cs @@ -0,0 +1,21 @@ +using System; +using WorkFlowProvider; +using yavscModel.WorkFlow; + +namespace ITContent +{ + public interface IITContent: IContentProvider + { + int NewProject(string name, string desc, string ownedId); + void AddDevRessource (int prjId, string userName); + int NewTask(int projectId, string name, string desc); + void SetProjectName(int projectId, string name); + void SetProjectDesc(int projectId, string desc); + void SetTaskName(int taskId, string name); + void SetStartDate(int taskId, DateTime d); + void SetEndDate(int taskId, DateTime d); + void SetTaskDesc(int taskId, string desc); + void NewRelease(int projectId, string Version); + } +} + diff --git a/ITContent/ITContent.csproj b/ITContent/ITContent.csproj new file mode 100644 index 00000000..77e6106c --- /dev/null +++ b/ITContent/ITContent.csproj @@ -0,0 +1,49 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {88D83FC9-4158-4435-98A6-1F8F7F448B8F} + Library + ITContent + ITContent + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + {821FF72D-9F4B-4A2C-B95C-7B965291F119} + WorkFlowProvider + + + {68F5B80A-616E-4C3C-91A0-828AA40000BD} + yavscModel + + + \ No newline at end of file diff --git a/ITContent/Properties/AssemblyInfo.cs b/ITContent/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..ccc7943b --- /dev/null +++ b/ITContent/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("ITContent")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Paul Schneider")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/NpgsqlBlogProvider/AssemblyInfo.cs b/NpgsqlBlogProvider/AssemblyInfo.cs new file mode 100644 index 00000000..7cc5217d --- /dev/null +++ b/NpgsqlBlogProvider/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("NpgsqlBlogProvider")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("paul")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/NpgsqlBlogProvider/BlogHelper.cs b/NpgsqlBlogProvider/BlogHelper.cs new file mode 100644 index 00000000..b08e339e --- /dev/null +++ b/NpgsqlBlogProvider/BlogHelper.cs @@ -0,0 +1,35 @@ +using System; +using System.Configuration; +using System.Reflection; +using System.Collections.Specialized; +using Npgsql.Web.Blog.Configuration; + +namespace Npgsql.Web.Blog +{ + public static class BlogHelper + { + public static BlogProvider GetProvider () + { + BlogProvidersConfigurationSection config = ConfigurationManager.GetSection ("system.web/blog") as BlogProvidersConfigurationSection; + if (config == null) + throw new ConfigurationErrorsException("The configuration bloc for the blog provider was not found"); + BlogProviderConfigurationElement celt = + config.Providers.GetElement (config.DefaultProvider); + if (config == null) + throw new ConfigurationErrorsException("The default blog provider was not found"); + ConstructorInfo ci = Type.GetType (celt.Type).GetConstructor (Type.EmptyTypes); + BlogProvider bp = ci.Invoke (Type.EmptyTypes) as BlogProvider; + NameValueCollection c = new NameValueCollection (); + c.Add ("name", celt.Name); + c.Add ("type", celt.Type); + c.Add ("connectionStringName", celt.ConnectionStringName); + c.Add ("description", celt.Description); + c.Add ("applicationName", celt.ApplicationName); + bp.Initialize (celt.Name, c); + return bp; + } + + + } + +} diff --git a/NpgsqlBlogProvider/BlogManager.cs b/NpgsqlBlogProvider/BlogManager.cs new file mode 100644 index 00000000..594f7a40 --- /dev/null +++ b/NpgsqlBlogProvider/BlogManager.cs @@ -0,0 +1,61 @@ +using System; +using Npgsql.Web.Blog.DataModel; + +namespace Npgsql.Web.Blog +{ + public static class BlogManager + { + public static long RemoveComment(long cmtid) + { + return Provider.RemoveComment (cmtid); + } + + public static void Comment (string from, long postid, string content, bool visible) + { + provider.Comment (from, postid, content); + } + + static BlogProvider provider; + + public static BlogProvider Provider { + get { + if (provider == null) + provider = BlogHelper.GetProvider(); + return provider; + } + } + public static BlogEntry GetPost (string username, string title) + { + return Provider.GetPost (username, title ); + } + public static BlogEntry GetPost(long postid) + { + return Provider.GetPost (postid); + } + public static void Post(string username, string title, string content, bool visible) + { + Provider.Post(username, title, content, visible ); + } + public static void UpdatePost(long postid, string content, bool visible) + { + Provider.UpdatePost(postid, content, visible); + } + public static BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords) + { + return Provider.FindPost (pattern, searchflags, pageIndex, pageSize, out totalRecords); + } + public static void RemovePost (string username, string title) + { + Provider.RemovePost (username, title); + } + public static BlogEntryCollection LastPosts (int pageIndex, int pageSize, out int totalRecords) + { + return Provider.LastPosts (pageIndex, pageSize, out totalRecords); + } + public static Comment[] GetComments(long postid, bool getHidden=true) + { + return Provider.GetComments (postid,getHidden); + } + } +} + diff --git a/NpgsqlBlogProvider/BlogProvider.cs b/NpgsqlBlogProvider/BlogProvider.cs new file mode 100644 index 00000000..fc579116 --- /dev/null +++ b/NpgsqlBlogProvider/BlogProvider.cs @@ -0,0 +1,32 @@ +using System; +using System.Configuration; +using System.Configuration.Provider; +using System.Collections.Generic; +using Npgsql.Web.Blog.DataModel; + +namespace Npgsql.Web.Blog +{ + public abstract class BlogProvider: ProviderBase + { + public abstract BlogEntry GetPost (long postid); + public abstract BlogEntry GetPost (string username, string title); + public abstract long GetPostId (string username, string title); + + public abstract long Post (string username, string title, string content, bool visible); + public abstract void UpdatePost (long postid, string content, bool visible); + public abstract BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags, + int pageIndex, int pageSize, out int totalRecords); + public abstract void RemovePost (string username, string title); + public abstract void RemovePost (long postid); + public abstract long RemoveComment (long cmtid); + public abstract BlogEntryCollection LastPosts(int pageIndex, int pageSize, out int totalRecords); + public abstract string BlogTitle (string username); + public abstract long Comment (string from, long postid, string content); + public abstract Comment[] GetComments (long postid, bool getHidden) ; + public abstract bool AutoValidateComment { get; set; } + public abstract void ValidateComment (long cmtid); + public abstract void UpdateComment (long cmtid, string content, bool visible); + } + +} + diff --git a/NpgsqlBlogProvider/Configuration/BlogProviderConfigurationElement.cs b/NpgsqlBlogProvider/Configuration/BlogProviderConfigurationElement.cs new file mode 100644 index 00000000..6dd50742 --- /dev/null +++ b/NpgsqlBlogProvider/Configuration/BlogProviderConfigurationElement.cs @@ -0,0 +1,40 @@ +using System; +using System.Configuration; +using System.ComponentModel; + +namespace Npgsql.Web.Blog.Configuration +{ + + public class BlogProviderConfigurationElement : ConfigurationElement + { + [ConfigurationProperty("name", IsRequired = true, IsKey=true)] + public string Name { + get { return (string)this ["name"]; } + set { this ["name"] = value; } + } + + [ConfigurationProperty("type", IsRequired = true, IsKey=false)] + public string Type { + get { return (string)this ["type"]; } + set { this ["type"] = value; } + } + + [ConfigurationProperty("connectionStringName")] + public string ConnectionStringName { + get { return (string)this ["connectionStringName"]; } + set { this ["connectionStringName"] = value; } + } + + [ConfigurationProperty("description")] + public string Description { + get { return (string)this ["description"]; } + set { this ["description"] = value; } + } + + [ConfigurationProperty("applicationName")] + public string ApplicationName { + get { return (string)this ["applicationName"]; } + set { this ["applicationName"] = value; } + } + } +} diff --git a/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationCollection.cs b/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationCollection.cs new file mode 100644 index 00000000..14b65694 --- /dev/null +++ b/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationCollection.cs @@ -0,0 +1,26 @@ +using System; +using System.Configuration; +using System.ComponentModel; + +namespace Npgsql.Web.Blog.Configuration +{ + public class BlogProvidersConfigurationCollection : ConfigurationElementCollection + { + protected override ConfigurationElement CreateNewElement () + { + return new BlogProviderConfigurationElement(); + } + + protected override object GetElementKey (ConfigurationElement element) + { + return ((BlogProviderConfigurationElement) element).Name; + } + + public BlogProviderConfigurationElement GetElement (string name) + { + return this.BaseGet(name) as BlogProviderConfigurationElement; + } + } + +} + diff --git a/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationSection.cs b/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationSection.cs new file mode 100644 index 00000000..96800d86 --- /dev/null +++ b/NpgsqlBlogProvider/Configuration/BlogProvidersConfigurationSection.cs @@ -0,0 +1,26 @@ +using System; +using System.Configuration; +using System.ComponentModel; + +namespace Npgsql.Web.Blog.Configuration +{ + public class BlogProvidersConfigurationSection : ConfigurationSection + { + [ConfigurationProperty("defaultProvider")] + public string DefaultProvider { + get { return (string)base ["defaultProvider"]; } + set { base ["defaultProvider"] = value; } + } + + [ConfigurationProperty("providers")] + [ConfigurationCollection(typeof(BlogProvidersConfigurationCollection), + AddItemName = "add", + ClearItemsName = "clear", + RemoveItemName = "remove")] + public BlogProvidersConfigurationCollection Providers{ + get { return (BlogProvidersConfigurationCollection) base ["providers"]; } + set { base ["providers"] = value; } + } + } + +} diff --git a/NpgsqlBlogProvider/DataModel/Blog.cs b/NpgsqlBlogProvider/DataModel/Blog.cs new file mode 100644 index 00000000..74c6590e --- /dev/null +++ b/NpgsqlBlogProvider/DataModel/Blog.cs @@ -0,0 +1,26 @@ +using System; +using System.Configuration; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace Npgsql.Web.Blog.DataModel +{ + public class Blog + { + string title; + + [StringValidator(MaxLength=512)] + [Required] + [DisplayName("Titre")] + public string Title { + get { + return title; + } + set { + title = value; + } + } + + } +} + diff --git a/NpgsqlBlogProvider/DataModel/BlogEntry.cs b/NpgsqlBlogProvider/DataModel/BlogEntry.cs new file mode 100644 index 00000000..c58a632c --- /dev/null +++ b/NpgsqlBlogProvider/DataModel/BlogEntry.cs @@ -0,0 +1,91 @@ +using System; +using System.Configuration; +using System.Configuration.Provider; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace Npgsql.Web.Blog.DataModel +{ + public class BlogEntry + { + long id; + [DisplayName("Identifiant numérique de billet")] + public long Id { + get { + return id; + } + set { + id = value; + } + } + + string title; + + [StringValidator(MaxLength=512)] + [DisplayName("Titre du billet")] + [StringLength(512)] + [RegularExpression("^[^:%&?]*$",ErrorMessage = "Les caratères suivants sont invalides pour un titre: :%&?")] + [Required(ErrorMessage = "S'il vous plait, saisissez un titre")] + public string Title { + get { + return title; + } + set { + title = value; + } + } + + string content; + + [DisplayName("Corps du billet")] + [Required(ErrorMessage = "S'il vous plait, saisissez un texte.")] + public string Content { + get { + return content; + } + set { + content = value; + } + } + + string userName; + + [StringValidator(MaxLength=255)] + [DisplayName("Nom de l'auteur")] + public string UserName { + get { + return userName; + } + set { + userName = value; + } + } + + public DateTime posted; + + [DisplayName("Date de creation")] + public DateTime Posted { + get { + return posted; + } + set { + posted = value; + } + } + + public DateTime modified; + + [DisplayName("Date de modification")] + public DateTime Modified { + get { + return modified; + } + set { + modified = value; + } + } + public bool Visible { get; set ; } + public string [] Tags { get; set ; } + } + +} diff --git a/NpgsqlBlogProvider/DataModel/BlogEntryCollection.cs b/NpgsqlBlogProvider/DataModel/BlogEntryCollection.cs new file mode 100644 index 00000000..5e508cb1 --- /dev/null +++ b/NpgsqlBlogProvider/DataModel/BlogEntryCollection.cs @@ -0,0 +1,12 @@ +using System; +using System.Configuration; +using System.Configuration.Provider; +using System.Collections.Generic; + +namespace Npgsql.Web.Blog.DataModel +{ + public class BlogEntryCollection : List + { + } + +} diff --git a/NpgsqlBlogProvider/DataModel/Comment.cs b/NpgsqlBlogProvider/DataModel/Comment.cs new file mode 100644 index 00000000..698490dc --- /dev/null +++ b/NpgsqlBlogProvider/DataModel/Comment.cs @@ -0,0 +1,76 @@ +using System; +using System.Configuration; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace Npgsql.Web.Blog.DataModel +{ + public class Comment + { + long id; + [DisplayName("Identifiant numérique de commentaire")] + public long Id { + get { + return id; + } + set { + id = value; + } + } + long postid; + [DisplayName("Identifiant numérique du billet commenté")] + public long PostId { + get { + return postid; + } + set { + postid = value; + } + } + /// + /// Gets or sets the author of this comment. + /// + /// From. + public string From { get; set; } + + string content; + [DisplayName("Contenu")] + [Required(ErrorMessage = "S'il vous plait, saisissez un contenu")] + public string CommentText { + get { + return content; + } + set { + content = value; + } + } + + public DateTime posted; + + [DisplayName("Date de creation")] + public DateTime Posted { + get { + return posted; + } + set { + posted = value; + } + } + + public DateTime modified; + + [DisplayName("Date de modification")] + public DateTime Modified { + get { + return modified; + } + set { + modified = value; + } + } + + public bool Visible { get; set ; } + + } +} + diff --git a/NpgsqlBlogProvider/DataModel/FindBlogEntryFlags.cs b/NpgsqlBlogProvider/DataModel/FindBlogEntryFlags.cs new file mode 100644 index 00000000..43dff0f9 --- /dev/null +++ b/NpgsqlBlogProvider/DataModel/FindBlogEntryFlags.cs @@ -0,0 +1,16 @@ +using System; +using System.Configuration; +using System.Configuration.Provider; +using System.Collections.Generic; + +namespace Npgsql.Web.Blog.DataModel +{ + + public enum FindBlogEntryFlags : byte { + MatchTitle = 1, + MatchContent = 2, + MatchUserName = 4, + MatchInvisible = 8 + } + +} diff --git a/NpgsqlBlogProvider/NpgsqlBlogProvider.cs b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs new file mode 100644 index 00000000..cf811139 --- /dev/null +++ b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs @@ -0,0 +1,340 @@ +using System; +using System.Configuration; +using System.Configuration.Provider; +using Npgsql; +using Npgsql.Web.Blog.DataModel; +using System.Collections.Generic; + +namespace Npgsql.Web.Blog +{ + public class NpgsqlBlogProvider : BlogProvider + { + string applicationName; + string connectionString; + + #region implemented abstract members of BlogProvider + + public override long GetPostId (string username, string title) + { + throw new NotImplementedException (); + } + public override Comment[] GetComments (long postid, bool getHidden) + { + List cmts = new List (); + + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + + cmd.CommandText = "select _id, username, bcontent, modified, posted, visible from comment " + + "where applicationname = @appname and postid = @id" + + ((getHidden) ? " and visible = true ":" ") + + "order by posted asc" ; + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@id", postid); + cnx.Open (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + while (rdr.Read ()) { + Comment c = new Comment(); + c.CommentText = rdr.GetString (rdr.GetOrdinal ("bcontent")); + c.From = rdr.GetString (rdr.GetOrdinal ("username")); + c.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); + c.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); + c.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + c.PostId = postid; + c.Id = rdr.GetInt64(rdr.GetOrdinal("_id")); + cmts.Add (c); + } + } + } + return cmts.ToArray(); + } + public override void UpdatePost (long postid, string content, bool visible) + { + using (NpgsqlConnection cnx = new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + DateTime now = DateTime.Now; + cmd.CommandText = + "update blog set modified=@now, bcontent=@content, " + + "visible = @visible where _id = @id"; + cmd.Parameters.Add ("@now", now); + cmd.Parameters.Add ("@content", content); + cmd.Parameters.Add ("@visible", visible); + cmd.Parameters.Add ("@id", postid); + cnx.Open (); + cmd.ExecuteNonQuery (); + cnx.Close(); + } + } + + public override void RemovePost (long postid) + { + throw new NotImplementedException (); + } + + public override long Comment (string from, long postid, string content) + { + if (from == null) + throw new ArgumentNullException("from"); + if (content == null) + throw new ArgumentNullException("content"); + bool visible = AutoValidateComment; + using (NpgsqlConnection cnx= + new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "insert into comment (postid,bcontent," + + "modified,posted,visible,username,applicationname)" + + "values (@postid,@bcontent,@modified,@posted," + + "@visible,@username,@appname) returning _id"; + cmd.Parameters.Add ("@postid", postid); + cmd.Parameters.Add ("@bcontent", content); + DateTime now = DateTime.Now; + cmd.Parameters.Add ("@modified", now); + cmd.Parameters.Add ("@posted", now); + cmd.Parameters.Add ("@visible", visible); + cmd.Parameters.Add ("@username", from); + cmd.Parameters.Add ("@appname", applicationName); + cnx.Open (); + return (long) cmd.ExecuteScalar(); + } + } + + public override void ValidateComment (long cmtid) + { + throw new NotImplementedException (); + } + + public override void UpdateComment + (long cmtid, string content, bool visible) + { + throw new NotImplementedException (); + } + + private bool autoValidateComment = true; + + public override bool AutoValidateComment { + get { + return autoValidateComment; + } + set { + autoValidateComment=value; + } + } + + + public override string BlogTitle + (string username) + { + throw new NotImplementedException (); + } + + #endregion + + public override void Initialize + (string name, System.Collections.Specialized.NameValueCollection config) + { + string cnxName = config ["connectionStringName"]; + connectionString = ConfigurationManager.ConnectionStrings [cnxName].ConnectionString; + config.Remove ("connectionStringName"); + applicationName = config ["applicationName"]; + config.Remove ("applicationName"); + defaultPageSize = int.Parse ( config ["pageLen"] ?? "10") ; + base.Initialize (name, config); + } + #region implemented abstract members of BlogProvider + public override BlogEntry GetPost (long postid) + { + BlogEntry be = null; + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "select username, title, bcontent, modified, posted, visible from blog " + + "where applicationname = @appname and _id = @id"; + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@id", postid); + cnx.Open (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + if (rdr.Read ()) { + be = new BlogEntry (); + be.Title = rdr.GetString (rdr.GetOrdinal ("title")); + be.Content = rdr.GetString (rdr.GetOrdinal ("bcontent")); + be.UserName = rdr.GetString (rdr.GetOrdinal ("username")); + be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); + be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); + be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Id = postid; + } + } + } + return be; + } + public override long RemoveComment (long cmtid) + { + long postid = 0; + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "delete from comment where _id = @id returning postid"; + cmd.Parameters.Add ("id", cmtid); + cnx.Open (); + postid = (long) cmd.ExecuteScalar (); + } + return postid; + } + public override BlogEntry GetPost (string username, string title) + { + BlogEntry be = null; + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "select _id,bcontent,modified,posted,visible from blog " + + "where applicationname = @appname and username = @username and title = @title"; + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@username", username); + cmd.Parameters.Add ("@title", title); + cnx.Open (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + if (rdr.Read ()) { + be = new BlogEntry (); + be.Title = title; + be.Content = rdr.GetString (rdr.GetOrdinal ("bcontent")); + be.UserName = username; + be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); + be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); + be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id")); + } + } + } + return be; + } + + public override long Post (string username, string title, string content, bool visible) + { + if (username == null) + throw new ArgumentNullException("username"); + if (title == null) + throw new ArgumentNullException("title"); + if (content == null) + throw new ArgumentNullException("content"); + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "insert into blog (title,bcontent,modified,posted,visible,username,applicationname)" + + "values (@title,@bcontent,@modified,@posted,@visible,@username,@appname) returning _id"; + cmd.Parameters.Add ("@title", title); + cmd.Parameters.Add ("@bcontent", content); + DateTime now = DateTime.Now; + cmd.Parameters.Add ("@modified", now); + cmd.Parameters.Add ("@posted", now); + cmd.Parameters.Add ("@visible", visible); + cmd.Parameters.Add ("@username", username); + cmd.Parameters.Add ("@appname", applicationName); + cnx.Open (); + return (long) cmd.ExecuteScalar(); + } + } + + public override BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords) + { + BlogEntryCollection c = new BlogEntryCollection (); + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "select title,bcontent,modified,posted,username,visible from blog " + + "where applicationname = @appname"; + cmd.Parameters.Add ("@appname", applicationName); + if ((searchflags & FindBlogEntryFlags.MatchContent) > 0) { + cmd.CommandText += " and bcontent like @bcontent"; + cmd.Parameters.Add ("@bcontent", pattern); + } + if ((searchflags & FindBlogEntryFlags.MatchTitle) > 0) { + cmd.CommandText += " and title like @title"; + cmd.Parameters.Add ("@title", pattern); + } + if ((searchflags & FindBlogEntryFlags.MatchUserName) > 0) { + cmd.CommandText += " and username like @username"; + cmd.Parameters.Add ("@username", pattern); + } + if ((searchflags & FindBlogEntryFlags.MatchInvisible) == 0) { + cmd.CommandText += " and visible = true"; + } + + cmd.CommandText += " order by posted desc"; + cnx.Open (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + totalRecords = 0; + int firstrec = pageIndex * pageSize; + int lastrec = firstrec + pageSize - 1; + while (rdr.Read()) { + if (totalRecords >= firstrec && totalRecords <= lastrec) { + BlogEntry be = new BlogEntry (); + be.Title = rdr.GetString (rdr.GetOrdinal ("title")); + be.Content = rdr.GetString (rdr.GetOrdinal ("bcontent")); + be.UserName = rdr.GetString (rdr.GetOrdinal ("username")); + be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); + be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); + be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + c.Add (be); + } + totalRecords++; + } + } + } + return c; + } + + public override void RemovePost (string username, string title) + { + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "delete from blog where username = @username and applicationname = @appname and title=@title"; + cmd.Parameters.Add ("@username",username); + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@title",title); + cnx.Open (); + cmd.ExecuteNonQuery (); + cnx.Close(); + } + } + + + int defaultPageSize = 10; + + public override BlogEntryCollection LastPosts(int pageIndex, int pageSize, out int totalRecords) + { + BlogEntryCollection c = new BlogEntryCollection (); + using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + + /*cmd.CommandText = "select blog.* from blog, " + + "(select max(posted) lpost, username " + + "from blog where applicationname = @appname " + + "group by username) as lblog " + + "where blog.posted = lblog.lpost and blog.username = lblog.username " ; + */ + cmd.CommandText = "select * " + + "from blog where applicationname = @appname and visible = true " + + " order by posted desc limit @len" ; + + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@len", defaultPageSize); + cnx.Open (); + using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + totalRecords = 0; + int firstrec = pageIndex * pageSize; + int lastrec = firstrec + pageSize - 1; + while (rdr.Read()) { + if (totalRecords >= firstrec && totalRecords <= lastrec) { + BlogEntry be = new BlogEntry (); + be.Title = rdr.GetString (rdr.GetOrdinal ("title")); + be.Content = rdr.GetString (rdr.GetOrdinal ("bcontent")); + be.UserName = rdr.GetString (rdr.GetOrdinal ("username")); + be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); + be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); + be.Visible = true; // because of sql code used + c.Add (be); + } + totalRecords++; + } + } + } + return c; + } + #endregion + } +} diff --git a/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj b/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj new file mode 100644 index 00000000..41bd272a --- /dev/null +++ b/NpgsqlBlogProvider/NpgsqlBlogProvider.csproj @@ -0,0 +1,70 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {C6E9E91B-97D3-48D9-8AA7-05356929E162} + Library + Npgsql.Web.Blog + NpgsqlBlogProvider + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + none + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NpgsqlBlogProvider/Sql/BlogTable.sql b/NpgsqlBlogProvider/Sql/BlogTable.sql new file mode 100644 index 00000000..07fc24e2 --- /dev/null +++ b/NpgsqlBlogProvider/Sql/BlogTable.sql @@ -0,0 +1,21 @@ + +-- Table: blog + +-- DROP TABLE blog; + +CREATE TABLE blog +( + applicationname character varying(255) NOT NULL, + username character varying(255) NOT NULL, + posted timestamp with time zone NOT NULL, + modified timestamp with time zone NOT NULL, + title character varying(255) NOT NULL, + bcontent text NOT NULL, + CONSTRAINT pk_blog PRIMARY KEY (username , applicationname , title ), + CONSTRAINT bloguser FOREIGN KEY (applicationname, username) + REFERENCES users (applicationname, username) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE +) +WITH ( + OIDS=FALSE +); diff --git a/NpgsqlMRPProviders/AssemblyInfo.cs b/NpgsqlMRPProviders/AssemblyInfo.cs new file mode 100644 index 00000000..5aad255b --- /dev/null +++ b/NpgsqlMRPProviders/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("NpgsqlMRPProviders")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("paul")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/NpgsqlMRPProviders/NpgsqlMRPProviders.csproj b/NpgsqlMRPProviders/NpgsqlMRPProviders.csproj new file mode 100644 index 00000000..797f8539 --- /dev/null +++ b/NpgsqlMRPProviders/NpgsqlMRPProviders.csproj @@ -0,0 +1,68 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {BBA7175D-7F92-4278-96FC-84C495A2B5A6} + Library + Npgsql.Web + NpgsqlMRPProviders + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + none + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs b/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs new file mode 100644 index 00000000..bce01049 --- /dev/null +++ b/NpgsqlMRPProviders/NpgsqlMembershipProvider.cs @@ -0,0 +1,1211 @@ +using System.Web.Security; +using System.Configuration.Provider; +using System.Collections.Specialized; +using System; +using System.Data; +using Npgsql; +using NpgsqlTypes; +using System.Configuration; +using System.Diagnostics; +using System.Web; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; +using System.Web.Configuration; + +namespace Npgsql.Web +{ + public sealed class NpgsqlMembershipProvider: MembershipProvider + { + + // + // Global connection string, generated password length. + // + + private int newPasswordLength = 8; + private string connectionString; + + // + // Used when determining encryption key values. + // + + private MachineKeySection machineKey; + + // + // System.Configuration.Provider.ProviderBase.Initialize Method + // + + public override void Initialize (string name, NameValueCollection config) + { + // + // Initialize values from web.config. + // + + if (config == null) + throw new ArgumentNullException ("config"); + + if (name == null || name.Length == 0) + name = "NpgsqlMembershipProvider"; + + if (String.IsNullOrEmpty (config ["description"])) { + config.Remove ("description"); + config.Add ("description", "Sample Npgsql Membership provider"); + } + + // Initialize the abstract base class. + base.Initialize (name, config); + + pApplicationName = GetConfigValue (config ["applicationName"], + System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath); + pMaxInvalidPasswordAttempts = Convert.ToInt32 (GetConfigValue (config ["maxInvalidPasswordAttempts"], "5")); + pPasswordAttemptWindow = Convert.ToInt32 (GetConfigValue (config ["passwordAttemptWindow"], "10")); + pMinRequiredNonAlphanumericCharacters = Convert.ToInt32 (GetConfigValue (config ["minRequiredNonAlphanumericCharacters"], "1")); + pMinRequiredPasswordLength = Convert.ToInt32 (GetConfigValue (config ["minRequiredPasswordLength"], "7")); + pPasswordStrengthRegularExpression = Convert.ToString (GetConfigValue (config ["passwordStrengthRegularExpression"], "")); + pEnablePasswordReset = Convert.ToBoolean (GetConfigValue (config ["enablePasswordReset"], "true")); + pEnablePasswordRetrieval = Convert.ToBoolean (GetConfigValue (config ["enablePasswordRetrieval"], "true")); + pRequiresQuestionAndAnswer = Convert.ToBoolean (GetConfigValue (config ["requiresQuestionAndAnswer"], "false")); + pRequiresUniqueEmail = Convert.ToBoolean (GetConfigValue (config ["requiresUniqueEmail"], "true")); + string temp_format = config ["passwordFormat"]; + if (temp_format == null) { + temp_format = "Hashed"; + } + + switch (temp_format) { + case "Hashed": + pPasswordFormat = MembershipPasswordFormat.Hashed; + break; + case "Encrypted": + pPasswordFormat = MembershipPasswordFormat.Encrypted; + break; + case "Clear": + pPasswordFormat = MembershipPasswordFormat.Clear; + break; + default: + throw new ProviderException ("Password format not supported."); + } + + // + // Initialize NpgsqlConnection. + // + + ConnectionStringSettings ConnectionStringSettings = + ConfigurationManager.ConnectionStrings [config ["connectionStringName"]]; + + if (ConnectionStringSettings == null || ConnectionStringSettings.ConnectionString.Trim () == "") { + throw new ProviderException ("Connection string cannot be blank."); + } + connectionString = ConnectionStringSettings.ConnectionString; + + // Get encryption and decryption key information from the configuration. + Configuration cfg = + WebConfigurationManager.OpenWebConfiguration (System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath); + machineKey = (MachineKeySection)cfg.GetSection ("system.web/machineKey"); + + if (machineKey.ValidationKey.Contains ("AutoGenerate")) + if (PasswordFormat != MembershipPasswordFormat.Clear) + throw new ProviderException ("Hashed or Encrypted passwords " + + "are not supported with auto-generated keys." + ); + } + + + // + // A helper function to retrieve config values from the configuration file. + // + + private string GetConfigValue (string configValue, string defaultValue) + { + if (String.IsNullOrEmpty (configValue)) + return defaultValue; + + return configValue; + } + + + // + // System.Web.Security.MembershipProvider properties. + // + private string pApplicationName; + private bool pEnablePasswordReset; + private bool pEnablePasswordRetrieval; + private bool pRequiresQuestionAndAnswer; + private bool pRequiresUniqueEmail; + private int pMaxInvalidPasswordAttempts; + private int pPasswordAttemptWindow; + private MembershipPasswordFormat pPasswordFormat; + + public override string ApplicationName { + get { return pApplicationName; } + set { pApplicationName = value; } + } + + public override bool EnablePasswordReset { + get { return pEnablePasswordReset; } + } + + public override bool EnablePasswordRetrieval { + get { return pEnablePasswordRetrieval; } + } + + public override bool RequiresQuestionAndAnswer { + get { return pRequiresQuestionAndAnswer; } + } + + public override bool RequiresUniqueEmail { + get { return pRequiresUniqueEmail; } + } + + public override int MaxInvalidPasswordAttempts { + get { return pMaxInvalidPasswordAttempts; } + } + + public override int PasswordAttemptWindow { + get { return pPasswordAttemptWindow; } + } + + public override MembershipPasswordFormat PasswordFormat { + get { return pPasswordFormat; } + } + + private int pMinRequiredNonAlphanumericCharacters; + + public override int MinRequiredNonAlphanumericCharacters { + get { return pMinRequiredNonAlphanumericCharacters; } + } + + private int pMinRequiredPasswordLength; + + public override int MinRequiredPasswordLength { + get { return pMinRequiredPasswordLength; } + } + + private string pPasswordStrengthRegularExpression; + + public override string PasswordStrengthRegularExpression { + get { return pPasswordStrengthRegularExpression; } + } + + // + // System.Web.Security.MembershipProvider methods. + // + + // + // MembershipProvider.ChangePassword + // + + public override bool ChangePassword (string username, string oldPwd, string newPwd) + { + if (!ValidateUser (username, oldPwd)) + return false; + ValidatePasswordEventArgs args = new ValidatePasswordEventArgs (username, newPwd, true); + OnValidatingPassword (args); + if (args.Cancel) { + if (args.FailureInformation != null) + throw args.FailureInformation; + else + throw new MembershipPasswordException ("Change password canceled due to new password validation failure."); + } + int rowsAffected = 0; + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("UPDATE Users " + + " SET Passw = @Password, LastPasswordChangedDate = @LastPasswordChangedDate " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@Password", NpgsqlDbType.Varchar, 255).Value = EncodePassword (newPwd); + cmd.Parameters.Add ("@LastPasswordChangedDate", DateTime.Now); + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + rowsAffected = cmd.ExecuteNonQuery (); + conn.Close (); + } + } + if (rowsAffected > 0) { + return true; + } + + return false; + } + + + + // + // MembershipProvider.ChangePasswordQuestionAndAnswer + // + + public override bool ChangePasswordQuestionAndAnswer (string username, + string password, + string newPwdQuestion, + string newPwdAnswer) + { + if (!ValidateUser (username, password)) + return false; + int rowsAffected = 0; + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("UPDATE Users " + + " SET PasswordQuestion = @Question, PasswordAnswer = @Answer" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@Question", NpgsqlDbType.Varchar, 255).Value = newPwdQuestion; + cmd.Parameters.Add ("@Answer", NpgsqlDbType.Varchar, 255).Value = EncodePassword (newPwdAnswer); + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + rowsAffected = cmd.ExecuteNonQuery (); + conn.Close (); + } + } + if (rowsAffected > 0) { + return true; + } + + return false; + } + + + + // + // MembershipProvider.CreateUser + // + + public override MembershipUser CreateUser (string username, + string password, + string email, + string passwordQuestion, + string passwordAnswer, + bool isApproved, + object providerUserKey, + out MembershipCreateStatus status) + { + ValidatePasswordEventArgs args = + new ValidatePasswordEventArgs (username, password, true); + + OnValidatingPassword (args); + + if (args.Cancel) { + status = MembershipCreateStatus.InvalidPassword; + return null; + } + if (RequiresUniqueEmail && GetUserNameByEmail (email) != "") { + status = MembershipCreateStatus.DuplicateEmail; + return null; + } + + MembershipUser u = GetUser (username, false); + + if (u == null) { + DateTime createDate = DateTime.Now; + + if (providerUserKey == null) { + providerUserKey = Guid.NewGuid (); + } else { + if (!(providerUserKey is Guid)) { + status = MembershipCreateStatus.InvalidProviderUserKey; + return null; + } + } + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("INSERT INTO Users " + + " (PKID, Username, Passw, Email, PasswordQuestion, " + + " PasswordAnswer, IsApproved," + + " Comment, CreationDate, LastPasswordChangedDate, LastActivityDate," + + " ApplicationName, IsLockedOut, LastLockedOutDate," + + " FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, " + + " FailedPasswordAnswerAttemptCount, FailedPasswordAnswerAttemptWindowStart)" + + " Values(@PKID, @Username, @Password, @Email, @PasswordQuestion, @PasswordAnswer, @IsApproved," + + "@Comment, @CreationDate, @LastPasswordChangedDate, @LastActivityDate, " + + "@ApplicationName,@IsLockedOut, @LastLockedOutDate," + + "@FailedPasswordAttemptCount , @FailedPasswordAttemptWindowStart, " + + " @FailedPasswordAnswerAttemptCount, @FailedPasswordAnswerAttemptWindowStart)", conn)) { + + cmd.Parameters.Add ("@PKID", NpgsqlDbType.Varchar).Value = providerUserKey; + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@Password", NpgsqlDbType.Varchar, 255).Value = EncodePassword (password); + cmd.Parameters.Add ("@Email", NpgsqlDbType.Varchar, 128).Value = email; + cmd.Parameters.Add ("@PasswordQuestion", NpgsqlDbType.Varchar, 255).Value = passwordQuestion; + cmd.Parameters.Add ("@PasswordAnswer", NpgsqlDbType.Varchar, 255).Value = EncodePassword (passwordAnswer); + cmd.Parameters.Add ("@IsApproved", NpgsqlDbType.Bit).Value = isApproved; + cmd.Parameters.Add ("@Comment", NpgsqlDbType.Varchar, 255).Value = ""; + cmd.Parameters.Add ("@CreationDate", createDate); + cmd.Parameters.Add ("@LastPasswordChangedDate", createDate); + cmd.Parameters.Add ("@LastActivityDate", createDate); + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + cmd.Parameters.Add ("@IsLockedOut", NpgsqlDbType.Bit).Value = false; + cmd.Parameters.Add ("@LastLockedOutDate", createDate); + cmd.Parameters.Add ("@FailedPasswordAttemptCount", NpgsqlDbType.Integer).Value = 0; + cmd.Parameters.Add ("@FailedPasswordAttemptWindowStart", createDate); + cmd.Parameters.Add ("@FailedPasswordAnswerAttemptCount", NpgsqlDbType.Integer).Value = 0; + cmd.Parameters.Add ("@FailedPasswordAnswerAttemptWindowStart", createDate); + conn.Open (); + int recAdded = cmd.ExecuteNonQuery (); + if (recAdded > 0) { + status = MembershipCreateStatus.Success; + } else { + status = MembershipCreateStatus.UserRejected; + } + conn.Close (); + } + } + return GetUser (username, false); + } else { + status = MembershipCreateStatus.DuplicateUserName; + } + return null; + } + + // + // MembershipProvider.DeleteUser + // + /// + /// To be added. + /// + /// + /// Delete the user from given name. + /// + /// + /// The deleteAllRelatedData parameter usage has to be implemented. + /// + /// + /// The user. + /// + /// + /// If set to true username. + /// + /// + /// If set to true delete all related data. + /// + public override bool DeleteUser (string username, bool deleteAllRelatedData) + { + int rowsAffected = 0; + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("DELETE FROM Users " + + " WHERE Username = @Username AND Applicationname = @ApplicationName", conn)) { + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + rowsAffected = cmd.ExecuteNonQuery (); + if (deleteAllRelatedData) { + // TODO Process commands to delete all data for the user in the database. + } + conn.Close (); + } + } + return (rowsAffected > 0); + } + + // + // MembershipProvider.GetAllUsers + // + + public override MembershipUserCollection GetAllUsers (int pageIndex, int pageSize, out int totalRecords) + { + MembershipUserCollection users = new MembershipUserCollection (); + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT Count(*) FROM Users " + + "WHERE ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = ApplicationName; + conn.Open (); + totalRecords = 0; + totalRecords = (int)((long)cmd.ExecuteScalar ()); + + if (totalRecords > 0) { + cmd.CommandText = "SELECT PKID, Username, Email, PasswordQuestion," + + " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," + + " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" + + " FROM Users " + + " WHERE ApplicationName = @ApplicationName " + + " ORDER BY Username Asc"; + using (NpgsqlDataReader reader = cmd.ExecuteReader ()) { + + int counter = 0; + int startIndex = pageSize * pageIndex; + int endIndex = startIndex + pageSize - 1; + + while (reader.Read()) { + if (counter >= startIndex) { + MembershipUser u = GetUserFromReader (reader); + users.Add (u); + } + + if (counter >= endIndex) { + cmd.Cancel (); + } + + counter++; + } + reader.Close (); + + } + } + conn.Close (); + } + } + return users; + } + + + // + // MembershipProvider.GetNumberOfUsersOnline + // + + public override int GetNumberOfUsersOnline () + { + int numOnline = 0; + TimeSpan onlineSpan = new TimeSpan (0, System.Web.Security.Membership.UserIsOnlineTimeWindow, 0); + DateTime compareTime = DateTime.Now.Subtract (onlineSpan); + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT Count(*) FROM Users " + + " WHERE LastActivityDate > @CompareDate AND ApplicationName = @ApplicationName", conn)) { + + cmd.Parameters.Add ("@CompareDate", compareTime); + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + + + conn.Open (); + + numOnline = (int)cmd.ExecuteScalar (); + } + conn.Close (); + } + + return numOnline; + } + + + + // + // MembershipProvider.GetPassword + // + + public override string GetPassword (string username, string answer) + { + string password = ""; + string passwordAnswer = ""; + + if (!EnablePasswordRetrieval) { + throw new ProviderException ("Password Retrieval Not Enabled."); + } + + if (PasswordFormat == MembershipPasswordFormat.Hashed) { + throw new ProviderException ("Cannot retrieve Hashed passwords."); + } + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT Passw, PasswordAnswer, IsLockedOut FROM Users " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + + NpgsqlDataReader reader = null; + + + conn.Open (); + + using (reader = cmd.ExecuteReader ()) { + + if (reader.HasRows) { + reader.Read (); + + if (reader.GetBoolean (2)) + throw new MembershipPasswordException ("The supplied user is locked out."); + + password = reader.GetString (0); + passwordAnswer = reader.GetString (1); + } else { + throw new MembershipPasswordException ("The supplied user name is not found."); + } + + reader.Close (); + } + } + conn.Close (); + } + + if (RequiresQuestionAndAnswer && !CheckPassword (answer, passwordAnswer)) { + UpdateFailureCount (username, "passwordAnswer"); + throw new MembershipPasswordException ("Incorrect password answer."); + } + if (PasswordFormat == MembershipPasswordFormat.Encrypted) { + password = UnEncodePassword (password); + } + return password; + } + + // + // MembershipProvider.GetUser(string, bool) + // + /// + /// Gets the user as a MembershipUser object + /// + /// + /// The user. + /// + /// + /// The user name to search. + /// + /// + /// Only return the user when it's online. + /// + public override MembershipUser GetUser (string username, bool userIsOnline) + { + MembershipUser u = null; + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT PKID, Username, Email, PasswordQuestion," + + " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," + + " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" + + " FROM Users WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + using (NpgsqlDataReader reader = cmd.ExecuteReader ()) { + if (reader.HasRows) { + reader.Read (); + u = GetUserFromReader (reader); + + if (userIsOnline) { + NpgsqlCommand updateCmd = new NpgsqlCommand ("UPDATE Users " + + "SET LastActivityDate = @LastActivityDate " + + "WHERE Username = @Username AND Applicationname = @ApplicationName", conn); + + updateCmd.Parameters.Add ("@LastActivityDate", DateTime.Now); + updateCmd.Parameters.Add ("@Username", username); + updateCmd.Parameters.Add ("@ApplicationName", pApplicationName); + + updateCmd.ExecuteNonQuery (); + } + } + reader.Close (); + } + } + conn.Close (); + } + return u; + } + + + // + // MembershipProvider.GetUser(object, bool) + // + public override MembershipUser GetUser (object providerUserKey, bool userIsOnline) + { + MembershipUser u = null; + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT PKID, Username, Email, PasswordQuestion," + + " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," + + " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" + + " FROM Users WHERE PKID = @PKID", conn)) { + + cmd.Parameters.Add ("@PKID", NpgsqlDbType.Varchar).Value = providerUserKey; + conn.Open (); + + using (NpgsqlDataReader reader = cmd.ExecuteReader ()) { + if (reader.HasRows) { + reader.Read (); + u = GetUserFromReader (reader); + + if (userIsOnline) { + NpgsqlCommand updateCmd = new NpgsqlCommand ("UPDATE Users " + + "SET LastActivityDate = @LastActivityDate " + + "WHERE PKID = @PKID", conn); + updateCmd.Parameters.Add ("@LastActivityDate", DateTime.Now); + updateCmd.Parameters.Add ("@PKID", providerUserKey); + updateCmd.ExecuteNonQuery (); + } + } + reader.Close (); + } + } + conn.Close (); + } + + return u; + } + + + // + // GetUserFromReader + // A helper function that takes the current row from the NpgsqlDataReader + // and hydrates a MembershiUser from the values. Called by the + // MembershipUser.GetUser implementation. + // + + private MembershipUser GetUserFromReader (NpgsqlDataReader reader) + { + object providerUserKey = reader.GetValue (0); + string username = reader.GetString (1); + string email = reader.GetString (2); + + string passwordQuestion = ""; + if (reader.GetValue (3) != DBNull.Value) + passwordQuestion = reader.GetString (3); + + string comment = ""; + if (reader.GetValue (4) != DBNull.Value) + comment = reader.GetString (4); + + bool isApproved = reader.GetBoolean (5); + bool isLockedOut = reader.GetBoolean (6); + DateTime creationDate = reader.GetDateTime (7); + + DateTime lastLoginDate = new DateTime (); + if (reader.GetValue (8) != DBNull.Value) + lastLoginDate = reader.GetDateTime (8); + + DateTime lastActivityDate = reader.GetDateTime (9); + DateTime lastPasswordChangedDate = reader.GetDateTime (10); + + DateTime lastLockedOutDate = new DateTime (); + if (reader.GetValue (11) != DBNull.Value) + lastLockedOutDate = reader.GetDateTime (11); + + MembershipUser u = new MembershipUser (this.Name, + username, + providerUserKey, + email, + passwordQuestion, + comment, + isApproved, + isLockedOut, + creationDate, + lastLoginDate, + lastActivityDate, + lastPasswordChangedDate, + lastLockedOutDate); + + return u; + } + + + // + // MembershipProvider.UnlockUser + // + + public override bool UnlockUser (string username) + { + int rowsAffected = 0; + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("UPDATE Users " + + " SET IsLockedOut = False, LastLockedOutDate = @LastLockedOutDate " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@LastLockedOutDate", DateTime.Now); + cmd.Parameters.Add ("@Username", username); + cmd.Parameters.Add ("@ApplicationName", pApplicationName); + conn.Open (); + rowsAffected = cmd.ExecuteNonQuery (); + conn.Close (); + } + } + if (rowsAffected > 0) + return true; + + return false; + } + + + // + // MembershipProvider.GetUserNameByEmail + // + + public override string GetUserNameByEmail (string email) + { + string username = ""; + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT Username" + + " FROM Users WHERE Email = @Email AND ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@Email", NpgsqlDbType.Varchar, 128).Value = email; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + username = (string)cmd.ExecuteScalar (); + conn.Close (); + } + } + if (username == null) + username = ""; + return username; + } + + // + // MembershipProvider.ResetPassword + // + + public override string ResetPassword (string username, string answer) + { + int rowsAffected = 0; + if (!EnablePasswordReset) { + throw new NotSupportedException ("Password reset is not enabled."); + } + + if (answer == null && RequiresQuestionAndAnswer) { + UpdateFailureCount (username, "passwordAnswer"); + throw new ProviderException ("Password answer required for password reset."); + } + + string newPassword = + System.Web.Security.Membership.GeneratePassword (newPasswordLength, MinRequiredNonAlphanumericCharacters); + + ValidatePasswordEventArgs args = new ValidatePasswordEventArgs (username, newPassword, true); + + OnValidatingPassword (args); + + if (args.Cancel) + if (args.FailureInformation != null) + throw args.FailureInformation; + else + throw new MembershipPasswordException ("Reset password canceled due to password validation failure."); + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT PasswordAnswer, IsLockedOut FROM Users " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + + string passwordAnswer = ""; + conn.Open (); + + using (NpgsqlDataReader reader = cmd.ExecuteReader (CommandBehavior.SingleRow)) { + + if (reader.HasRows) { + reader.Read (); + + if (reader.GetBoolean (1)) + throw new MembershipPasswordException ("The supplied user is locked out."); + + passwordAnswer = reader.GetString (0); + } else { + throw new MembershipPasswordException ("The supplied user name is not found."); + } + + if (RequiresQuestionAndAnswer && !CheckPassword (answer, passwordAnswer)) { + UpdateFailureCount (username, "passwordAnswer"); + + throw new MembershipPasswordException ("Incorrect password answer."); + } + + NpgsqlCommand updateCmd = new NpgsqlCommand ("UPDATE Users " + + " SET Passw = @Password, LastPasswordChangedDate = @LastPasswordChangedDate" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName AND IsLockedOut = False", conn); + + updateCmd.Parameters.Add ("@Password", NpgsqlDbType.Varchar, 255).Value = EncodePassword (newPassword); + updateCmd.Parameters.Add ("@LastPasswordChangedDate", DateTime.Now); + updateCmd.Parameters.Add ("@Username", username); + updateCmd.Parameters.Add ("@ApplicationName", pApplicationName); + + rowsAffected = updateCmd.ExecuteNonQuery (); + + reader.Close (); + } + conn.Close (); + } + } + + if (rowsAffected > 0) { + return newPassword; + } else { + throw new MembershipPasswordException ("User not found, or user is locked out. Password not Reset."); + } + } + + + // + // MembershipProvider.UpdateUser + // + + public override void UpdateUser (MembershipUser user) + { + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("UPDATE Users " + + " SET Email = @Email, Comment = @Comment," + + " IsApproved = @IsApproved" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + cmd.Parameters.Add ("@Email", NpgsqlDbType.Varchar, 128).Value = user.Email; + cmd.Parameters.Add ("@Comment", NpgsqlDbType.Varchar, 255).Value = user.Comment; + cmd.Parameters.Add ("@IsApproved", NpgsqlDbType.Bit).Value = user.IsApproved; + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = user.UserName; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + cmd.ExecuteNonQuery (); + conn.Close (); + } + } + } + + + // + // MembershipProvider.ValidateUser + // + + public override bool ValidateUser (string username, string password) + { + bool isValid = false; + + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT Passw, IsApproved FROM Users " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName AND IsLockedOut = False", conn)) { + + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + + bool isApproved = false; + string pwd = ""; + + conn.Open (); + bool userfound = false; + using (NpgsqlDataReader reader = cmd.ExecuteReader (CommandBehavior.SingleRow)) { + userfound = reader.HasRows; + if (userfound) { + reader.Read (); + pwd = reader.GetString (0); + isApproved = reader.GetBoolean (1); + } + + reader.Close (); + } + if (userfound) { + if (CheckPassword (password, pwd)) { + if (isApproved) { + isValid = true; + + NpgsqlCommand updateCmd = new NpgsqlCommand ("UPDATE Users SET LastLoginDate = @LastLoginDate" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn); + + updateCmd.Parameters.Add ("@LastLoginDate", DateTime.Now); + updateCmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + updateCmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + updateCmd.ExecuteNonQuery (); + } + } else { + UpdateFailureCount (username, "password"); + } + } + conn.Close (); + } + } + + return isValid; + } + + + + /// + /// A helper method that performs the checks and updates associated with + /// password failure tracking. + /// + /// + /// User name. + /// + /// + /// Failure type, one of password, passwordAnswer + /// + private void UpdateFailureCount (string username, string failureType) + { + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT FailedPasswordAttemptCount, " + + " FailedPasswordAttemptWindowStart, " + + " FailedPasswordAnswerAttemptCount, " + + " FailedPasswordAnswerAttemptWindowStart " + + " FROM Users " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName", conn)) { + + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + + DateTime windowStart = new DateTime (); + int failureCount = 0; + + + conn.Open (); + using (NpgsqlDataReader reader = cmd.ExecuteReader (CommandBehavior.SingleRow)) { + + if (reader.HasRows) { + reader.Read (); + + if (failureType == "password") { + failureCount = reader.GetInt32 (0); + windowStart = reader.GetDateTime (1); + } + + if (failureType == "passwordAnswer") { + failureCount = reader.GetInt32 (2); + windowStart = reader.GetDateTime (3); + } + } + + reader.Close (); + } + DateTime windowEnd = windowStart.AddMinutes (PasswordAttemptWindow); + + if (failureCount == 0 || DateTime.Now > windowEnd) { + // First password failure or outside of PasswordAttemptWindow. + // Start a new password failure count from 1 and a new window starting now. + + if (failureType == "password") + cmd.CommandText = "UPDATE Users " + + " SET FailedPasswordAttemptCount = @Count, " + + " FailedPasswordAttemptWindowStart = @WindowStart " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName"; + + if (failureType == "passwordAnswer") + cmd.CommandText = "UPDATE Users " + + " SET FailedPasswordAnswerAttemptCount = @Count, " + + " FailedPasswordAnswerAttemptWindowStart = @WindowStart " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName"; + + cmd.Parameters.Clear (); + + cmd.Parameters.Add ("@Count", NpgsqlDbType.Integer).Value = 1; + cmd.Parameters.Add ("@WindowStart", DateTime.Now); + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + cmd.ExecuteNonQuery (); + + } else { + if (failureCount++ >= MaxInvalidPasswordAttempts) { + // Password attempts have exceeded the failure threshold. Lock out + // the user. + + cmd.CommandText = "UPDATE Users " + + " SET IsLockedOut = @IsLockedOut, LastLockedOutDate = @LastLockedOutDate " + + " WHERE Username = @Username AND ApplicationName = @ApplicationName"; + + cmd.Parameters.Clear (); + + cmd.Parameters.Add ("@IsLockedOut", NpgsqlDbType.Bit).Value = true; + cmd.Parameters.Add ("@LastLockedOutDate", DateTime.Now); + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + cmd.ExecuteNonQuery (); + + } else { + // Password attempts have not exceeded the failure threshold. Update + // the failure counts. Leave the window the same. + + if (failureType == "password") + cmd.CommandText = "UPDATE Users " + + " SET FailedPasswordAttemptCount = @Count" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName"; + + if (failureType == "passwordAnswer") + cmd.CommandText = "UPDATE Users " + + " SET FailedPasswordAnswerAttemptCount = @Count" + + " WHERE Username = @Username AND ApplicationName = @ApplicationName"; + + cmd.Parameters.Clear (); + + cmd.Parameters.Add ("@Count", NpgsqlDbType.Integer).Value = failureCount; + cmd.Parameters.Add ("@Username", NpgsqlDbType.Varchar, 255).Value = username; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + + cmd.ExecuteNonQuery (); + } + } + } + conn.Close (); + } + } + + + // + // CheckPassword + // Compares password values based on the MembershipPasswordFormat. + // + + private bool CheckPassword (string password, string dbpassword) + { + string pass1 = password; + string pass2 = dbpassword; + + switch (PasswordFormat) { + case MembershipPasswordFormat.Encrypted: + pass2 = UnEncodePassword (dbpassword); + break; + case MembershipPasswordFormat.Hashed: + pass1 = EncodePassword (password); + break; + default: + break; + } + if (pass1 == pass2) { + return true; + } + return false; + } + + + // + // EncodePassword + // Encrypts, Hashes, or leaves the password clear based on the PasswordFormat. + // + + private string EncodePassword (string password) + { + string encodedPassword = password; + + switch (PasswordFormat) { + case MembershipPasswordFormat.Clear: + break; + case MembershipPasswordFormat.Encrypted: + encodedPassword = + Convert.ToBase64String (EncryptPassword (Encoding.Unicode.GetBytes (password))); + break; + case MembershipPasswordFormat.Hashed: + HMACSHA1 hash = new HMACSHA1 (); + hash.Key = HexToByte (machineKey.ValidationKey); + encodedPassword = + Convert.ToBase64String (hash.ComputeHash (Encoding.Unicode.GetBytes (password))); + break; + default: + throw new ProviderException ("Unsupported password format."); + } + + return encodedPassword; + } + + + // + // UnEncodePassword + // Decrypts or leaves the password clear based on the PasswordFormat. + // + + private string UnEncodePassword (string encodedPassword) + { + string password = encodedPassword; + + switch (PasswordFormat) { + case MembershipPasswordFormat.Clear: + break; + case MembershipPasswordFormat.Encrypted: + password = + Encoding.Unicode.GetString (DecryptPassword (Convert.FromBase64String (password))); + break; + case MembershipPasswordFormat.Hashed: + throw new ProviderException ("Cannot unencode a hashed password."); + default: + throw new ProviderException ("Unsupported password format."); + } + + return password; + } + + // + // HexToByte + // Converts a hexadecimal string to a byte array. Used to convert encryption + // key values from the configuration. + // + + private byte[] HexToByte (string hexString) + { + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes [i] = Convert.ToByte (hexString.Substring (i * 2, 2), 16); + return returnBytes; + } + + + // + // MembershipProvider.FindUsersByName + // + + public override MembershipUserCollection FindUsersByName (string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) + { + MembershipUserCollection users = new MembershipUserCollection (); + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT count(*)" + + " FROM Users " + + " WHERE Username LIKE @UsernameSearch AND ApplicationName = @ApplicationName ", conn)) { + totalRecords = (int)cmd.ExecuteScalar (); + } + if (totalRecords > 0) + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT PKID, Username, Email, PasswordQuestion," + + " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," + + " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate " + + " FROM Users " + + " WHERE Username LIKE @UsernameSearch AND ApplicationName = @ApplicationName " + + " ORDER BY Username Asc", conn)) { + cmd.Parameters.Add ("@UsernameSearch", NpgsqlDbType.Varchar, 255).Value = usernameToMatch; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = pApplicationName; + conn.Open (); + using (NpgsqlDataReader reader = cmd.ExecuteReader ()) { + int counter = 0; + int startIndex = pageSize * pageIndex; + int endIndex = startIndex + pageSize - 1; + + while (reader.Read()) { + if (counter >= startIndex) { + MembershipUser u = GetUserFromReader (reader); + users.Add (u); + } + if (counter >= endIndex) { + cmd.Cancel (); + } + counter++; + } + reader.Close (); + } + conn.Close (); + } + } + return users; + } + + // + // MembershipProvider.FindUsersByEmail + // + + public override MembershipUserCollection FindUsersByEmail (string emailToMatch, int pageIndex, int pageSize, out int totalRecords) + { + MembershipUserCollection users = new MembershipUserCollection (); + using (NpgsqlConnection conn = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT count(*) " + + " FROM Users " + + " WHERE Email LIKE @EmailSearch AND ApplicationName = @ApplicationName ", conn)) { + totalRecords = (int)cmd.ExecuteScalar (); + } + + using (NpgsqlCommand cmd = new NpgsqlCommand ("SELECT PKID, Username, Email, PasswordQuestion," + + " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," + + " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" + + " FROM Users " + + " WHERE Email LIKE @EmailSearch AND ApplicationName = @ApplicationName " + + " ORDER BY Username Asc", conn)) { + cmd.Parameters.Add ("@EmailSearch", NpgsqlDbType.Varchar, 255).Value = emailToMatch; + cmd.Parameters.Add ("@ApplicationName", NpgsqlDbType.Varchar, 255).Value = ApplicationName; + conn.Open (); + using (NpgsqlDataReader reader = cmd.ExecuteReader ()) { + int counter = 0; + int startIndex = pageSize * pageIndex; + int endIndex = startIndex + pageSize - 1; + + while (reader.Read()) { + if (counter >= startIndex) { + MembershipUser u = GetUserFromReader (reader); + users.Add (u); + } + if (counter >= endIndex) { + cmd.Cancel (); + } + counter++; + } + reader.Close (); + } + conn.Close (); + } + } + return users; + } + + } +} diff --git a/NpgsqlMRPProviders/NpgsqlProfileProvider.cs b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs new file mode 100644 index 00000000..44e362cc --- /dev/null +++ b/NpgsqlMRPProviders/NpgsqlProfileProvider.cs @@ -0,0 +1,237 @@ +using System; +using System.Configuration; +using System.Web.Profile; +using Npgsql; + +namespace Npgsql.Web +{ + public class NpgsqlProfileProvider: ProfileProvider + { + private string connectionString; + private string applicationName; + + public NpgsqlProfileProvider () + { + } + + public override void Initialize (string iname, System.Collections.Specialized.NameValueCollection config) + { + // get the + // - application name + // - connection string name + // - the connection string from its name + string cnxName = config ["connectionStringName"]; + connectionString = ConfigurationManager.ConnectionStrings [cnxName].ConnectionString; + config.Remove ("connectionStringName"); + applicationName = config ["applicationName"]; + config.Remove ("applicationName"); + base.Initialize (iname, config); + } + + #region implemented abstract members of System.Web.Profile.ProfileProvider + + public override int DeleteInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) + { + throw new System.NotImplementedException (); + } + + public override int DeleteProfiles (string[] usernames) + { + throw new System.NotImplementedException (); + } + + public override int DeleteProfiles (ProfileInfoCollection profiles) + { + throw new System.NotImplementedException (); + } + + public override ProfileInfoCollection FindInactiveProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) + { + throw new System.NotImplementedException (); + } + + public override ProfileInfoCollection FindProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) + { + if (pageIndex < 0) + throw new ArgumentException ("pageIndex"); + if (pageSize < 1) + throw new ArgumentException ("pageSize"); + + long lowerBound = (long)pageIndex * pageSize; + long upperBound = lowerBound + pageSize - 1; + if (upperBound > Int32.MaxValue) + throw new ArgumentException ("lowerBound + pageSize*pageIndex -1 > Int32.MaxValue"); + ProfileInfoCollection c = new ProfileInfoCollection (); + totalRecords = 0; + + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "select username, uniqueid, lastactivitydate, lastupdateddate, isanonymous from profiles where username like @username and applicationname = @appname"; + cmd.Parameters.Add ("@username", usernameToMatch); + cmd.Parameters.Add ("@appname", applicationName); + cnx.Open (); + using (NpgsqlDataReader r = cmd.ExecuteReader ()) { + if (r.HasRows) { + while (r.Read ()) { + if (totalRecords >= lowerBound && totalRecords <= upperBound) { + + object o = r.GetValue (r.GetOrdinal ("isanonymous")); + bool isanon = o is DBNull ? true : (bool) o; + o = r.GetValue (r.GetOrdinal ("lastactivitydate")); + DateTime lact = o is DBNull ? new DateTime() : (DateTime) o; + o = r.GetValue (r.GetOrdinal ("lastupdateddate")); + DateTime lupd = o is DBNull ? new DateTime() : (DateTime) o; + ProfileInfo pi = + new ProfileInfo ( + r.GetString (r.GetOrdinal ("username")), + isanon, + lact, + lupd, + 0); + c.Add (pi); + totalRecords++; + } + } + } + } + } + + } + return c; + } + + public override ProfileInfoCollection GetAllInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) + { + throw new System.NotImplementedException (); + } + + public override ProfileInfoCollection GetAllProfiles (ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) + { + throw new System.NotImplementedException (); + } + + public override int GetNumberOfInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) + { + throw new System.NotImplementedException (); + } + + #endregion + + #region implemented abstract members of System.Configuration.SettingsProvider + + public override SettingsPropertyValueCollection GetPropertyValues (SettingsContext context, SettingsPropertyCollection collection) + { + SettingsPropertyValueCollection c = new SettingsPropertyValueCollection (); + if (collection == null || collection.Count < 1 || context == null) + return c; + string username = (string)context ["UserName"]; + if (String.IsNullOrEmpty (username)) + return c; + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "SELECT * from profiledata,profiles where " + + "profiledata.uniqueid = profiles.uniqueid " + + "and profiles.username = @username " + + "and profiles.applicationname = @appname"; + cmd.Parameters.Add ("@username", username); + cmd.Parameters.Add ("@appname", applicationName); + cnx.Open (); + using (NpgsqlDataReader r = cmd.ExecuteReader ( + System.Data.CommandBehavior.CloseConnection | System.Data.CommandBehavior.SingleRow)) { + if (r.Read ()) { + foreach (SettingsProperty p in collection) { + SettingsPropertyValue v = new SettingsPropertyValue (p); + int o = r.GetOrdinal (p.Name.ToLower ()); + v.PropertyValue = r.GetValue (o); + c.Add (v); + } + } else { + foreach (SettingsProperty p in collection) { + SettingsPropertyValue v = new SettingsPropertyValue (p); + v.PropertyValue = null; + c.Add (v); + } + } + } + } + return c; + + } + + public override void SetPropertyValues (SettingsContext context, SettingsPropertyValueCollection collection) + { + // get the unique id of the profile + if (collection == null) + return; + long puid = 0; + string username = (string)context ["UserName"]; + + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { + cnx.Open (); + using (NpgsqlCommand cmdpi = cnx.CreateCommand ()) { + cmdpi.CommandText = "select count(uniqueid) " + + "from profiles where username = @username " + + "and applicationname = @appname"; + cmdpi.Parameters.Add ("@username", username); + cmdpi.Parameters.Add ("@appname", applicationName); + + long c = (long)cmdpi.ExecuteScalar (); + if (c == 0) { + cmdpi.CommandText = "insert into profiles (username,applicationname) " + + "values ( @username, @appname ) " + + "returning uniqueid"; + puid = (long)cmdpi.ExecuteScalar (); + // TODO spec: profiledata insertion <=> profile insertion + // => BAD DESIGN + // + using (NpgsqlCommand cmdpdins = cnx.CreateCommand ()) { + cmdpdins.CommandText = "insert into profiledata (uniqueid) values (@puid)"; + cmdpdins.Parameters.Add ("@puid", puid); + cmdpdins.ExecuteNonQuery (); + } + } else { + cmdpi.CommandText = "select uniqueid from profiles where username = @username " + + "and applicationname = @appname"; + puid = (long)cmdpi.ExecuteScalar (); + } + } + + + foreach (SettingsPropertyValue s in collection) { + if (s.UsingDefaultValue) { + //TODO Drop the property in the profile + } else { + // update the property value + // TODO update to null values (included to avoid Not Implemented columns in profiledata + if (s.PropertyValue != null) { + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = string.Format ( + "update profiledata " + + "set {0} = @val " + + "where uniqueid = @puid ", + s.Name + ); + cmd.Parameters.Add ("@puid", puid); + cmd.Parameters.Add ("@val", s.PropertyValue); + cmd.ExecuteNonQuery (); + } + } + } + } + } + } + + public override string ApplicationName { + get { + return applicationName; + } + set { + applicationName = value; + } + } + + #endregion + + } +} + diff --git a/NpgsqlMRPProviders/NpgsqlRoleProvider.cs b/NpgsqlMRPProviders/NpgsqlRoleProvider.cs new file mode 100644 index 00000000..c583d8ea --- /dev/null +++ b/NpgsqlMRPProviders/NpgsqlRoleProvider.cs @@ -0,0 +1,364 @@ +using System; +using System.Web.Security; +using System.Configuration.Provider; +using System.Configuration; +using Npgsql; +using System.Collections.Generic; + +/* + * +CREATE TABLE roles +( + rolename character varying(255) NOT NULL, + applicationname character varying(255) NOT NULL, + comment character varying(255) NOT NULL, + CONSTRAINT roles_pkey PRIMARY KEY (rolename , applicationname ) +) +WITH ( + OIDS=FALSE +); + +CREATE TABLE usersroles +( + applicationname character varying(255) NOT NULL, + rolename character varying(255) NOT NULL, + username character varying(255) NOT NULL, + CONSTRAINT attrroles_pkey PRIMARY KEY (applicationname , rolename , username ), + CONSTRAINT usersroles_fk_role FOREIGN KEY (applicationname, rolename) + REFERENCES roles (applicationname, rolename) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE, + CONSTRAINT usersroles_fk_user FOREIGN KEY (applicationname, username) + REFERENCES users (applicationname, username) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE +) +WITH ( + OIDS=FALSE +); + + */ +using System.Linq; + + +namespace Npgsql.Web +{ + public class NpgsqlRoleProvider: RoleProvider + { + protected string name = "NpgsqlRoleProvider"; + protected string connectionStringName = "pgProvider"; + protected string applicationName = "/"; + protected string connectionString = string.Empty; + + public override void Initialize (string iname, System.Collections.Specialized.NameValueCollection config) + { + try { + + name = iname ?? config ["name"]; + + connectionStringName = config ["connectionStringName"] ?? connectionStringName; + + applicationName = config ["applicationName"] ?? applicationName; + + if (applicationName.Length > 250) + throw new ProviderException ("The maximum length for an application name is 250 characters."); + + var cs = ConfigurationManager.ConnectionStrings [connectionStringName]; + if (cs == null || string.IsNullOrEmpty (cs.ConnectionString)) { + throw new ProviderException ( + string.Format ("The role provider connection string, '{0}', is not defined.", connectionStringName)); + } + + connectionString = ConfigurationManager.ConnectionStrings [connectionStringName].ConnectionString; + if (string.IsNullOrEmpty (connectionString)) + throw new ConfigurationErrorsException ( + string.Format ( + "The connection string for the given name ({0})" + + "must be specified in the " + + "configuration bloc. Aborting.", connectionStringName) + ); + + } catch (Exception ex) { + var message = "Error initializing the role configuration settings"; + throw new ProviderException (message, ex); + } + } + + public override void AddUsersToRoles (string[] usernames, string[] roleNames) + { + if (usernames.Any (x => x == null) || roleNames.Any (x => x == null)) { + throw new ArgumentNullException (); + } + if (usernames.Any (x => x.Trim () == string.Empty) || (roleNames.Any (x => x.Trim () == string.Empty))) { + throw new ArgumentException ("One or more of the supplied usernames or role names are empty."); + } + + + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "insert into usersroles (applicationname, username, rolename) values (@appname,@user,@role)"; + comm.Parameters.Add ("appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + NpgsqlParameter pu = comm.Parameters.Add ("user", NpgsqlTypes.NpgsqlDbType.Varchar, 250); + NpgsqlParameter pr = comm.Parameters.Add ("role", NpgsqlTypes.NpgsqlDbType.Varchar, 250); + foreach (string u in usernames) { + pu.Value = u; + foreach (string r in roleNames) { + pr.Value = r; + comm.ExecuteNonQuery (); + } + } + } + + } + + } + + public override string ApplicationName { + get { + return applicationName; + } + set { + applicationName = value; + } + } + + public override void CreateRole (string roleName) + { + if (roleName == null) + throw new ArgumentNullException (); + if (roleName.Trim () == string.Empty) + throw new ArgumentException ("A role name cannot be empty."); + if (roleName.Contains (",")) + throw new ArgumentException ("A role name cannot contain commas. Blame Microsoft for that rule!"); + if (roleName.Length > 250) + throw new ArgumentException ("The maximum length for a Role name is 250 characters."); + + + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "insert into roles (rolename, applicationname, comment) values (@rolename, @appname, @comment)"; + comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + comm.Parameters.Add ("@comment", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; + comm.ExecuteNonQuery (); + } + } + + } + + public override bool DeleteRole (string roleName, bool throwOnPopulatedRole) + { + if (roleName == null) + throw new ArgumentNullException (); + if (roleName.Trim () == string.Empty) + throw new ArgumentException ("The specified role name cannot be empty."); + if (throwOnPopulatedRole) + if (FindUsersInRole (roleName, "").Count () > 0) + throw new ProviderException ( + string.Format ("The role {0} is populated, we cannot delete it.", roleName)); + + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "delete from roles where rolename = @rolename and applicationname = @appname"; + comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + comm.Parameters.Add ("@comment", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; + comm.ExecuteNonQuery (); + } + } + return true; + } + + public override string[] FindUsersInRole (string roleName, string usernameToMatch) + { + return GetUsersInRole (roleName, usernameToMatch); + } + + protected string[] GetUsersInRole (string rolename, string usernameToMatch) + { + if (rolename == null) + throw new ArgumentNullException (); + if (rolename == string.Empty) + throw new ProviderException ("Cannot look for blank role names."); + usernameToMatch = usernameToMatch ?? string.Empty; + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select username from usersroles where applicationname = @appname " + + "and rolename = @rolename and username like @username"; + comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = rolename; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + comm.Parameters.Add ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = usernameToMatch; + using (var reader = comm.ExecuteReader()) { + var r = new List (); + var usernameColumn = reader.GetOrdinal ("username"); + while (reader.Read()) { + r.Add (reader.GetString (usernameColumn)); + } + return r.ToArray (); + } + } + } + } + + public override string[] GetAllRoles () + { + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select rolename from roles where applicationname = @appname"; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + using (var reader = comm.ExecuteReader()) { + var r = new List (); + var rolenameColumn = reader.GetOrdinal ("rolename"); + while (reader.Read()) { + r.Add (reader.GetString (rolenameColumn)); + } + return r.ToArray (); + } + } + } + } + + public override string[] GetRolesForUser (string username) + { + if (username == null) + throw new ArgumentNullException (); + if (username.Trim () == string.Empty) + throw new ArgumentException ("The specified username cannot be blank."); + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select rolename from usersroles where applicationname = @appname and username = @username"; + comm.Parameters.Add ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = username; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + using (var reader = comm.ExecuteReader()) { + var r = new List (); + var rolenameColumn = reader.GetOrdinal ("rolename"); + while (reader.Read()) { + r.Add (reader.GetString (rolenameColumn)); + } + return r.ToArray (); + } + } + } + } + + public override string[] GetUsersInRole (string roleName) + { + if (string.IsNullOrEmpty (roleName)) + throw new ArgumentException ("The specified role name cannot be blank or null"); + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + // + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select username from usersroles where applicationname = @appname " + + "and rolename = @rolename"; + comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 255).Value = roleName; + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 255).Value = applicationName; + using (var reader = comm.ExecuteReader()) { + var r = new List (); + var usernameColumn = reader.GetOrdinal ("username"); + while (reader.Read()) { + r.Add (reader.GetString (usernameColumn)); + } + return r.ToArray (); + } + } + } + } + + public override bool IsUserInRole (string username, string roleName) + { + if (username == null || roleName == null) + throw new ArgumentNullException (); + if (username.Trim () == string.Empty) + throw new ArgumentException ("The specified username cannot be blank."); + if (roleName.Trim () == string.Empty) + throw new ArgumentException ("The specified role name cannot be blank."); + + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + // + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select count(*)>0 from usersroles where applicationname = @appname " + + "and username = @username and rolename = @rolename"; + comm.Parameters.Add ("@username", username); + comm.Parameters.Add ("@rolename", roleName); + comm.Parameters.Add ("@appname", applicationName); + var retval = (bool)comm.ExecuteScalar (); + return retval; + } + } + + } + + public override void RemoveUsersFromRoles (string[] usernames, string[] roleNames) + { + if (usernames.Any (x => x == null) || roleNames.Any (x => x == null)) { + throw new ArgumentNullException (); + } + if (usernames.Any (x => x.Trim () == string.Empty) || (roleNames.Any (x => x.Trim () == string.Empty))) { + throw new ArgumentException ("One or more of the supplied usernames or role names are empty."); + } + + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = conn.CreateCommand()) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "delete from usersroles where applicationname = @appname and " + + "username = @username and rolename = @rolename"; + NpgsqlParameter pu = comm.Parameters.Add ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250); + NpgsqlParameter pr = comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250); + comm.Parameters.Add ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + foreach (string rolename in roleNames) { + pr.Value = rolename; + foreach (string username in usernames) { + pu.Value = username; + comm.ExecuteNonQuery (); + } + } + } + } + + } + + public override bool RoleExists (string roleName) + { + using (var conn = new NpgsqlConnection(connectionString)) { + conn.Open (); + using (var comm = new NpgsqlCommand("role_exists", conn)) { + comm.CommandType = System.Data.CommandType.Text; + comm.CommandText = "select Count(*)>0 from roles where applicationname = @applicationname and rolename = @rolename"; + comm.Parameters.Add ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; + comm.Parameters.Add ("@applicationname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; + var retval = (bool)comm.ExecuteScalar (); + return retval; + } + } + } + + public override string Name { + get { + return name; + } + } + + public override string Description { + get { + return "PostgreSQL ASP.Net Role Provider class"; + } + } + } +} + diff --git a/NpgsqlMRPProviders/Sql/ProfileData.sql b/NpgsqlMRPProviders/Sql/ProfileData.sql new file mode 100644 index 00000000..76d63571 --- /dev/null +++ b/NpgsqlMRPProviders/Sql/ProfileData.sql @@ -0,0 +1,28 @@ +-- Table: profiledata + +-- DROP TABLE profiledata; + +CREATE TABLE profiledata +( + uniqueid integer, + zipcode character varying(10), + cityandstate character varying(255), + avatar bytea, + CONSTRAINT fkprofiles2 FOREIGN KEY (uniqueid) + REFERENCES profiles (uniqueid) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE +) +WITH ( + OIDS=FALSE +); + +-- Index: fki_fkprofiles2 + +-- DROP INDEX fki_fkprofiles2; + +CREATE INDEX fki_fkprofiles2 + ON profiledata + USING btree + (uniqueid ); + + diff --git a/NpgsqlMRPProviders/Sql/RolesTable.sql b/NpgsqlMRPProviders/Sql/RolesTable.sql new file mode 100644 index 00000000..71e9fc0f --- /dev/null +++ b/NpgsqlMRPProviders/Sql/RolesTable.sql @@ -0,0 +1,18 @@ +-- Table: roles + +-- DROP TABLE roles; + +CREATE TABLE roles +( + rolename character varying(255) NOT NULL, + applicationname character varying(255) NOT NULL, + comment character varying(255) NOT NULL, + CONSTRAINT roles_pkey PRIMARY KEY (rolename , applicationname ) +) +WITH ( + OIDS=FALSE +); + +COMMENT ON TABLE roles + IS 'Web application roles'; + diff --git a/NpgsqlMRPProviders/Sql/StockSymbols.sql b/NpgsqlMRPProviders/Sql/StockSymbols.sql new file mode 100644 index 00000000..53a88c2f --- /dev/null +++ b/NpgsqlMRPProviders/Sql/StockSymbols.sql @@ -0,0 +1,16 @@ + +-- Table: stocksymbols + +-- DROP TABLE stocksymbols; + +CREATE TABLE stocksymbols +( + uniqueid integer, + stocksymbol character varying(10), + CONSTRAINT fkprofiles1 FOREIGN KEY (uniqueid) + REFERENCES profiles (uniqueid) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION +) +WITH ( + OIDS=FALSE +); diff --git a/NpgsqlMRPProviders/Sql/UserRoleTable.sql b/NpgsqlMRPProviders/Sql/UserRoleTable.sql new file mode 100644 index 00000000..639ee34e --- /dev/null +++ b/NpgsqlMRPProviders/Sql/UserRoleTable.sql @@ -0,0 +1,21 @@ + +-- Table: usersroles + +-- DROP TABLE usersroles; + +CREATE TABLE usersroles +( + applicationname character varying(255) NOT NULL, + rolename character varying(255) NOT NULL, + username character varying(255) NOT NULL, + CONSTRAINT attrroles_pkey PRIMARY KEY (applicationname , rolename , username ), + CONSTRAINT usersroles_fk_role FOREIGN KEY (applicationname, rolename) + REFERENCES roles (applicationname, rolename) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE, + CONSTRAINT usersroles_fk_user FOREIGN KEY (applicationname, username) + REFERENCES users (applicationname, username) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE +) +WITH ( + OIDS=FALSE +); diff --git a/NpgsqlMRPProviders/Sql/UsersTable.sql b/NpgsqlMRPProviders/Sql/UsersTable.sql new file mode 100644 index 00000000..813142da --- /dev/null +++ b/NpgsqlMRPProviders/Sql/UsersTable.sql @@ -0,0 +1,19 @@ +-- Table: profiles + +-- DROP TABLE profiles; + +CREATE TABLE profiles +( + uniqueid bigserial NOT NULL, + username character varying(255) NOT NULL, + applicationname character varying(255) NOT NULL, + isanonymous boolean, + lastactivitydate timestamp with time zone, + lastupdateddate timestamp with time zone, + CONSTRAINT profiles_pkey PRIMARY KEY (uniqueid ), + CONSTRAINT pkprofiles UNIQUE (username , applicationname ) +) +WITH ( + OIDS=FALSE +); + diff --git a/SalesCatalog/AssemblyInfo.cs b/SalesCatalog/AssemblyInfo.cs new file mode 100644 index 00000000..8bc3c1de --- /dev/null +++ b/SalesCatalog/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("SalesCatalog")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("paul")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/SalesCatalog/CatalogHelper.cs b/SalesCatalog/CatalogHelper.cs new file mode 100644 index 00000000..b6a859f0 --- /dev/null +++ b/SalesCatalog/CatalogHelper.cs @@ -0,0 +1,45 @@ +using System; +using System.Configuration; +using System.Reflection; +using System.Collections.Specialized; +using SalesCatalog.Configuration; + +namespace SalesCatalog +{ + /// + /// Catalog helper. + /// Used by the catalog manager to get the catalog provider from the configuration. + /// + public static class CatalogHelper + { + public static CatalogProvider GetProvider () + { + CatalogProvidersConfigurationSection config = ConfigurationManager.GetSection ("system.web/catalog") as CatalogProvidersConfigurationSection; + if (config == null) + throw new ConfigurationErrorsException("The configuration bloc for the catalog provider was not found"); + CatalogProviderConfigurationElement celt = + config.Providers.GetElement (config.DefaultProvider); + if (celt == null) + throw new ConfigurationErrorsException("The default catalog provider was not found"); + Type catprtype = Type.GetType (celt.Type); + if (catprtype == null) + throw new Exception ( + string.Format("The catalog provider type ({0}) could not be found",celt.Type)); + ConstructorInfo ci = catprtype.GetConstructor (Type.EmptyTypes); + if (ci==null) + throw new Exception ( + string.Format("The catalog provider type ({0}) doesn't contain public constructor with empty parameter list",celt.Type)); + + CatalogProvider cp = ci.Invoke (Type.EmptyTypes) as CatalogProvider; + NameValueCollection c = new NameValueCollection (); + c.Add ("name", celt.Name); + c.Add ("type", celt.Type); + c.Add ("connection", celt.Connection); + c.Add ("description", celt.Description); + c.Add ("applicationName", celt.ApplicationName); + cp.Initialize (celt.Name, c); + return cp; + } + } +} + diff --git a/SalesCatalog/CatalogManager.cs b/SalesCatalog/CatalogManager.cs new file mode 100644 index 00000000..d1e77809 --- /dev/null +++ b/SalesCatalog/CatalogManager.cs @@ -0,0 +1,19 @@ +using System; +using SalesCatalog.Model; + +namespace SalesCatalog +{ + /// + /// Catalog manager. + /// Use this class to retreive the catalog or its elements + /// + public static class CatalogManager + { + public static Catalog GetCatalog () + { + CatalogProvider p = CatalogHelper.GetProvider (); + return p.GetCatalog (); + } + } +} + diff --git a/SalesCatalog/CatalogProvider.cs b/SalesCatalog/CatalogProvider.cs new file mode 100644 index 00000000..c7fa1e32 --- /dev/null +++ b/SalesCatalog/CatalogProvider.cs @@ -0,0 +1,16 @@ +using System; +using System.Configuration.Provider; +using SalesCatalog.Model; + +namespace SalesCatalog +{ + /// + /// Catalog provider.
+ /// Abstract class, inherited to implement a catalog provider. + ///
+ public abstract class CatalogProvider: ProviderBase + { + public abstract Catalog GetCatalog (); + } +} + diff --git a/SalesCatalog/Configuration/CatalogProviderConfigurationElement.cs b/SalesCatalog/Configuration/CatalogProviderConfigurationElement.cs new file mode 100644 index 00000000..60488a35 --- /dev/null +++ b/SalesCatalog/Configuration/CatalogProviderConfigurationElement.cs @@ -0,0 +1,39 @@ +using System; +using System.Configuration; + +namespace SalesCatalog.Configuration +{ + + public class CatalogProviderConfigurationElement : ConfigurationElement + { + [ConfigurationProperty("name", IsRequired = true, IsKey=true)] + public string Name { + get { return (string)this ["name"]; } + set { this ["name"] = value; } + } + + [ConfigurationProperty("type", IsRequired = true)] + public string Type { + get { return (string)this ["type"]; } + set { this ["type"] = value; } + } + + [ConfigurationProperty("connection")] + public string Connection { + get { return (string)this ["connection"]; } + set { this ["connection"] = value; } + } + + [ConfigurationProperty("description")] + public string Description { + get { return (string)this ["description"]; } + set { this ["description"] = value; } + } + + [ConfigurationProperty("applicationName")] + public string ApplicationName { + get { return (string)this ["applicationName"]; } + set { this ["applicationName"] = value; } + } + } +} diff --git a/SalesCatalog/Configuration/CatalogProvidersConfigurationCollection.cs b/SalesCatalog/Configuration/CatalogProvidersConfigurationCollection.cs new file mode 100644 index 00000000..cf1491a2 --- /dev/null +++ b/SalesCatalog/Configuration/CatalogProvidersConfigurationCollection.cs @@ -0,0 +1,26 @@ +using System; +using System.Configuration; +using System.ComponentModel; + +namespace SalesCatalog.Configuration +{ + public class CatalogProvidersConfigurationCollection : ConfigurationElementCollection + { + protected override ConfigurationElement CreateNewElement () + { + return new CatalogProviderConfigurationElement(); + } + + protected override object GetElementKey (ConfigurationElement element) + { + return ((CatalogProviderConfigurationElement) element).Name; + } + + public CatalogProviderConfigurationElement GetElement (string name) + { + return this.BaseGet(name) as CatalogProviderConfigurationElement; + } + } + +} + diff --git a/SalesCatalog/Configuration/CatalogProvidersConfigurationSection.cs b/SalesCatalog/Configuration/CatalogProvidersConfigurationSection.cs new file mode 100644 index 00000000..b6f945c9 --- /dev/null +++ b/SalesCatalog/Configuration/CatalogProvidersConfigurationSection.cs @@ -0,0 +1,26 @@ +using System; +using System.Configuration; +using System.ComponentModel; + +namespace SalesCatalog.Configuration +{ + public class CatalogProvidersConfigurationSection : ConfigurationSection + { + [ConfigurationProperty("defaultProvider")] + public string DefaultProvider { + get { return (string)base ["defaultProvider"]; } + set { base ["defaultProvider"] = value; } + } + + [ConfigurationProperty("providers")] + [ConfigurationCollection(typeof(CatalogProvidersConfigurationCollection), + AddItemName = "add", + ClearItemsName = "clear", + RemoveItemName = "remove")] + public CatalogProvidersConfigurationCollection Providers{ + get { return (CatalogProvidersConfigurationCollection) base ["providers"]; } + set { base ["providers"] = value; } + } + } + +} diff --git a/SalesCatalog/Model/Brand.cs b/SalesCatalog/Model/Brand.cs new file mode 100644 index 00000000..0c948542 --- /dev/null +++ b/SalesCatalog/Model/Brand.cs @@ -0,0 +1,37 @@ +using System; +using System.Xml.Serialization; +using System.ComponentModel.DataAnnotations; + +namespace SalesCatalog.Model +{ + public class Brand + { + public Brand () + { + } + + [Required] + public string Name { get; set; } + + public string Slogan { get; set; } + + public ProductImage Logo { get; set; } + + public ProductCategory[] Categories { get; set; } + /// + /// Gets or sets the default form. + /// + /// The default form. + public SaleForm DefaultForm { get; set; } + + public ProductCategory GetProductCategory(string reference) + { + return Array.Find(Categories, c => c.Reference == reference); + } + public ProductCategory GetProductCategoryByName(string catName) + { + return Array.Find(Categories, c => c.Name == catName); + } + } +} + diff --git a/SalesCatalog/Model/Catalog.cs b/SalesCatalog/Model/Catalog.cs new file mode 100644 index 00000000..93dad93a --- /dev/null +++ b/SalesCatalog/Model/Catalog.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace SalesCatalog.Model +{ + /// + /// Catalog. + /// + public class Catalog { + /// + /// Gets or sets the brands. + /// + /// The brands. + public Brand[] Brands { get; set; } + + public Brand GetBrand(string brandName) + { + return Array.Find(Brands, b => b.Name == brandName); + } + + public Brand AddBrand(string brandName,string slogan=null, ProductImage logo=null) + { + Brand[] oldbrs = (Brand[]) Brands.Clone (); + int oldl = Brands.Length; + Array.Resize(ref oldbrs,oldl+1); + Brand b = new Brand (); + b.Name=brandName; + b.Slogan = slogan; + b.Logo = logo; + oldbrs [oldl] = b; + Brands=oldbrs; + return b; + } + + public bool RemoveBrand(string brandName) + { + Brand b = this.GetBrand (brandName); + if (b == null) + return false; + //assert(Brands.Length>0); + List nb = new List (Brands); + nb.Remove (b); + Brands = nb.ToArray (); + return true; + } + + public DateTime StartDate { get; set; } + + public DateTime EndDate { get; set; } + + } + +} diff --git a/SalesCatalog/Model/CheckBox.cs b/SalesCatalog/Model/CheckBox.cs new file mode 100644 index 00000000..b1e37c20 --- /dev/null +++ b/SalesCatalog/Model/CheckBox.cs @@ -0,0 +1,18 @@ +using System; + +namespace SalesCatalog.Model +{ + public class CheckBox : FormInput + { + public CheckBox () + { + } + public bool Value { get; set; } + + public override string ToHtml () + { + return string.Format ("", Id,Name,Value?"checked":""); + } + } +} + diff --git a/SalesCatalog/Model/Currency.cs b/SalesCatalog/Model/Currency.cs new file mode 100644 index 00000000..0700448c --- /dev/null +++ b/SalesCatalog/Model/Currency.cs @@ -0,0 +1,9 @@ +using System; + +namespace SalesCatalog.Model +{ + public abstract class Currency: Unit + { + } +} + diff --git a/SalesCatalog/Model/Euro.cs b/SalesCatalog/Model/Euro.cs new file mode 100644 index 00000000..72e3f576 --- /dev/null +++ b/SalesCatalog/Model/Euro.cs @@ -0,0 +1,34 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Euro : Currency + { + public Euro () + { + } + + public override string Name { + get { + return "Euro"; + } + } + + public override string Description { + get { + return "European currency"; + } + } + + public override bool MayConvertTo (Unit other) + { + return other.GetType().IsSubclassOf(typeof (Currency)); + } + + public override object ConvertTo (Unit dest, object value) + { + throw new NotImplementedException(); + } + } +} + diff --git a/SalesCatalog/Model/FilesInput.cs b/SalesCatalog/Model/FilesInput.cs new file mode 100644 index 00000000..8fd64376 --- /dev/null +++ b/SalesCatalog/Model/FilesInput.cs @@ -0,0 +1,18 @@ +using System; + +namespace SalesCatalog.Model +{ + public class FilesInput : FormInput + { + + public FilesInput () + { + } + + public override string ToHtml () + { + return string.Format ("", Id); + } + } +} + diff --git a/SalesCatalog/Model/FormElement.cs b/SalesCatalog/Model/FormElement.cs new file mode 100644 index 00000000..283c0312 --- /dev/null +++ b/SalesCatalog/Model/FormElement.cs @@ -0,0 +1,10 @@ +using System; + +namespace SalesCatalog.Model +{ + public abstract class FormElement + { + public abstract string ToHtml (); + } +} + diff --git a/SalesCatalog/Model/FormInput.cs b/SalesCatalog/Model/FormInput.cs new file mode 100644 index 00000000..63a8e1d9 --- /dev/null +++ b/SalesCatalog/Model/FormInput.cs @@ -0,0 +1,19 @@ +using System; + +namespace SalesCatalog.Model +{ + public abstract class FormInput: FormElement + { + /// + /// Gets or sets the identifier, unique in its Form. + /// + /// + /// The identifier. + /// + + public string Id { get; set; } + private string name=null; + public string Name { get { return name == null ? Id : name; } set { name = value; } } + } +} + diff --git a/SalesCatalog/Model/Label.cs b/SalesCatalog/Model/Label.cs new file mode 100644 index 00000000..6b3c9803 --- /dev/null +++ b/SalesCatalog/Model/Label.cs @@ -0,0 +1,18 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Label:FormElement + { + public Label () + { + } + string Text { get; set; } + string For { get; set ; } + public override string ToHtml () + { + return string.Format ("", For, Text); + } + } +} + diff --git a/SalesCatalog/Model/Link.cs b/SalesCatalog/Model/Link.cs new file mode 100644 index 00000000..728c824c --- /dev/null +++ b/SalesCatalog/Model/Link.cs @@ -0,0 +1,15 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace SalesCatalog.Model +{ + public class Link:Label + { + public Link () + { + } + [Required] + public string Ref { get; set; } + } +} + diff --git a/SalesCatalog/Model/Note.cs b/SalesCatalog/Model/Note.cs new file mode 100644 index 00000000..add594c4 --- /dev/null +++ b/SalesCatalog/Model/Note.cs @@ -0,0 +1,13 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Note:Text + { + public override string ToHtml () + { + return string.Format("{0}",Val); + } + } +} + diff --git a/SalesCatalog/Model/Option.cs b/SalesCatalog/Model/Option.cs new file mode 100644 index 00000000..daeea5a3 --- /dev/null +++ b/SalesCatalog/Model/Option.cs @@ -0,0 +1,19 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Option : FormElement + { + public Option () + { + } + public string Value { get; set; } + public string Text { get; set; } + + public override string ToHtml () + { + return string.Format ("\n",Value,Text); + } + } +} + diff --git a/SalesCatalog/Model/Period.cs b/SalesCatalog/Model/Period.cs new file mode 100644 index 00000000..b4e30b31 --- /dev/null +++ b/SalesCatalog/Model/Period.cs @@ -0,0 +1,15 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Period + { + public Period () + { + } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + + } +} + diff --git a/SalesCatalog/Model/PhysicalProduct.cs b/SalesCatalog/Model/PhysicalProduct.cs new file mode 100644 index 00000000..c90c14ee --- /dev/null +++ b/SalesCatalog/Model/PhysicalProduct.cs @@ -0,0 +1,27 @@ +using System; + +namespace SalesCatalog.Model +{ + public class PhysicalProduct : Product + { + public PhysicalProduct () + { + } + public Price UnitaryPrice { get; set; } + #region implemented abstract members of SalesCatalog.Model.Product + public override string[] GetSalesConditions () + { + return new string [] { string.Format( + "Prix unitaire : {0} {1}", + UnitaryPrice.Quantity.ToString(), + UnitaryPrice.Unit.Name) }; + } + #endregion + + public override string ToString () + { + return string.Format ("[PhysicalProduct: UnitaryPrice={0}]", UnitaryPrice); + } + } +} + diff --git a/SalesCatalog/Model/Price.cs b/SalesCatalog/Model/Price.cs new file mode 100644 index 00000000..dee40da1 --- /dev/null +++ b/SalesCatalog/Model/Price.cs @@ -0,0 +1,36 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Price: Scalar + { + public Price () + { + } + + decimal quantity; + + #region implemented abstract members of SalesCatalog.Value + public override object Quantity { + get { + return quantity; + } + set { + quantity = (decimal) value; + } + } + + Currency curr; + public override SalesCatalog.Model.Unit Unit { + get { + return curr; + } + set { + curr = (Currency)value; + } + } + #endregion + + } +} + diff --git a/SalesCatalog/Model/Product.cs b/SalesCatalog/Model/Product.cs new file mode 100644 index 00000000..10f1b356 --- /dev/null +++ b/SalesCatalog/Model/Product.cs @@ -0,0 +1,37 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace SalesCatalog.Model +{ + /// + /// Product. + /// Crucial object in the catalog, + /// being at each origin of form display + /// its properties may be used to fill some form input values or other form element. + /// in text values, within {} ex: {Name} : {Price} ({stockStatus}) ($description) . + /// + public abstract class Product + { + /// + /// Gets or sets the product name. + /// + /// The name. + [Required] + [StringLength(1024)] + public string Name { get; set; } + /// + /// Gets or sets the product description. + /// + /// The description. + public string Description { get; set; } + public ProductImage[] Images { get; set; } + public SaleForm CommandForm { get; set; } + [Required] + [StringLength(255)] + public string Reference { get; set; } + public Period CommandValidityDates { get; set; } + public abstract string[] GetSalesConditions(); + + } +} + diff --git a/SalesCatalog/Model/ProductCategory.cs b/SalesCatalog/Model/ProductCategory.cs new file mode 100644 index 00000000..be88b5b9 --- /dev/null +++ b/SalesCatalog/Model/ProductCategory.cs @@ -0,0 +1,23 @@ +using System; + +namespace SalesCatalog.Model +{ + public class ProductCategory + { + public ProductCategory () + { + } + public string Name { get; set; } + public string Reference { get; set; } + public Product[] Products { get; set; } + public Product GetProductByName (string productName) + { + return Array.Find (Products, p => p.Name == productName); + } + public Product GetProduct (string reference) + { + return Array.Find (Products, p => p.Reference == reference); + } + } +} + diff --git a/SalesCatalog/Model/ProductImage.cs b/SalesCatalog/Model/ProductImage.cs new file mode 100644 index 00000000..83bc5822 --- /dev/null +++ b/SalesCatalog/Model/ProductImage.cs @@ -0,0 +1,23 @@ +using System; + +namespace SalesCatalog.Model +{ + public class ProductImage: FormElement + { + #region implemented abstract members of FormElement + + public override string ToHtml () + { + return string.Format ("\"\"/", Src, Alt); + } + + #endregion + + public ProductImage () + { + } + public string Src { get; set; } + public string Alt { get; set; } + } +} + diff --git a/SalesCatalog/Model/RadioButton.cs b/SalesCatalog/Model/RadioButton.cs new file mode 100644 index 00000000..2cb3917d --- /dev/null +++ b/SalesCatalog/Model/RadioButton.cs @@ -0,0 +1,17 @@ +using System; + +namespace SalesCatalog.Model +{ + public class RadioButton:FormInput + { + public RadioButton () + { + } + public string Choice { get; set; } + public override string ToHtml () + { + return string.Format ("", Id,Name,Choice); + } + } +} + diff --git a/SalesCatalog/Model/SaleForm.cs b/SalesCatalog/Model/SaleForm.cs new file mode 100644 index 00000000..436b1032 --- /dev/null +++ b/SalesCatalog/Model/SaleForm.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace SalesCatalog.Model +{ + public class SaleForm + { + public SaleForm () + { + } + + public string Action { + get; + set; + } + + public FormElement[] Items { get; set; } + } +} + diff --git a/SalesCatalog/Model/Scalar.cs b/SalesCatalog/Model/Scalar.cs new file mode 100644 index 00000000..705d7111 --- /dev/null +++ b/SalesCatalog/Model/Scalar.cs @@ -0,0 +1,14 @@ +using System; + +namespace SalesCatalog.Model +{ + public abstract class Scalar + { + public Scalar () + { + } + public abstract object Quantity { get; set; } + public abstract Unit Unit{ get; set; } + } +} + diff --git a/SalesCatalog/Model/SelectInput.cs b/SalesCatalog/Model/SelectInput.cs new file mode 100644 index 00000000..3b364172 --- /dev/null +++ b/SalesCatalog/Model/SelectInput.cs @@ -0,0 +1,20 @@ +using System; +using System.Text; +using System.Web.Mvc; + +namespace SalesCatalog.Model +{ + public class SelectInput: FormInput + { + public Option[] Items; + public int SelectedIndex; + public override string ToHtml () + { + StringBuilder sb = new StringBuilder (); + foreach (Option opt in Items) + sb.Append (opt.ToHtml()); + return string.Format ("\n", Id,Name,sb.ToString()); + } + } +} + diff --git a/SalesCatalog/Model/SelectItem.cs b/SalesCatalog/Model/SelectItem.cs new file mode 100644 index 00000000..9ac5cafc --- /dev/null +++ b/SalesCatalog/Model/SelectItem.cs @@ -0,0 +1,23 @@ +using System; + +namespace SalesCatalog.Model +{ + public class SelectItem + { + public SelectItem(string t) + { + Value = t; + } + public string Value { get; set; } + public static implicit operator string(SelectItem t) + { + return t.Value; + } + public static implicit operator SelectItem(string t) + { + return new SelectItem(t); + } + + } +} + diff --git a/SalesCatalog/Model/Service.cs b/SalesCatalog/Model/Service.cs new file mode 100644 index 00000000..9c153125 --- /dev/null +++ b/SalesCatalog/Model/Service.cs @@ -0,0 +1,28 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Service : Product + { + public Service () + { + } + + public Price HourPrice { get; set; } + + #region implemented abstract members of SalesCatalog.Model.Product + public override string [] GetSalesConditions () + { + return new string [] { string.Format( + "Prix horaire de la prestation : {0} {1}", + HourPrice.Quantity.ToString(), + HourPrice.Unit.Name) } ; + } + #endregion + public override string ToString () + { + return string.Format ("[Service: HourPrice={0}]", HourPrice); + } + } +} + diff --git a/SalesCatalog/Model/StockStatus.cs b/SalesCatalog/Model/StockStatus.cs new file mode 100644 index 00000000..b4129b4e --- /dev/null +++ b/SalesCatalog/Model/StockStatus.cs @@ -0,0 +1,11 @@ +using System; + +namespace SalesCatalog.Model +{ + public enum StockStatus + { + NoStock, + InStock + } +} + diff --git a/SalesCatalog/Model/Text.cs b/SalesCatalog/Model/Text.cs new file mode 100644 index 00000000..ab223c01 --- /dev/null +++ b/SalesCatalog/Model/Text.cs @@ -0,0 +1,18 @@ +using System; + +namespace SalesCatalog.Model +{ + public class Text: FormElement + { + public string Val { + get; + set; + } + + public override string ToHtml () + { + return Val; + } + } +} + diff --git a/SalesCatalog/Model/TextInput.cs b/SalesCatalog/Model/TextInput.cs new file mode 100644 index 00000000..f3890b78 --- /dev/null +++ b/SalesCatalog/Model/TextInput.cs @@ -0,0 +1,46 @@ +using System; + +namespace SalesCatalog.Model +{ + public class TextInput:FormInput + { + public TextInput () + { + } + public TextInput (string txt) + { + text = txt; + } + string text = null; + + + public static implicit operator string(TextInput t) + { + return t.text; + } + public static implicit operator TextInput(string t) + { + return new TextInput(t); + } + public string DefaultValue { + get { + return text; + } + set { + text = (string) value; + } + } + + private bool multiline = false; + public bool MultiLine { get { return multiline; } set { multiline = value; } } + + public override string ToHtml () + { + + return MultiLine? + string.Format ("", Id,Name,DefaultValue) + : string.Format ("", Id,Name,DefaultValue); + } + } +} + diff --git a/SalesCatalog/Model/Unit.cs b/SalesCatalog/Model/Unit.cs new file mode 100644 index 00000000..8b64aea6 --- /dev/null +++ b/SalesCatalog/Model/Unit.cs @@ -0,0 +1,13 @@ +using System; + +namespace SalesCatalog.Model +{ + public abstract class Unit + { + public abstract string Name { get; } + public abstract string Description { get; } + public abstract object ConvertTo (Unit dest, object value); + public abstract bool MayConvertTo (Unit other); + } +} + diff --git a/SalesCatalog/SalesCatalog.csproj b/SalesCatalog/SalesCatalog.csproj new file mode 100644 index 00000000..9e10e684 --- /dev/null +++ b/SalesCatalog/SalesCatalog.csproj @@ -0,0 +1,102 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {90BF2234-7252-4CD5-B2A4-17501B19279B} + Library + SalesCatalog + SalesCatalog + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + none + true + bin\Release + prompt + 4 + false + + + + + + False + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SalesCatalog/Tests/TestBrands.cs b/SalesCatalog/Tests/TestBrands.cs new file mode 100644 index 00000000..ca6b6cc6 --- /dev/null +++ b/SalesCatalog/Tests/TestBrands.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using System; +using SalesCatalog.Model; + +namespace SalesCatalog.Tests +{ + [TestFixture ()] + public class TestBrands + { + [Test ()] + public void TestCaseAddRemoveBrand () + { + Catalog c = new Catalog (); + c.Brands = new Brand[0]; + Brand b=c.AddBrand ("coko"); + if (c.Brands.Length != 1) + throw new Exception ("Pas ajouté"); + if (b == null) + throw new Exception ("Renvoyé null"); + if (b.Name != "coko") + throw new Exception ("Pas le bon nom"); + if (c.Brands [0] != b) + throw new Exception ("err index 0"); + if (c.GetBrand ("coko") != b) + throw new Exception ("err get by name"); + if (!c.RemoveBrand ("coko")) + throw new Exception ("Pas supprimé"); + } + } +} + diff --git a/SalesCatalog/Tests/TestCatalogInit.cs b/SalesCatalog/Tests/TestCatalogInit.cs new file mode 100644 index 00000000..1dbeda61 --- /dev/null +++ b/SalesCatalog/Tests/TestCatalogInit.cs @@ -0,0 +1,106 @@ +using System; +using NUnit.Framework; +using SalesCatalog.XmlImplementation; +using SalesCatalog.Model; +using System.Xml.Serialization; +using System.IO; +using System.Xml; +using System.Text; + +namespace SalesCatalog.Tests +{ + [TestFixture()] + public class TestCatalogInit + { + [Test()] + public void TestSerDeserCat () + { + Catalog cat = new XmlCatalog (); + Brand b = new Brand (); + b.Logo = new ProductImage (); + b.Logo.Src = "/images/dev.png"; + b.Logo.Alt = "Dev"; + b.Name = "Developpement à la carte"; + b.Slogan = "Votre logiciel, efficace, sûr, et sur mesure"; + ProductCategory si = new ProductCategory (); + si.Name = "Systèmes d'information et sites Web"; + ProductCategory progiciel = new ProductCategory (); + progiciel.Name = "Progiciels"; + b.Categories = new ProductCategory[]{ si, progiciel }; + Service simaint = new Service (); + simaint.Name = "Maintenance logicielle"; + simaint.Description = "Correction des bugs, évolution"; + Service sidev = new Service (); + sidev.Name = "Développement logiciel"; + sidev.Description = "Votre intranet, votre site Web, sur mesure, " + + "développé en cycles courts, et en étroite collaboration avec vous"; + Service aubb = new Service (); + aubb.Name = "Audit de sécurité en black box"; + aubb.Description = "Je recherche les failles de sécurité de votre SI ou site Web, depuis l'exterieur de " + + "votre système, sans avoir eu connaissance d'aucun élément sur l'architécture de votre " + + "système"; + Service auwb = new Service (); + auwb.Name = "Audit de sécurité en white box"; + auwb.Description = "Je me déplace chez vous, pour travailler à partir de votre code source, " + + "et isoler ses failles de sécurités"; + si.Products = new Product[] { simaint, sidev, aubb, auwb }; + Service maint = new Service (); + maint.Name = "Maintenance logicielle"; + maint.Description = "Correction des bugs, évolution"; + Service dev = new Service (); + dev.Name = "Développement logiciel"; + dev.Description = "Votre progiciel, sur mesure, " + + "développé en cycles courts, et en étroite collaboration avec vous"; + progiciel.Products = new Product[] { maint, dev }; + SaleForm f = new SaleForm (); + f.Action = "/testAction"; + TextInput ticat = new TextInput ("Choose a Title"); + ticat.Id = "title" ; + ticat.MultiLine = true; + SelectInput selSize = new SelectInput (); + selSize.Id="size"; + Option o1 = new Option (); + o1.Value = "1m"; o1.Text = "1 mois"; + Option o2 = new Option (); + o2.Value = "2m"; o2.Text = "2 mois"; + Option o3 = new Option (); + o3.Value = "6m"; o3.Text = "6 mois"; + selSize.Items = new Option [] { o1, o2, o3 }; + var txt1 = new SalesCatalog.Model.Text (); + var txt2 = new SalesCatalog.Model.Text (); + txt1.Val="Choose a title : "; + txt2.Val = "[br]Choose the size : "; + f.Items = new FormElement[] {txt1,ticat,txt2,selSize}; + b.DefaultForm = f; + cat.Brands = new Brand[] { b }; + b.Categories = new ProductCategory[] { si, progiciel }; + XmlSerializer ser = + new XmlSerializer + (typeof(XmlCatalog), + new Type[]{typeof(Service), + typeof(PhysicalProduct), + typeof(Euro), + typeof(TextInput), + typeof(SalesCatalog.Model.Text), + typeof(TextInput), + typeof(SelectInput) + }); + FileInfo fi = new FileInfo ("Catalog.xml"); + if (fi.Exists) + fi.Delete (); + using (FileStream ws = fi.OpenWrite()) { + ser.Serialize (ws, cat); + } + using (FileStream rs = fi.OpenRead()) { + using (XmlTextReader rdr = new XmlTextReader(rs)) { + XmlCatalog copy = (XmlCatalog)ser.Deserialize (rdr); + if (copy.Brands == null) throw new Exception("Null brand array!"); + if (copy.Brands.Length != cat.Brands.Length) throw new Exception("Not the same count of brands"); + if (copy.Brands[0].DefaultForm.Action != cat.Brands[0].DefaultForm.Action) throw new Exception("not the same default form"); + // ... + } + } + } + } +} + diff --git a/SalesCatalog/XmlImplementation/XmlCatalog.cs b/SalesCatalog/XmlImplementation/XmlCatalog.cs new file mode 100644 index 00000000..31b2a2ba --- /dev/null +++ b/SalesCatalog/XmlImplementation/XmlCatalog.cs @@ -0,0 +1,15 @@ +using System; +using SalesCatalog.Model; +using System.Xml.Serialization; + +namespace SalesCatalog.XmlImplementation +{ + [XmlRoot] + public class XmlCatalog : Catalog + { + public XmlCatalog () + { + } + } +} + diff --git a/SalesCatalog/XmlImplementation/XmlCatalogProvider.cs b/SalesCatalog/XmlImplementation/XmlCatalogProvider.cs new file mode 100644 index 00000000..bd410b76 --- /dev/null +++ b/SalesCatalog/XmlImplementation/XmlCatalogProvider.cs @@ -0,0 +1,55 @@ +using System; +using System.Xml.Serialization; +using SalesCatalog.Model; +using System.Configuration; +using System.IO; +using System.Xml; + +namespace SalesCatalog.XmlImplementation +{ + public class XmlCatalogProvider: CatalogProvider + { + #region implemented abstract members of SalesCatalog.CatalogProvider + + public override Catalog GetCatalog () + { + // Assert fileName != null + FileInfo fi = new FileInfo (fileName); + if (fi.LastWriteTime > lastModification) + LoadCatalog (); + return catInstance; + } + + protected XmlCatalog catInstance = null; + protected DateTime lastModification; + protected string fileName = null; + #endregion + + public override void Initialize (string name, System.Collections.Specialized.NameValueCollection config) + { + fileName = config ["connection"]; + LoadCatalog (); + } + private void LoadCatalog () + { + FileInfo fi = new FileInfo (fileName); + if (!fi.Exists) + throw new Exception ( + string.Format ("Le fichier Xml decrivant le catalogue n'existe pas ({0})", fi.FullName)); + XmlSerializer xsr = new XmlSerializer (typeof(XmlCatalog),new Type[]{ + typeof(Service), + typeof(PhysicalProduct), + typeof(Euro), + typeof(Text), + typeof(TextInput), + typeof(SelectInput)}); + + using (FileStream fs = fi.OpenRead()) { + catInstance = (XmlCatalog) xsr.Deserialize (fs); + } + fileName = fi.FullName; + lastModification = fi.LastWriteTime; + } + } +} + diff --git a/SalesCatalog/catalog.xsd b/SalesCatalog/catalog.xsd new file mode 100644 index 00000000..7c9e5f73 --- /dev/null +++ b/SalesCatalog/catalog.xsd @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WebControls/Properties/AssemblyInfo.cs b/WebControls/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..ee64d87a --- /dev/null +++ b/WebControls/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Web.UI; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("WebControls")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Paul Schneider")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] +[assembly: TagPrefix("Yavsc.WebControls", "yavsc")] diff --git a/WebControls/ResultPages.cs b/WebControls/ResultPages.cs new file mode 100644 index 00000000..c1a9c8b2 --- /dev/null +++ b/WebControls/ResultPages.cs @@ -0,0 +1,116 @@ +using System; +using System.Web; +using System.Security.Permissions; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.ComponentModel; + +namespace Yavsc.WebControls +{ + [ + AspNetHostingPermission (SecurityAction.Demand, + Level = AspNetHostingPermissionLevel.Minimal), + AspNetHostingPermission (SecurityAction.InheritanceDemand, + Level = AspNetHostingPermissionLevel.Minimal), + ParseChildren (true, "Action"), + DefaultProperty ("Action"), + ToolboxData ("<{0}:ResultPages runat=\"server\"> ") + ] + public class ResultPages: WebControl + { + public ResultPages () + { + } + + + [Bindable (true)] + [DefaultValue(10)] + public int ResultsPerPage { + get { + return (int)( ViewState["ResultsPerPage"]==null?10:ViewState["ResultsPerPage"]); + } + set { + ViewState["ResultsPerPage"]=value; + } + } + + + [Bindable (true)] + [DefaultValue(0)] + public int ResultCount { + get { + + return (int)( ViewState["ResultCount"]==null?0:ViewState["ResultCount"]); + } + set { + ViewState["ResultCount"] = value; + } + } + + [Bindable (true)] + [DefaultValue("Pages:")] + [Localizable(true)] + public string Text { + get { + + string s = (string)ViewState["Text"]; + return (s == null) ? "Pages:" : s; + } + set { + ViewState["Text"] = value; + } + } + + [Bindable (true)] + [DefaultValue("")] + public string Action { + get { + + string s = (string)ViewState["Action"]; + return (s == null) ? String.Empty : s; + } + set { + ViewState["Action"] = value; + } + } + + + [Bindable (true)] + [DefaultValue(0)] + public int CurrentPage { + get { + int i = (int)(ViewState["CurrentPage"]==null?0:ViewState["CurrentPage"]); + return i; + } + set { + ViewState["CurrentPage"] = value; + } + } + + protected override void RenderContents (HtmlTextWriter writer) + { + if (ResultCount > 0) { + writer.WriteEncodedText (Text); + int pageCount = ((ResultCount-1) / ResultsPerPage) + 1; + for (int pi = (CurrentPage < 5) ? 0 : CurrentPage - 5; pi < pageCount && pi < CurrentPage + 5; pi++) { + if (CurrentPage == pi) + writer.RenderBeginTag ("b"); + else { + writer.AddAttribute (HtmlTextWriterAttribute.Href, + string.Format (Action, pi)); + writer.RenderBeginTag ("a"); + + } + writer.Write (pi); + writer.RenderEndTag (); + writer.Write (" "); + } + writer.Write ("("+ResultCount.ToString()+" resultat(s))"); + } else { + writer.Write ("(Pas de resultat)"); + } + } + } +} + + diff --git a/WebControls/WebControls.csproj b/WebControls/WebControls.csproj new file mode 100644 index 00000000..f81a2a3a --- /dev/null +++ b/WebControls/WebControls.csproj @@ -0,0 +1,49 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356} + Library + WebControls + Yavsc.WebControls + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + False + + + False + + + + + + + + + + + + \ No newline at end of file diff --git a/WorkFlowProvider/NpgsqlContentProvider.cs b/WorkFlowProvider/NpgsqlContentProvider.cs new file mode 100644 index 00000000..ffcbb35b --- /dev/null +++ b/WorkFlowProvider/NpgsqlContentProvider.cs @@ -0,0 +1,148 @@ +using System; +using Npgsql; +using NpgsqlTypes; +using System.Configuration; +using System.Collections.Specialized; +using yavscModel.WorkFlow; + +namespace WorkFlowProvider +{ + public class NpgsqlContentProvider: IContentProvider + { + public string Order (IWFCommand c) + { + throw new NotImplementedException (); + } + + public IContent Get (string orderId) + { + throw new NotImplementedException (); + } + + public void AddDevRessource (int prjId, string userName) + { + throw new NotImplementedException (); + } + + public void AddPrjRessource(int prjId, string owner) + { + } + + public void NewRelease (int projectId, string Version) + { + throw new NotImplementedException (); + } + + string applicationName=null; + string cnxstr = null; + + public NpgsqlContentProvider () + { + Initialize("NpgsqlYavscContentProvider",ConfigurationManager.AppSettings); + } + + public void Initialize (string name, NameValueCollection config) + { + cnxstr = ConfigurationManager.ConnectionStrings [config ["connectionStringName"]].ConnectionString; + applicationName = config["applicationName"] ?? "/"; + } + + NpgsqlConnection CreateConnection () + { + return new NpgsqlConnection (cnxstr); + } + + #region IDisposable implementation + public void Dispose () + { + + } + #endregion + + #region IContentProvider implementation + + public int NewTask (int projectId, string name, string desc) + { + throw new System.NotImplementedException (); + } + + public void SetProjectName (int projectId, string name) + { + throw new System.NotImplementedException (); + } + + public void SetProjectDesc (int projectId, string desc) + { + throw new System.NotImplementedException (); + } + + public void SetTaskName (int taskId, string name) + { + throw new System.NotImplementedException (); + } + + public void SetStartDate (int taskId, DateTime d) + { + throw new System.NotImplementedException (); + } + + public void SetEndDate (int taskId, DateTime d) + { + throw new System.NotImplementedException (); + } + + public void SetTaskDesc (int taskId, string desc) + { + throw new System.NotImplementedException (); + } + + public void RemoveProject (int prjId) + { + using (var cnx = CreateConnection()) { + cnx.Open (); + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "delete from projets where id = @id"; + cmd.Parameters.Add ("@id", prjId); + cmd.ExecuteNonQuery(); + } + cnx.Close (); + } + } + + public void RemoveTask (int taskId) + { + throw new System.NotImplementedException (); + } + + public void SetManager (int projectId, string user) + { + throw new System.NotImplementedException (); + } + + public void RemoveUser (string user) + { + throw new System.NotImplementedException (); + } + + public int NewProject (string name, string desc, string ownerId) + { + int id = 0; + using (var cnx = CreateConnection()) { + cnx.Open (); + using (NpgsqlCommand cmd = cnx.CreateCommand()) { + cmd.CommandText = "insert into projets (name,managerid,ApplicatonName,prdesc) values (@name,@mid,@appname,@pdesc)"; + cmd.Parameters.Add ("@name", name); + cmd.Parameters.Add ("@mid", ownerId); + cmd.Parameters.Add ("@appname", applicationName); + cmd.Parameters.Add ("@desc", desc); + id = (int)cmd.ExecuteScalar (); + } + cnx.Close (); + } + return id; + } + #endregion + + } +} + diff --git a/WorkFlowProvider/Properties/AssemblyInfo.cs b/WorkFlowProvider/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..6344211b --- /dev/null +++ b/WorkFlowProvider/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("WorkFlowProvider")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Paul Schneider")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/WorkFlowProvider/WFManager.cs b/WorkFlowProvider/WFManager.cs new file mode 100644 index 00000000..c9ccf4fb --- /dev/null +++ b/WorkFlowProvider/WFManager.cs @@ -0,0 +1,18 @@ +using System; +using yavscModel.WorkFlow; + +namespace WorkFlowProvider +{ + public static class WFManager + { + public static IContentProvider GetContentProviderFWC () + { + string clsName = System.Configuration.ConfigurationManager.AppSettings ["WorkflowContentProviderClass"]; + if (clsName == null) + throw new Exception ("No content provider specified in the configuration file (Application parameter \"WorkflowContentProviderClass\")"); + System.Reflection.ConstructorInfo ci = Type.GetType (clsName).GetConstructor (System.Type.EmptyTypes); + return (IContentProvider) ci.Invoke (System.Type.EmptyTypes); + } + } +} + diff --git a/WorkFlowProvider/WorkFlowProvider.csproj b/WorkFlowProvider/WorkFlowProvider.csproj new file mode 100644 index 00000000..f4713164 --- /dev/null +++ b/WorkFlowProvider/WorkFlowProvider.csproj @@ -0,0 +1,49 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {821FF72D-9F4B-4A2C-B95C-7B965291F119} + Library + WorkFlowProvider + WorkFlowProvider + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + {68F5B80A-616E-4C3C-91A0-828AA40000BD} + yavscModel + + + \ No newline at end of file diff --git a/Yavsc.sln b/Yavsc.sln new file mode 100644 index 00000000..2aa90b95 --- /dev/null +++ b/Yavsc.sln @@ -0,0 +1,74 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "web\Web.csproj", "{77044C92-D2F1-45BD-80DD-AA25B311B027}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NpgsqlMRPProviders", "NpgsqlMRPProviders\NpgsqlMRPProviders.csproj", "{BBA7175D-7F92-4278-96FC-84C495A2B5A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NpgsqlBlogProvider", "NpgsqlBlogProvider\NpgsqlBlogProvider.csproj", "{C6E9E91B-97D3-48D9-8AA7-05356929E162}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SalesCatalog", "SalesCatalog\SalesCatalog.csproj", "{90BF2234-7252-4CD5-B2A4-17501B19279B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "yavscModel", "yavscModel\yavscModel.csproj", "{68F5B80A-616E-4C3C-91A0-828AA40000BD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowProvider", "WorkFlowProvider\WorkFlowProvider.csproj", "{821FF72D-9F4B-4A2C-B95C-7B965291F119}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YavscClient", "yavscclient\YavscClient.csproj", "{EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebControls", "WebControls\WebControls.csproj", "{59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vscadm", "vscadm\vscadm.csproj", "{6C5E1490-E141-4ADA-84E5-6D65523D6B73}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ITContent", "ITContent\ITContent.csproj", "{88D83FC9-4158-4435-98A6-1F8F7F448B8F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356}.Release|Any CPU.Build.0 = Release|Any CPU + {68F5B80A-616E-4C3C-91A0-828AA40000BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68F5B80A-616E-4C3C-91A0-828AA40000BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68F5B80A-616E-4C3C-91A0-828AA40000BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68F5B80A-616E-4C3C-91A0-828AA40000BD}.Release|Any CPU.Build.0 = Release|Any CPU + {6C5E1490-E141-4ADA-84E5-6D65523D6B73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6C5E1490-E141-4ADA-84E5-6D65523D6B73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6C5E1490-E141-4ADA-84E5-6D65523D6B73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6C5E1490-E141-4ADA-84E5-6D65523D6B73}.Release|Any CPU.Build.0 = Release|Any CPU + {77044C92-D2F1-45BD-80DD-AA25B311B027}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77044C92-D2F1-45BD-80DD-AA25B311B027}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77044C92-D2F1-45BD-80DD-AA25B311B027}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77044C92-D2F1-45BD-80DD-AA25B311B027}.Release|Any CPU.Build.0 = Release|Any CPU + {821FF72D-9F4B-4A2C-B95C-7B965291F119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {821FF72D-9F4B-4A2C-B95C-7B965291F119}.Debug|Any CPU.Build.0 = Debug|Any CPU + {821FF72D-9F4B-4A2C-B95C-7B965291F119}.Release|Any CPU.ActiveCfg = Release|Any CPU + {821FF72D-9F4B-4A2C-B95C-7B965291F119}.Release|Any CPU.Build.0 = Release|Any CPU + {88D83FC9-4158-4435-98A6-1F8F7F448B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88D83FC9-4158-4435-98A6-1F8F7F448B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88D83FC9-4158-4435-98A6-1F8F7F448B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88D83FC9-4158-4435-98A6-1F8F7F448B8F}.Release|Any CPU.Build.0 = Release|Any CPU + {90BF2234-7252-4CD5-B2A4-17501B19279B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90BF2234-7252-4CD5-B2A4-17501B19279B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90BF2234-7252-4CD5-B2A4-17501B19279B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90BF2234-7252-4CD5-B2A4-17501B19279B}.Release|Any CPU.Build.0 = Release|Any CPU + {BBA7175D-7F92-4278-96FC-84C495A2B5A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BBA7175D-7F92-4278-96FC-84C495A2B5A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BBA7175D-7F92-4278-96FC-84C495A2B5A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BBA7175D-7F92-4278-96FC-84C495A2B5A6}.Release|Any CPU.Build.0 = Release|Any CPU + {C6E9E91B-97D3-48D9-8AA7-05356929E162}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6E9E91B-97D3-48D9-8AA7-05356929E162}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6E9E91B-97D3-48D9-8AA7-05356929E162}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6E9E91B-97D3-48D9-8AA7-05356929E162}.Release|Any CPU.Build.0 = Release|Any CPU + {EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = web\Web.csproj + EndGlobalSection +EndGlobal diff --git a/mkReleaseSourceCode.sh b/mkReleaseSourceCode.sh new file mode 100644 index 00000000..ae13d4bf --- /dev/null +++ b/mkReleaseSourceCode.sh @@ -0,0 +1 @@ +git archive --format=tar --prefix=yavsc-1.1/ 1.1 | bzip2 > yavsc-1.1.tar.bz2 diff --git a/noavatar.xcf b/noavatar.xcf new file mode 100644 index 00000000..e182ad80 Binary files /dev/null and b/noavatar.xcf differ diff --git a/vscadm/Program.cs b/vscadm/Program.cs new file mode 100644 index 00000000..f6f417a9 --- /dev/null +++ b/vscadm/Program.cs @@ -0,0 +1,15 @@ +using System; +using System.IO; +using System.Threading; + +namespace vscadm +{ + class MainClass + { + public static void Main (string[] args) + { + Console.WriteLine ("Hello World!"); + + } + } +} diff --git a/vscadm/Properties/AssemblyInfo.cs b/vscadm/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..e9090dae --- /dev/null +++ b/vscadm/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("vscadm")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Paul Schneider")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/vscadm/vscadm.csproj b/vscadm/vscadm.csproj new file mode 100644 index 00000000..ffbd3755 --- /dev/null +++ b/vscadm/vscadm.csproj @@ -0,0 +1,42 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {6C5E1490-E141-4ADA-84E5-6D65523D6B73} + Exe + vscadm + vscadm + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/Admin/DataManager.cs b/web/Admin/DataManager.cs new file mode 100644 index 00000000..cc24a375 --- /dev/null +++ b/web/Admin/DataManager.cs @@ -0,0 +1,81 @@ +using System; +using System.Diagnostics; +using System.IO; +using yavscModel.Admin; +using Npgsql.Web.Blog; + +namespace Yavsc.Admin +{ + public class DataManager + { + DataAccess da; + public DataManager (DataAccess datac) + { + da = datac; + } + + public Export CreateBackup () + { + Environment.SetEnvironmentVariable("PGPASSWORD", da.Password); + Export e = new Export (); + string fileName = da.BackupPrefix + "-" + DateTime.Now.ToString ("yyyyMMdd"); + FileInfo ofi = new FileInfo (fileName); + e.FileName = ofi.FullName; + Exec ("pg_dump", string.Format ( + "-wb -Z3 -f {0} -Fd -h {1} -U {2} -p {3} {4}", + fileName, da.Host, da.Dbuser, da.Port, da.Dbname ),e); + return e; + } + + private void Exec(string name, string args, TaskOutput output) + { + ProcessStartInfo Pinfo = + new ProcessStartInfo (name,args); + Pinfo.RedirectStandardError = true; + Pinfo.RedirectStandardOutput = true; + Pinfo.CreateNoWindow = true; + Pinfo.UseShellExecute = false; + using (Process p = new Process ()) { + p.EnableRaisingEvents = true; + p.StartInfo = Pinfo; + p.Start (); + p.WaitForExit (); + output.Error = p.StandardError.ReadToEnd (); + output.Message = p.StandardOutput.ReadToEnd (); + output.ExitCode = p.ExitCode; + p.Close (); + } + } + public TaskOutput Restore (string fileName, bool dataOnly) + { + Environment.SetEnvironmentVariable("PGPASSWORD", da.Password); + var t = new TaskOutput (); + Exec ("pg_restore", (dataOnly?"-a ":"")+string.Format ( + "-1 -w -Fd -O -h {0} -U {1} -p {2} -d {3} {4}", + da.Host, da.Dbuser, da.Port, da.Dbname, fileName ),t); + return t; + } + public TaskOutput CreateDb () + { + return Restore ("freshinstall", false); + } + public Export TagBackup (string filename, string [] tags) + { + /* FileInfo fi = new FileInfo (filename); + using (FileStream s = fi.OpenWrite ()) { + + } */ + throw new NotImplementedException (); + } + public TaskOutput TagRestore (string fileName) + { + Environment.SetEnvironmentVariable ("PGPASSWORD", da.Password); + var t = new TaskOutput (); + Exec ("pg_restore", string.Format ( + "-a -w -Fd -O -h {0} -U {1} -p {2} -d {3} {4}", + da.Host, da.Dbuser, da.Port, da.Dbname, fileName ),t); + return t; + } + } +} + diff --git a/web/Admin/Export.cs b/web/Admin/Export.cs new file mode 100644 index 00000000..046512f7 --- /dev/null +++ b/web/Admin/Export.cs @@ -0,0 +1,14 @@ +using System; +using System.ComponentModel; + +namespace Yavsc.Admin +{ + public class Export: TaskOutput + { + public Export () + { + } + public string FileName { get; set; } + } +} + diff --git a/web/Admin/TaskOutput.cs b/web/Admin/TaskOutput.cs new file mode 100644 index 00000000..b84225ab --- /dev/null +++ b/web/Admin/TaskOutput.cs @@ -0,0 +1,12 @@ +using System; +using System.ComponentModel; + +namespace Yavsc.Admin +{ + public class TaskOutput { + public string Message { get; set; } + public string Error { get; set; } + public int ExitCode { get; set; } + } + +} diff --git a/web/AssemblyInfo.cs b/web/AssemblyInfo.cs new file mode 100644 index 00000000..08760d78 --- /dev/null +++ b/web/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("Yavsc")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("paul schneider")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.2.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/web/Basket/Basket.cs b/web/Basket/Basket.cs new file mode 100644 index 00000000..bcfb9ec3 --- /dev/null +++ b/web/Basket/Basket.cs @@ -0,0 +1,17 @@ +using System; +using SalesCatalog.Model; +using System.Collections.Generic; + +namespace Yavsc.Basket +{ + public class Basket + { + public Basket () + { + } + + public void Add(Product p) + { + } + } +} diff --git a/web/CatExts/WebCatalogExtensions.cs b/web/CatExts/WebCatalogExtensions.cs new file mode 100644 index 00000000..01e07b9f --- /dev/null +++ b/web/CatExts/WebCatalogExtensions.cs @@ -0,0 +1,80 @@ +using System; +using System.Web; +using SalesCatalog; +using SalesCatalog.Model; +using System.Text; +using System.Web.Mvc; +using System.Web.Routing; +using System.Web.Mvc.Html; + +namespace Yavsc.CatExts +{ + public static class WebCatalogExtensions + { + public static string CommandForm(this HtmlHelper helper, Product pos,string atc="Add to backet") { + StringBuilder sb = new StringBuilder (); + sb.Append (helper.ValidationSummary ()); + TagBuilder ft = new TagBuilder ("form"); + ft.Attributes.Add("action","/FrontOffice/Command"); + ft.Attributes.Add("method","post"); + ft.Attributes.Add("enctype","multipart/form-data"); + TagBuilder fieldset = new TagBuilder ("fieldset"); + + TagBuilder legend = new TagBuilder ("legend"); + legend.SetInnerText (pos.Name); + TagBuilder para = new TagBuilder ("p"); + + StringBuilder sbfc = new StringBuilder (); + if (pos.CommandForm != null) + foreach (FormElement e in pos.CommandForm.Items) { + sbfc.Append (e.ToHtml ()); + sbfc.Append ("
\n"); + } + sbfc.Append ( + string.Format( + "
\n", + atc + )); + + sbfc.Append (helper.Hidden ("ref", pos.Reference)); + para.InnerHtml = sbfc.ToString (); + fieldset.InnerHtml = legend.ToString ()+"\n"+para.ToString (); + ft.InnerHtml = fieldset.ToString (); + sb.Append (ft.ToString ()); + return sb.ToString (); + } + public static string CommandForm(this HtmlHelper helper, Product pos,string atc="Add to backet") { + StringBuilder sb = new StringBuilder (); + sb.Append (helper.ValidationSummary ()); + TagBuilder ft = new TagBuilder ("form"); + ft.Attributes.Add("action","/FrontOffice/Command"); + ft.Attributes.Add("method","post"); + ft.Attributes.Add("enctype","multipart/form-data"); + TagBuilder fieldset = new TagBuilder ("fieldset"); + + TagBuilder legend = new TagBuilder ("legend"); + legend.SetInnerText (pos.Name); + TagBuilder para = new TagBuilder ("p"); + + StringBuilder sbfc = new StringBuilder (); + if (pos.CommandForm != null) + foreach (FormElement e in pos.CommandForm.Items) { + sbfc.Append (e.ToHtml ()); + sbfc.Append ("
\n"); + } + sbfc.Append ( + string.Format( + "
\n",atc)); + sbfc.Append (helper.Hidden ("ref", pos.Reference)); + para.InnerHtml = sbfc.ToString (); + fieldset.InnerHtml = legend.ToString ()+"\n"+para.ToString (); + ft.InnerHtml = fieldset.ToString (); + sb.Append (ft.ToString ()); + return sb.ToString (); + } + + + + } +} + diff --git a/web/Catalog.xml b/web/Catalog.xml new file mode 100644 index 00000000..4095cd74 --- /dev/null +++ b/web/Catalog.xml @@ -0,0 +1,56 @@ + + + + + shdsi + Votre logiciel, efficace, sûr, et sur mesure + + /images/logoDev.png + + + + + Systèmes d'information et sites Web + ntic + + + Développement + Votre Extranet, Intranet, + site Web, sur mesure, élégant et efficace, au look racé, accessible, + et développé en cycles courts + nticdev + + + Maintenance + Correction des anomalies, réalisation des évolutions, prévision des besoins + nticmaint + + + + + + /Commande + + + Entrez un commentaire : + + + comment + Commentaire + + + Choisissez le type d'intervention souhaité: + + + ad + + à distance + sur site + + 0 + + + + + + diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs new file mode 100644 index 00000000..8685a59c --- /dev/null +++ b/web/Controllers/AccountController.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mail; +using System.Web; +using System.Web.Configuration; +using System.Web.Mvc; +using System.Web.Mvc.Ajax; +using System.Web.Profile; +using System.Web.Security; +using Yavsc; +using yavscModel.RolesAndMembers; +using Yavsc.Helpers; + +namespace Yavsc.Controllers +{ + public class AccountController : Controller + { + private static string registrationMessage = + WebConfigurationManager.AppSettings ["RegistrationMessage"]; + + string avatarDir = "~/avatars"; + + public string AvatarDir { + get { return avatarDir; } + set { avatarDir = value; } + } + + public ActionResult Index () + { + return View (); + } + + public ActionResult Login (string returnUrl) + { + ViewData ["returnUrl"] = returnUrl; + return View (); + } + + [Authorize] + public ActionResult Profile(Profile model) + { + ViewData ["UserName"] = Membership.GetUser ().UserName; + model.FromProfileBase(HttpContext.Profile); + return View (model); + } + // TODO [ValidateAntiForgeryToken] + public ActionResult DoLogin (LoginModel model, string returnUrl) + { + if (ModelState.IsValid) { + if (Membership.ValidateUser (model.UserName, model.Password)) { + FormsAuthentication.SetAuthCookie (model.UserName, model.RememberMe); + if (returnUrl != null) + return Redirect (returnUrl); + else return View ("Index"); + } else { + ModelState.AddModelError ("UserName", "The user name or password provided is incorrect."); + } + } + + ViewData ["returnUrl"] = returnUrl; + + // If we got this far, something failed, redisplay form + return View ("Login",model); + } + + public ActionResult Register (RegisterViewModel model, string returnUrl) + { + ViewData["returnUrl"] = returnUrl; + if (Request.RequestType == "GET") { + foreach (string k in ModelState.Keys) + ModelState [k].Errors.Clear (); + return View (model); + } + if (ModelState.IsValid) { + if (model.ConfirmPassword != model.Password) + { + ModelState.AddModelError("ConfirmPassword","Veuillez confirmer votre mot de passe"); + return View (model); + } + + MembershipCreateStatus mcs; + var user = Membership.CreateUser ( + model.UserName, + model.Password, + model.Email, + null, + null, + false, + out mcs); + switch (mcs) { + case MembershipCreateStatus.DuplicateEmail: + ModelState.AddModelError("Email", "Cette adresse e-mail correspond " + + "à un compte utilisateur existant"); + return View (model); + case MembershipCreateStatus.DuplicateUserName: + ModelState.AddModelError("UserName", "Ce nom d'utilisateur est " + + "déjà enregistré"); + return View (model); + case MembershipCreateStatus.Success: + FileInfo fi = new FileInfo ( + Server.MapPath(registrationMessage)); + if (!fi.Exists) { + ViewData["Error"] = "Erreur inattendue (pas de corps de message à envoyer)"; + return View (model); + } + using (StreamReader sr = fi.OpenText()) { + string body = sr.ReadToEnd(); + body = body.Replace("<%SiteName%>",YavscHelpers.SiteName); + body = body.Replace("<%UserName%>",user.UserName); + body = body.Replace("<%UserActivatonUrl%>", + string.Format("<{0}://{1}/Account/Validate/{2}?key={3}", + Request.Url.Scheme, + Request.Url.Authority, + user.UserName, + user.ProviderUserKey.ToString())); + using (MailMessage msg = new MailMessage( + HomeController.Admail,user.Email, + string.Format("Validation de votre compte {0}",YavscHelpers.SiteName), + body)) + { + using (SmtpClient sc = new SmtpClient()) + { + sc.Send (msg); + } + } + + ViewData ["username"] = user.UserName; + ViewData ["email"] = user.Email; + return View ("RegistrationPending"); + } + default: + ViewData["Error"] = "Une erreur inattendue s'est produite" + + "a l'enregistrement de votre compte utilisateur" + + string.Format("({0}).",mcs.ToString()) + + "Veuillez pardonner la gêne" + + "occasionnée"; + return View (model); + } + + } + return View (model); + } + + public ActionResult ChangePasswordSuccess () + { + return View (); + } + + [HttpGet] + [Authorize] + public ActionResult ChangePassword() + { + return View(); + } + + [Authorize] + [HttpPost] + public ActionResult ChangePassword (ChangePasswordModel model) + { + if (ModelState.IsValid) { + + // ChangePassword will throw an exception rather + // than return false in certain failure scenarios. + bool changePasswordSucceeded; + try { + var users = Membership.FindUsersByName (model.Username); + + if (users.Count > 0) { + MembershipUser user = Membership.GetUser (model.Username,true); + changePasswordSucceeded = user.ChangePassword (model.OldPassword, model.NewPassword); + } else { + changePasswordSucceeded = false; + } + } catch (Exception) { + changePasswordSucceeded = false; + } + + if (changePasswordSucceeded) { + return RedirectToAction ("ChangePasswordSuccess"); + } else { + ModelState.AddModelError ("Password", "The current password is incorrect or the new password is invalid."); + } + } + + // If we got this far, something failed, redisplay form + return View (model); + } + + [Authorize()] + public ActionResult UserList () + { + MembershipUserCollection c = Membership.GetAllUsers (); + return View (c); + } + + private const string adminRoleName = "Admin"; + + [Authorize()] + public ActionResult Admin (NewAdminModel model) + { + string currentUser = Membership.GetUser ().UserName; + if (ModelState.IsValid) { + Roles.AddUserToRole (model.UserName, adminRoleName); + ViewData ["Message"] = model.UserName + " was added to the role '" + adminRoleName + "'"; + } else { + if (!Roles.RoleExists (adminRoleName)) { + Roles.CreateRole (adminRoleName); + string.Format ("The role '{0}' has just been created. ", + adminRoleName); + } + string [] admins = Roles.GetUsersInRole (adminRoleName); + if (admins.Length > 0) { + if (! admins.Contains (Membership.GetUser ().UserName)) { + ModelState.Remove("UserName"); + ModelState.AddModelError("UserName", "You're not administrator!"); + return View ("Index"); + } + } else { + Roles.AddUserToRole (currentUser, adminRoleName); + admins = new string[] { currentUser }; + ViewData ["Message"] += string.Format ( + "There was no user in the 'Admin' role. You ({0}) was just added as the firt user in the 'Admin' role. ", currentUser); + } + + List users = new List (); + foreach (MembershipUser u in Membership.GetAllUsers ()) { + var i = new SelectListItem (); + i.Text = string.Format ("{0} <{1}>", u.UserName, u.Email); + i.Value = u.UserName; + users.Add (i); + } + ViewData ["useritems"] = users; + ViewData ["admins"] = admins; + } + return View (model); + } + + [Authorize()] + public ActionResult RoleList () + { + return View (Roles.GetAllRoles ()); + } + + + [Authorize(Roles="Admin")] + public ActionResult RemoveFromRole(string username, string rolename, string returnUrl) + { + Roles.RemoveUserFromRole(username,rolename); + return Redirect(returnUrl); + } + + [Authorize(Roles="Admin")] + public ActionResult RemoveUser (string username, string submitbutton) + { + if (submitbutton == "Supprimer") { + Membership.DeleteUser (username); + ViewData["Message"]= + string.Format("utilisateur \"{0}\" supprimé",username); + } + return RedirectToAction("UserList"); + } + [Authorize] + [HttpPost] + //public ActionResult UpdateProfile(HttpPostedFileBase Avatar, string Address, string CityAndState, string ZipCode, string Country, string WebSite) + public ActionResult UpdateProfile(Profile model, HttpPostedFileBase AvatarFile) + { + string username = Membership.GetUser ().UserName; + + if (AvatarFile != null) { + + if (AvatarFile.ContentType == "image/png") { + // byte[] img = new byte[AvatarFile.ContentLength]; + // AvatarFile.InputStream.Read (img, 0, AvatarFile.ContentLength); + // model.Avatar = img; + + string avdir=Server.MapPath (AvatarDir); + string avpath=Path.Combine(avdir,username+".png"); + AvatarFile.SaveAs (avpath); + } else + ModelState.AddModelError ("Avatar", + string.Format ("Image type {0} is not supported (suported formats : {1})", + AvatarFile.ContentType, "image/png") + ); + } + if (ModelState.IsValid) { + HttpContext.Profile.SetPropertyValue ( + "Address", model.Address); + HttpContext.Profile.SetPropertyValue ( + "BlogTitle", model.BlogTitle); + HttpContext.Profile.SetPropertyValue ( + "BlogVisible", model.BlogVisible); + HttpContext.Profile.SetPropertyValue ( + "CityAndState", model.CityAndState); + HttpContext.Profile.SetPropertyValue ( + "Country", model.Country); + HttpContext.Profile.SetPropertyValue ( + "WebSite", model.WebSite); + + } + // HttpContext.Profile.SetPropertyValue("Avatar",Avatar); + return RedirectToAction ("Profile"); + } + + [Authorize(Roles="Admin")] + public ActionResult RemoveRole (string rolename, string submitbutton) + { + if (submitbutton == "Supprimer") + { + Roles.DeleteRole(rolename); + } + return RedirectToAction("RoleList"); + } + + [Authorize(Roles="Admin")] + public ActionResult RemoveRoleQuery(string rolename) + { + ViewData["roletoremove"] = rolename; + return View (); + } + + [Authorize(Roles="Admin")] + public ActionResult RemoveUserQuery(string username) + { + ViewData["usertoremove"] = username; + return UserList(); + } + + [Authorize] + public ActionResult Logout (string returnUrl) + { + FormsAuthentication.SignOut(); + return Redirect(returnUrl); + } + + [Authorize(Roles="Admin")] + public ActionResult AddRole () + { + return View (); + } + + [Authorize(Roles="Admin")] + public ActionResult DoAddRole (string rolename) + { + Roles.CreateRole(rolename); + ViewData["Message"] = "Rôle créé : "+rolename; + return View (); + } + + public ActionResult Validate (string id, string key) + { + MembershipUser u = Membership.GetUser (id, false); + if (u == null) { + ViewData ["Error"] = + string.Format ("Cet utilisateur n'existe pas ({0})", id); + } + else + if (u.ProviderUserKey.ToString () == key) { + u.IsApproved = true; + Membership.UpdateUser(u); + ViewData["Message"] = + string.Format ("La création de votre compte ({0}) est validée.", id); + } + else ViewData["Error"] = "La clé utilisée pour valider ce compte est incorrecte"; + return View (); + } + } +} diff --git a/web/Controllers/BackOfficeController.cs b/web/Controllers/BackOfficeController.cs new file mode 100644 index 00000000..66c7c484 --- /dev/null +++ b/web/Controllers/BackOfficeController.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Yavsc.Admin; +using yavscModel.Admin; + + +namespace Yavsc.Controllers +{ + public class BackOfficeController : Controller + { + [Authorize(Roles="Admin")] + public ActionResult Index(DataAccess model) + { + return View (model); + } + [Authorize(Roles="Admin")] + public ActionResult Backups(DataAccess model) + { + return View (model); + } + + [Authorize(Roles="Admin")] + public ActionResult CreateBackup(DataAccess datac) + { + if (datac != null) { + if (ModelState.IsValid) { + if (string.IsNullOrEmpty (datac.Password)) + ModelState.AddModelError ("Password", "Invalid passord"); + DataManager ex = new DataManager (datac); + Export e = ex.CreateBackup (); + if (e.ExitCode > 0) + ModelState.AddModelError ("Password", "Operation Failed"); + return View ("BackupCreated", e); + } + } else { + datac = new DataAccess (); + } + return View (datac); + } + + [Authorize(Roles="Admin")] + public ActionResult CreateUserBackup(DataAccess datac,string username) + { +throw new NotImplementedException(); + } + + + [Authorize(Roles="Admin")] + public ActionResult Restore(DataAccess datac,string backupName,bool dataOnly=true) + { + ViewData ["BackupName"] = backupName; + if (ModelState.IsValid) { + DataManager mgr = new DataManager (datac); + ViewData ["BackupName"] = backupName; + ViewData ["DataOnly"] = dataOnly; + TaskOutput t = mgr.Restore (backupName,dataOnly); + return View ("Restored", t); + } + return View (datac); + } + + } +} diff --git a/web/Controllers/BasketController.cs b/web/Controllers/BasketController.cs new file mode 100644 index 00000000..410a3e70 --- /dev/null +++ b/web/Controllers/BasketController.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Security; + +namespace Yavsc.Controllers +{ + public class BasketController : Controller + { + public ActionResult Index() + { + return View (); + } + + public ActionResult Details(int id) + { + return View (); + } + + public ActionResult Create() + { + var user = Membership.GetUser (); + var username = (user != null)?user.UserName:Request.AnonymousID; + // get an existing basket + + return View (); + } + + [HttpPost] + public ActionResult Create(FormCollection collection) + { + try { + return RedirectToAction ("Index"); + } catch { + return View (); + } + } + + public ActionResult Edit(int id) + { + return View (); + } + + [HttpPost] + public ActionResult Edit(int id, FormCollection collection) + { + try { + return RedirectToAction ("Index"); + } catch { + return View (); + } + } + + public ActionResult Delete(int id) + { + return View (); + } + + [HttpPost] + public ActionResult Delete(int id, FormCollection collection) + { + try { + return RedirectToAction ("Index"); + } catch { + return View (); + } + } + } +} \ No newline at end of file diff --git a/web/Controllers/BlogsController.cs b/web/Controllers/BlogsController.cs new file mode 100644 index 00000000..9d5fc9c2 --- /dev/null +++ b/web/Controllers/BlogsController.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Net.Mime; +using System.Runtime.Serialization.Formatters.Binary; +using System.Web; +using System.Web.Configuration; +using System.Web.Mvc; +using System.Web.Mvc.Ajax; +using System.Web.Profile; +using System.Web.Security; +using CodeKicker.BBCode; +using Npgsql.Web.Blog; +using Npgsql.Web.Blog.DataModel; +using Yavsc; +using yavscModel; + +namespace Yavsc.Controllers +{ + public class BlogsController : Controller + { + string defaultAvatarMimetype; + private string sitename = + WebConfigurationManager.AppSettings ["Name"]; + string avatarDir = "~/avatars"; + + public string AvatarDir { + get { return avatarDir; } + set { avatarDir = value; } + } + + public BlogsController () + { + string[] defaultAvatarSpec = ConfigurationManager.AppSettings.Get ("DefaultAvatar").Split (';'); + if (defaultAvatarSpec.Length != 2) + throw new ConfigurationErrorsException ("the DefaultAvatar spec should be found as ; "); + defaultAvatar = defaultAvatarSpec [0]; + defaultAvatarMimetype = defaultAvatarSpec [1]; + } + + public ActionResult Index (string user = null, string title = null, int pageIndex=0, int pageSize=10) + { + if (string.IsNullOrEmpty (user)) { + ViewData ["Message"] = "Blogs"; + return BlogList (pageIndex, pageSize); + } else { + MembershipUser u = Membership.GetUser (user, false); + if (u == null) { + ModelState.AddModelError ("UserName", + string.Format ("Utilisateur inconu : {0}", user)); + return BlogList (); + } else { + if (string.IsNullOrEmpty (title)) + return UserPosts (user, pageIndex, pageSize); + return UserPost (user, title); + } + } + } + + public ActionResult BlogList (int pageIndex = 0, int pageSize = 10) + { + ViewData ["SiteName"] = sitename; + int totalRecords; + BlogEntryCollection bs = BlogManager.LastPosts (pageIndex, pageSize, out totalRecords); + ViewData ["RecordCount"] = totalRecords; + ViewData ["PageSize"] = pageSize; + ViewData ["PageIndex"] = pageIndex; + return View ("Index", bs); + } + + [HttpGet] + public ActionResult UserPosts (string user, int pageIndex = 0, int pageSize = 10) + { + int tr; + MembershipUser u = Membership.GetUser (); + FindBlogEntryFlags sf = FindBlogEntryFlags.MatchUserName; + ViewData ["SiteName"] = sitename; + ViewData ["BlogUser"] = user; + if (u != null) + if (u.UserName == user) + sf |= FindBlogEntryFlags.MatchInvisible; + BlogEntryCollection c = BlogManager.FindPost (user, sf, pageIndex, pageSize, out tr); + ViewData ["BlogTitle"] = BlogTitle (user); + ViewData ["PageIndex"] = pageIndex; + ViewData ["PageSize"] = pageSize; + ViewData ["RecordCount"] = tr; + return View ("UserPosts", c); + + } + + [Authorize] + public ActionResult RemoveComment(long cmtid) + { + long postid = BlogManager.RemoveComment (cmtid); + return UserPost (postid); + } + + private ActionResult UserPost (long id) + { + ViewData ["PostId"] = id; + + BlogEntry e = BlogManager.GetPost (id); + return UserPost (e); + } + + private ActionResult UserPost (BlogEntry e) + { + if (e == null) + return View ("TitleNotFound"); + MembershipUser u = Membership.GetUser (); + if (u != null) + ViewData ["UserName"] = u.UserName; + if (!e.Visible) { + if (u==null) + return View ("TitleNotFound"); + else if (u.UserName!=e.UserName) + return View ("TitleNotFound"); + } + ViewData ["BlogTitle"] = BlogTitle (e.UserName); + ViewData ["Comments"] = BlogManager.GetComments (e.Id); + return View ("UserPost", e); + } + + public ActionResult UserPost (string user, string title) + { + ViewData ["BlogUser"] = user; + ViewData ["PostTitle"] = title; + int postid = 0; + if (string.IsNullOrEmpty (title)) { + if (int.TryParse (user, out postid)) { + return UserPost (BlogManager.GetPost (postid)); + } + } + return UserPost (BlogManager.GetPost (user, title)); + } + + [Authorize] + public ActionResult Post (string user, string title) + { + ViewData ["SiteName"] = sitename; + string un = Membership.GetUser ().UserName; + if (String.IsNullOrEmpty (user)) + user = un; + if (un != user) + ViewData ["Message"] = string.Format ("Vous n'êtes pas {0}!", user); + ViewData ["UserName"] = un; + return View (new BlogEditEntryModel { Title = title }); + } + + [Authorize] + public ActionResult ValidatePost (BlogEditEntryModel model) + { + string username = Membership.GetUser ().UserName; + ViewData ["SiteName"] = sitename; + ViewData ["BlogUser"] = username; + if (ModelState.IsValid) { + if (!model.Preview) { + BlogManager.Post (username, model.Title, model.Content, model.Visible); + return UserPost (username, model.Title); + } + } + return View ("Post", model); + } + + [Authorize] + public ActionResult ValidateEdit (BlogEditEntryModel model) + { + ViewData ["SiteName"] = sitename; + ViewData ["BlogUser"] = Membership.GetUser ().UserName; + if (ModelState.IsValid) { + if (!model.Preview) { + BlogManager.UpdatePost (model.Id, model.Content, model.Visible); + return UserPost (model); + } + } + return View ("Edit", model); + } + + [Authorize] + public ActionResult Edit (BlogEditEntryModel model) + { + if (model != null) { + string user = Membership.GetUser ().UserName; + ViewData ["BlogTitle"] = this.BlogTitle (user); + ViewData ["UserName"] = user; + if (model.UserName == null) { + model.UserName = user; + BlogEntry e = BlogManager.GetPost (model.UserName, model.Title); + if (e == null) { + return View ("TitleNotFound"); + } else { + model = new BlogEditEntryModel (e); + ModelState.Clear (); + this.TryValidateModel (model); + } + } else if (model.UserName != user) { + return View ("TitleNotFound"); + } + } + return View (model); + } + + private string BlogTitle (string user) + { + return string.Format ("{0}'s blog", user); + } + public ActionResult Comment (BlogEditCommentModel model) { + string username = Membership.GetUser ().UserName; + ViewData ["SiteName"] = sitename; + if (ModelState.IsValid) { + if (!model.Preview) { + BlogManager.Comment(username, model.PostId, model.CommentText, model.Visible); + return UserPost (model.PostId); + } + } + return View (model); + } + + string defaultAvatar; + + [AcceptVerbs (HttpVerbs.Get)] + public ActionResult Avatar (string user) + { + string avpath = Path.Combine ( + Server.MapPath (AvatarDir), user + ".png"); + FileInfo fia = new FileInfo (avpath); + if (!fia.Exists) + fia = new FileInfo (Server.MapPath (defaultAvatar)); + return File (fia.OpenRead (), defaultAvatarMimetype); + } + + [Authorize] + public ActionResult Remove (string user, string title, string returnUrl) + { + if (!Roles.IsUserInRole ("Admin")) { + string rguser = Membership.GetUser ().UserName; + if (rguser != user) { + ModelState.AddModelError ( + "Title", string.Format ( + "Vous n'avez pas de droits sur le Blog de {0}", + user)); + return Return (returnUrl); + } + } + BlogEntry e = BlogManager.GetPost (user, title); + if (e == null) { + ModelState.AddModelError ( + "Title", + string.Format ( + "Aucun post portant le titre \"{0}\" pour l'utilisateur {1}", + title, user)); + return Return (returnUrl); + } + BlogManager.RemovePost (user, title); + return Return (returnUrl); + } + + private ActionResult Return (string returnUrl) + { + if (!string.IsNullOrEmpty (returnUrl)) + return Redirect (returnUrl); + else + return RedirectToAction ("Index"); + } + } +} + diff --git a/web/Controllers/Commande.cs b/web/Controllers/Commande.cs new file mode 100644 index 00000000..007dec84 --- /dev/null +++ b/web/Controllers/Commande.cs @@ -0,0 +1,21 @@ +using System; +using Yavsc; +using SalesCatalog; +using SalesCatalog.Model; +using System.Web.Mvc; +using System.Web; +using System.Text.RegularExpressions; +using System.IO; +using Yavsc.Controllers; + +namespace Yavsc.Controllers +{ + public class Commande + { + public Commande(FormCollection collection) + { + + } + } +} + diff --git a/web/Controllers/FileSystemController.cs b/web/Controllers/FileSystemController.cs new file mode 100644 index 00000000..6045fc94 --- /dev/null +++ b/web/Controllers/FileSystemController.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.IO; +using System.Web.Security; +using FileSystem; +using System.Text.RegularExpressions; + +namespace Yavsc.Controllers +{ + public class FileSystemController : Controller + { + private static string usersDir ="users"; + + public static string UsersDir { + get { + return usersDir; + } + } + + [Authorize] + public ActionResult Index() + { + string user = Membership.GetUser ().UserName; + ViewData ["UserName"] = user; + DirectoryInfo di = new DirectoryInfo ( + Path.Combine( + UsersDir, + user)); + if (!di.Exists) + di.Create (); + return View (new FileInfoCollection( di.GetFiles())); + } + + public ActionResult Details(string id) + { + foreach (char x in Path.GetInvalidPathChars()) { + if (id.Contains (x)) { + ViewData ["Message"] = + string.Format ( + "Something went wrong following the following path : {0} (\"{1}\")", + id,x); + return RedirectToAction ("Index"); + } + } + string fpath = Path.Combine (BaseDir, id); + ViewData["Content"] = Url.Content (fpath); + FileInfo fi = new FileInfo (fpath); + + return View (fi); + } + + public ActionResult Create() + { + return View (); + } + [HttpPost] + [Authorize] + public ActionResult Create(FormCollection collection) + { + try { + string fnre = "[A-Za-z0-9~\\-.]+"; + HttpFileCollectionBase hfc = Request.Files; + + for (int i=0; iFile name '{0}' refused

",hfc[i].FileName); + ModelState.AddModelError( + "AFile", + string.Format( + "The file name {0} dosn't match an acceptable file name {1}", + hfc[i].FileName,fnre)) + ; + return View(); + } + } + for (int i=0; iFile name '{0}' saved

",hfc[i].FileName); + } + return RedirectToAction ("Index","FileSystem"); + } catch (Exception e) { + ViewData ["Message"] = "Exception:"+e.Message; + return View (); + } + } + + + public static string BaseDir { get { return Path.Combine (UsersDir, Membership.GetUser ().UserName); } } + + public ActionResult Edit(int id) + { + return View (); + } + + [HttpPost] + public ActionResult Edit(int id, FormCollection collection) + { + try { + return RedirectToAction ("Index"); + } catch { + return View (); + } + } + + public ActionResult Delete(int id) + { + return View (); + } + + [HttpPost] + public ActionResult Delete(int id, FormCollection collection) + { + try { + return RedirectToAction ("Index"); + } catch { + return View (); + } + } + } +} \ No newline at end of file diff --git a/web/Controllers/FrontOfficeApiController.cs b/web/Controllers/FrontOfficeApiController.cs new file mode 100644 index 00000000..57ced4f3 --- /dev/null +++ b/web/Controllers/FrontOfficeApiController.cs @@ -0,0 +1,85 @@ +using System; +using Yavsc; +using SalesCatalog; +using SalesCatalog.Model; +using System.Web.Routing; +using System.Threading.Tasks; +using System.Diagnostics; +using System.Web.Http; +using System.Net.Http; +using System.Web; +using System.Linq; +using System.IO; +using System.Net; + +namespace Yavsc.ApiControllers +{ + + public class FrontOfficeController : ApiController + { + [AcceptVerbs("GET")] + public Catalog Catalog () + { + return CatalogManager.GetCatalog (); + } + + [AcceptVerbs("GET")] + public ProductCategory GetProductCategorie (string brandName, string prodCategorie) + { + return CatalogManager.GetCatalog ().GetBrand (brandName).GetProductCategory (prodCategorie) + ; + } + + [AcceptVerbs("POST")] + public string Command() + { + return null; + } + + + public HttpResponseMessage Post() + { + HttpResponseMessage result = null; + var httpRequest = HttpContext.Current.Request; + if (httpRequest.Files.Count > 0) + { + string username = HttpContext.Current.User.Identity.Name; + int nbf = 0; + foreach(string file in httpRequest.Files) + { + var postedFile = httpRequest.Files[file]; + string filePath = HttpContext.Current.Server.MapPath("~/users/"+username+"/"+ postedFile.FileName); + postedFile.SaveAs(filePath); + nbf++; + } + result = Request.CreateResponse (HttpStatusCode.Created, + string.Format("Received {0} files",nbf)); + + } + else + { + result = Request.CreateResponse (HttpStatusCode.BadRequest,"No file received"); + } + + return result; + } + + [HttpPost] + public string ProfileImagePost(HttpPostedFile profileImage) + { + string[] extensions = { ".jpg", ".jpeg", ".gif", ".bmp", ".png" }; + if (!extensions.Any(x => x.Equals(Path.GetExtension(profileImage.FileName.ToLower()), StringComparison.OrdinalIgnoreCase))) + { + throw new HttpResponseException( + new HttpResponseMessage(HttpStatusCode.BadRequest)); + } + + // string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads"); + // Other code goes here + // profileImage.SaveAs (); + return "/path/to/image.png"; + } + + } +} + diff --git a/web/Controllers/FrontOfficeController.cs b/web/Controllers/FrontOfficeController.cs new file mode 100644 index 00000000..c55a67de --- /dev/null +++ b/web/Controllers/FrontOfficeController.cs @@ -0,0 +1,128 @@ +using System; +using Yavsc; +using SalesCatalog; +using SalesCatalog.Model; +using System.Web.Mvc; +using System.Web; +using System.Text.RegularExpressions; +using System.IO; +using Yavsc.Controllers; +using System.Collections.Generic; + +namespace Yavsc.Controllers +{ + public class FrontOfficeController : Controller + { + [AcceptVerbs("GET")] + public ActionResult Catalog () + { + return View ( + CatalogManager.GetCatalog () + ); + } + /// + /// Catalog this instance. + /// + [AcceptVerbs("GET")] + public ActionResult Brand (string id) + { + Catalog c = CatalogManager.GetCatalog (); + ViewData ["BrandName"] = id; + return View ( c.GetBrand (id) ); + } + + /// + /// get the product category + /// + /// The category. + /// Bn. + /// Pc. + [AcceptVerbs("GET")] + public ActionResult ProductCategory (string id, string pc) + { + ViewData ["BrandName"] = id; + return View ( + CatalogManager.GetCatalog ().GetBrand (id).GetProductCategory (pc) + ); + } + + [AcceptVerbs("GET")] + public ActionResult Product (string id, string pc, string pref) + { + Product p = null; + ViewData ["BrandName"] = id; + ViewData ["ProdCatRef"] = pc; + ViewData ["ProdRef"] = pref; + Catalog cat = CatalogManager.GetCatalog (); + if (cat == null) { + ViewData ["Message"] = "Catalog introuvable"; + ViewData ["RefType"] = "Catalog"; + return View ("ReferenceNotFound"); + } + Brand b = cat.GetBrand (id); + if (b == null) { + ViewData ["RefType"] = "Brand"; + return View ("ReferenceNotFound"); + } + ProductCategory pcat = b.GetProductCategory (pc); + if (pcat == null) { + ViewData ["RefType"] = "ProductCategory"; + return View ("ReferenceNotFound"); + } + ViewData ["ProdCatName"] = pcat.Name; + p = pcat.GetProduct (pref); + if (p.CommandForm==null) + p.CommandForm = b.DefaultForm; + + return View ((p is Service)?"Service":"Product", p); + + } + + public ActionResult Command() + { + return View (); + } + + [HttpPost] + [Authorize] + public ActionResult Command(FormCollection collection) + { + try { + // get files from the request + string fnre = "[A-Za-z0-9~\\-.]+"; + HttpFileCollectionBase hfc = Request.Files; + + foreach (String h in hfc.AllKeys) + { + if (!Regex.Match(hfc[h].FileName,fnre).Success) + { + ViewData ["Message"] = "File name refused"; + ModelState.AddModelError( + h, + string.Format( + "The file name {0} dosn't match an acceptable file name {1}", + hfc[h].FileName,fnre)) + ; + return View(collection); + } + } + foreach (String h in hfc.AllKeys) + { + // TODO Limit with hfc[h].ContentLength + hfc[h].SaveAs(Path.Combine(FileSystemController.BaseDir,hfc[h].FileName)); + } + if (Session["Basket"]==null) + Session["Basket"]=new List(); + List basket = Session["Basket"] as List; + // Add specified product command to the basket, + basket.Add(new Commande(collection)); + return View (collection); + } catch (Exception e) { + ViewData ["Message"] = "Exception:"+e.Message; + return View (collection); + } + } + + } +} + diff --git a/web/Controllers/HomeController.cs b/web/Controllers/HomeController.cs new file mode 100644 index 00000000..95a15a10 --- /dev/null +++ b/web/Controllers/HomeController.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.Mail; +using System.Web; +using System.Web.Configuration; +using System.Web.Mvc; +using System.Web.Mvc.Ajax; +using Yavsc; + +namespace Yavsc.Controllers +{ + public class HomeController : Controller + { + // Site name + private static string name = null; + + /// + /// Gets or sets the site name. + /// + /// The name. + [Obsolete("Use YavscHelpers.SiteName insteed.")] + public static string Name { + get { + if (name == null) + name = WebConfigurationManager.AppSettings ["Name"]; + return name; + } + } + // Administrator email + private static string admail = + WebConfigurationManager.AppSettings ["AdminEmail"]; + /// + /// Gets the Administrator email. + /// + /// The admail. + public static string Admail { + get { + return admail; + } + } + + + private static string owneremail = null; + /// + /// Gets or sets the owner email. + /// + /// The owner email. + public static string OwnerEmail { + get { + if (owneremail == null) + owneremail = WebConfigurationManager.AppSettings.Get ("OwnerEMail"); + return owneremail; + } + set { + owneremail = value; + } + } + + public ActionResult Index () + { + InitCatalog (); + ViewData ["Message"] = string.Format(T.GetString("Welcome")+"({0})",GetType ().Assembly.FullName); + return View (); + } + + public void InitCatalog() { + CultureInfo culture = null; + string defaultCulture = "fr"; + + if (Request.UserLanguages.Length > 0) { + try { + culture = new CultureInfo (Request.UserLanguages [0]); + } + catch (Exception e) { + ViewData ["Message"] = e.ToString (); + culture = CultureInfo.CreateSpecificCulture(defaultCulture); + } + } + else culture = CultureInfo.CreateSpecificCulture(defaultCulture); + System.Threading.Thread.CurrentThread.CurrentUICulture = culture; + System.Threading.Thread.CurrentThread.CurrentCulture = culture; + string lcd = Server.MapPath ("./locale"); + Mono.Unix.Catalog.Init("i8n1", lcd ); + } + + public ActionResult AOEMail (string reason, string body) + { + // requires valid owner and admin email? + using (System.Net.Mail.MailMessage msg = new MailMessage(owneremail,admail,"Poke : "+reason,body)) + { + using (System.Net.Mail.SmtpClient sc = new SmtpClient()) + { + sc.Send (msg); + return View (); + } + } + } + } +} diff --git a/web/Controllers/T.cs b/web/Controllers/T.cs new file mode 100644 index 00000000..a212dbad --- /dev/null +++ b/web/Controllers/T.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Configuration; +using System.Web.Mvc; +using System.Web.Mvc.Ajax; +using System.Net.Mail; +using Yavsc; +using System.Globalization; + +namespace Yavsc +{ + public class T + { + public static string GetString(string msgid) + { + return Mono.Unix.Catalog.GetString (msgid); + } + + } +} diff --git a/web/Controllers/WorkFlowController.cs b/web/Controllers/WorkFlowController.cs new file mode 100644 index 00000000..27eb9f7c --- /dev/null +++ b/web/Controllers/WorkFlowController.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +using System.Web.Http; +using WorkFlowProvider; +using yavscModel.WorkFlow; + +namespace Yavsc.ApiControllers +{ + public class WorkFlowController : ApiController + { + [HttpGet] + public object Index() + { + return new { test="Hello World" }; + } + + + public object Details(int id) + { + throw new NotImplementedException (); + } + + public object Create() + { + throw new NotImplementedException (); + } + public object Edit(int id) + { + throw new NotImplementedException (); + } + + public object Delete(int id) + { + throw new NotImplementedException (); + } + + IContentProvider contentProvider = null; + IContentProvider ContentProvider { + get { + if (contentProvider == null ) + contentProvider = WFManager.GetContentProviderFWC (); + return contentProvider; + } + } + + + } +} diff --git a/web/FileInfoCollection.cs b/web/FileInfoCollection.cs new file mode 100644 index 00000000..7212f4ed --- /dev/null +++ b/web/FileInfoCollection.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Yavsc +{ + public class FileInfoCollection : List + { + public FileInfoCollection (System.IO.FileInfo[] collection) + { + this.AddRange (collection); + } + } +} + diff --git a/web/Global.asax b/web/Global.asax new file mode 100644 index 00000000..569f561d --- /dev/null +++ b/web/Global.asax @@ -0,0 +1 @@ +<%@ Application Inherits="Yavsc.MvcApplication" %> diff --git a/web/Global.asax.cs b/web/Global.asax.cs new file mode 100644 index 00000000..bfb3ac3c --- /dev/null +++ b/web/Global.asax.cs @@ -0,0 +1,69 @@ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; +using System.Web.Http; + +namespace Yavsc +{ + public class MvcApplication : System.Web.HttpApplication + { + public static void RegisterRoutes (RouteCollection routes) + { + + routes.IgnoreRoute ("{resource}.axd/{*pathInfo}"); + + routes.MapRoute ( + "Blog", + "Blog/{user}/{title}", + new { controller = "Blogs", action = "Index", user=UrlParameter.Optional, title = UrlParameter.Optional } + ); + routes.MapRoute ( + "Blogs", + "Blogs/{action}/{user}/{title}", + new { controller = "Blogs", action = "Index", user=UrlParameter.Optional, title = UrlParameter.Optional} + ); + + routes.MapRoute ( + "Default", + "{controller}/{action}/{id}", + new { controller = "Home", action = "Index", id = "" } + ); + + } + + protected void Application_Start () + { + AreaRegistration.RegisterAllAreas (); + + GlobalConfiguration.Configuration.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{action}/{*path}", + defaults: new { controller = "WorkFlow", action="Index", path = "" } + ); + + RegisterRoutes (RouteTable.Routes); + Error += HandleError; + } + + void HandleError (object sender, EventArgs e) + { + if (Server.GetLastError ().GetBaseException () is System.Web.HttpRequestValidationException) { + Response.Clear (); + Response.Write ("Invalid characters.
"); + Response.Write ("You may want to use your " + + "browser to go back to your form. " + + "You also can hit the url referrer."); + Response.StatusCode = 200; + Response.End (); + } + } + + } +} diff --git a/web/Helpers/BBCodeHelper.cs b/web/Helpers/BBCodeHelper.cs new file mode 100644 index 00000000..2c9246f8 --- /dev/null +++ b/web/Helpers/BBCodeHelper.cs @@ -0,0 +1,349 @@ +using System; +using CodeKicker.BBCode; +using System.Collections.Generic; +using System.Web.Mvc; +using System.Collections.Specialized; +using System.Text; + +namespace Yavsc.Helpers +{ + + public static class BBCodeHelper + { + static Dictionary parent = new Dictionary (); + private static string tclass="shoh"; + private static string cclass="hiduh"; + private static string mp4=null, ogg=null, webm=null; + public static string BBCodeViewClass { + get { + return cclass; + } + set { + cclass = value; + } + } + + public static string BBCodeCaseClass { + get { + return tclass; + } + set { + tclass = value; + } + } + + public static string[] BBTagsUsage { + get { + + List u = new List (); + foreach (BBTag t in Parser.Tags) + if (!parent.ContainsValue(t)) + { + TagBuilder tib = new TagBuilder ("div"); + tib.AddCssClass (BBCodeCaseClass); + string temp = tagUsage (t); + + tib.InnerHtml = temp; + u.Add (string.Format ("{0}
{1}
", tib.ToString (), Parser.ToHtml (temp),BBCodeViewClass)); + + + } + return u.ToArray (); + } + + + } + static string tagUsage(BBTag t,string content=null) + { + StringBuilder sb = new StringBuilder (); + sb.AppendFormat ("[{0}", t.Name); + List done = new List (); + foreach (var a in t.Attributes) { + if (string.IsNullOrEmpty (a.Name)) { + sb.AppendFormat ("=default_attribute_value"); + done.Add (a.ID); + } + } + + foreach (var a in t.Attributes) { + if (!done.Contains(a.ID)) { + sb.AppendFormat (" {0}=attribute_value", a.ID); + done.Add (a.ID); + } + } + if (content==null) + sb.AppendFormat ("]content[/{0}]", t.Name); + else + sb.AppendFormat ("]{1}[/{0}]", t.Name, content); + + if (!parent.ContainsKey(t.Name)) return sb.ToString (); + return tagUsage (parent [t.Name],sb.ToString()); + + } + private static BBCodeParser parser = null; + private static int sect1; + private static int sect2; + private static int sect3; + private static Dictionary d = new Dictionary (); + + public static void Init () + { + sect1 = 0; + sect2 = 0; + sect3 = 0; + d.Clear (); + } + + static string TocContentTransformer (string instr) + { + StringBuilder ttb = new StringBuilder (); + int m1=0, m2=0, m3=0; + foreach (string key in d.Keys) { + int s1 = 0, s2 = 0, s3 = 0; + string[] snums = key.Split ('.'); + s1 = int.Parse (snums [0]); + if (snums.Length>1) + s2 = int.Parse (snums [1]); + if (snums.Length>2) { + s3 = int.Parse (snums [2]); + } + if (m1 < s1) + m1 = s1; + if (m2 < s2) + m2 = s2; + if (m3 < s3) + m3 = s3; + + } + string[,,] toc = new string[m1+1, m2+1, m3+1]; + foreach (string key in d.Keys) { + int s1 = 0, s2 = 0, s3 = 0; + string[] snums = key.Split ('.'); + s1 = int.Parse (snums [0]); + if (snums.Length>1) + s2 = int.Parse (snums [1]); + if (snums.Length>2) { + s3 = int.Parse (snums [2]); + } + toc [s1, s2, s3] = d [key]; + } + + for (int i = 1; i<=m1; i++) { + string t1 = toc [i, 0, 0]; + // assert t1 != null + ttb.AppendFormat ("{0}) {1}
\n", i, t1); + + for (int j = 1; j <= m2; j++) { + string t2 = toc[i,j,0]; + if (t2 == null) + break; + ttb.AppendFormat ("{0}.{1}) {2}
\n", i,j, t2); + + for (int k = 1; k <= m3; k++) { + string t3 = toc[i,j,k]; + if (t3 == null) + break; + ttb.AppendFormat ("{0}.{1}.{2}) {3}
\n", i,j,k,t3); + + } + } + } + return ttb.ToString (); + } + + static string DocPageContentTransformer (string instr) + { + return TocContentTransformer(instr)+instr; + } + + static string TagContentTransformer (string instr) + { + return instr; + } + + static string TitleContentTransformer (IAttributeRenderingContext arg) + { + string tk; + if (arg.AttributeValue==null) + return null; + string t = arg.AttributeValue; + t=t.Replace ('_', ' '); + if (sect3 == 0) + if (sect2 == 0) { + tk = string.Format ("{0}", sect1); + } + else + tk = string.Format ("{0}.{1}", sect1 + 1, sect2); + else + tk = string.Format ("{0}.{1}.{2}", sect1 + 1, sect2 + 1, sect3); + if (!d.ContainsKey (tk)) + d.Add (tk, t); + return t; + } + + static string Section1Transformer (string instr) + { + sect1++; + sect2 = 0; + sect3 = 0; + return instr; + } + + static string Section2Transformer (string instr) + { + sect2++; + sect3 = 0; + return instr; + } + + static string Section3Transformer (string instr) + { + sect3++; + return instr; + } + + static string L3ContentTransformer (IAttributeRenderingContext arg) + { + return (sect1 + 1).ToString () + "." + (sect2 + 1) + "." + sect3; + } + + static string L2ContentTransformer (IAttributeRenderingContext arg) + { + return (sect1 + 1).ToString () + "." + sect2; + } + + static string L1ContentTransformer (IAttributeRenderingContext arg) + { + return sect1.ToString (); + } + static string OggSrcTr (IAttributeRenderingContext arg) + { + ogg = arg.AttributeValue; + return ogg; + } + static string Mp4SrcTr (IAttributeRenderingContext arg) + { + mp4=arg.AttributeValue; + return mp4; + } + static string WebmSrcTr (IAttributeRenderingContext arg) + { + webm = arg.AttributeValue; + return webm; + } + static string VideoContentTransformer (string cnt) + { + StringBuilder sb = new StringBuilder(); + if (mp4 != null) { + TagBuilder tb = new TagBuilder ("source"); + tb.Attributes.Add ("src", mp4); + tb.Attributes.Add ("type", "video/mp4"); + sb.Append (tb.ToString(TagRenderMode.StartTag)); + } + if (ogg != null) { + TagBuilder tb = new TagBuilder ("source"); + tb.Attributes.Add ("src", ogg); + tb.Attributes.Add ("type", "video/ogg"); + sb.Append (tb.ToString(TagRenderMode.StartTag)); + } + if (webm != null) { + TagBuilder tb = new TagBuilder ("source"); + tb.Attributes.Add ("src", webm); + tb.Attributes.Add ("type", "video/webm"); + sb.Append (tb.ToString(TagRenderMode.StartTag)); + + } + mp4 = null; + ogg=null; + webm=null; + sb.Append (cnt); + return sb.ToString(); + } + + public static BBCodeParser Parser { + get { + if (parser == null) { + Init (); + BBTag bblist =new BBTag ("list", "
    ", "
"); + BBTag bbs2=new BBTag ("sect2", + "
" + + "

${para} - ${title}

" + + "
${content}", + "
", + false, true, + Section2Transformer, + new BBAttribute ("title", "",TitleContentTransformer), + new BBAttribute ("title", "title", TitleContentTransformer), + new BBAttribute ("para", "para", L2ContentTransformer)); + BBTag bbs1=new BBTag ("sect1", + "
" + + "

${para} - ${title}

" + + "
${content}", + "
", + false, true, + Section1Transformer, + new BBAttribute ("title", "",TitleContentTransformer), + new BBAttribute ("title", "title", TitleContentTransformer), + new BBAttribute ("para", "para", L1ContentTransformer)); + BBTag bbdp=new BBTag ("docpage", + "
${content}
", "", + false, + false, + DocPageContentTransformer); + + parser = new BBCodeParser (new[] { + new BBTag ("b", "", ""), + new BBTag ("i", "", ""), + new BBTag ("u", "", ""), + new BBTag ("code", "", ""), + new BBTag ("img", "", "", false, true, new BBAttribute ("style", "style")), + new BBTag ("quote", "
", "
"), + new BBTag ("div", "
", "
", new BBAttribute("style","style")), + new BBTag ("p", "

", "

"), + new BBTag ("h", "

", "

"), + bblist, + new BBTag ("*", "
  • ", "
  • ", true, false), + new BBTag ("url", "", "", new BBAttribute ("href", ""), new BBAttribute ("href", "href")), + new BBTag ("br", "
    ", "", true, false), + new BBTag ("video", "", + new BBAttribute("mp4","mp4"), + new BBAttribute("ogg","ogg"), + new BBAttribute("webm","webm"), + new BBAttribute("style","style")), + new BBTag ("tag", "", "", true, true, + TagContentTransformer), + bbs1, + bbs2, + new BBTag ("sect3", + "
    " + + "

    ${para} - ${title}

    " + + "
    ${content}", + "
    ", + false, true, + Section3Transformer, + new BBAttribute ("title", "",TitleContentTransformer), + new BBAttribute ("title", "title", TitleContentTransformer), + new BBAttribute ("para", "para", L3ContentTransformer) + ), + bbdp, + new BBTag ("f", "", + new BBAttribute ("src", ""), new BBAttribute ("src", "src")), + + } + ); + parent.Add ("*", bblist); + parent.Add ("sect3", bbs2); + parent.Add ("sect2", bbs1); + parent.Add ("sect1", bbdp); + + } + return parser; + } + + } + } +} + diff --git a/web/Helpers/YavscHelpers.cs b/web/Helpers/YavscHelpers.cs new file mode 100644 index 00000000..2c3ef918 --- /dev/null +++ b/web/Helpers/YavscHelpers.cs @@ -0,0 +1,19 @@ +using System; +using System.Web; +using System.Configuration; + +namespace Yavsc.Helpers +{ + public static class YavscHelpers + { + private static string siteName = null; + public static string SiteName { + get { + if (siteName == null) + siteName = ConfigurationManager.AppSettings ["Name"]; + return siteName; + } + } + } +} + diff --git a/web/Models/App.master b/web/Models/App.master new file mode 100644 index 00000000..0ae55003 --- /dev/null +++ b/web/Models/App.master @@ -0,0 +1,61 @@ +<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> + + + + + + + + + + <asp:ContentPlaceHolder ID="titleContent" runat="server" /> + <asp:Literal runat="server" Text=" - " /><%= YavscHelpers.SiteName %> + + + + +
    +
    + <% if (Membership.GetUser()==null) { %> + +<%= Html.ActionLink("Login", "Login", "Account", new { returnUrl=Request.Url.PathAndQuery }, null ) %> + +<% } else { %> +<%= HttpContext.Current.User.Identity.Name %> + +<%= Html.ActionLink( "Logout", "Logout", "Account", new { returnUrl=Request.Url.PathAndQuery }, null) %> + <%= Html.ActionLink( "Poster", "Post", "Blogs" ) %> + <%= Html.ActionLink( "Profile", "Profile", "Account" ) %> + +<% } %> + <%= Html.ActionLink( "Accueil", "Index", "Home" ) %> + +
    + + + +

    <%=Html.Encode(YavscHelpers.SiteName)%>

    +<% if (ViewData["Error"]!=null) { %> +
    +<%= Html.Encode(ViewData["Error"]) %> +
    +<% } %> +<% if (ViewData["Message"]!=null) { %> +
    +<%= Html.Encode(ViewData["Message"]) %> +
    +<% } %> +
    +
    +
    + + + +
    +
    +
    + <%= string.Join("\n",Yavsc.ThanksHelper.Links()) %> +
    + + + diff --git a/web/README b/web/README new file mode 100644 index 00000000..c999c3dd --- /dev/null +++ b/web/README @@ -0,0 +1,45 @@ + Yavsc is a point of sales, implemented in a dot Net Web application + Copyright (C) 2014 Paul Schneider + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +You may contact me at + +------- + +Yavsc ("Mon Auto Entreprise") + +Les services : + +- Dépannage informatique +- Développement logiciel +- Developpement Web +- Audit de sécurité +- Dématérialisation des documents +- ... + +Les livrables : + +- Un site web ASP.Net propulsé par Mono et Apache, et une application mobile pour + * demander un devis + * avoir un status des projets des clients + * demander une intervention / saisir un ticket + * avoir un status des ticket du client + +Les projets : + +- des acteurs / des ressources humaines +- des etapes inter dépendantes, leurs attributs, leurs états +- des dates butoires + diff --git a/web/RegistrationMail.txt b/web/RegistrationMail.txt new file mode 100644 index 00000000..90e5bec0 --- /dev/null +++ b/web/RegistrationMail.txt @@ -0,0 +1,9 @@ + +Votre compte <%SiteName%> a été créé, votre nom d'utilisateur +est <%UserName%>. + +Pour l'activer, veuillez suivre le lien suivant : + +<%UserActivatonUrl%> + +Merci d'avoir créé un compte utilisateur. diff --git a/web/Test/TestByteA.cs b/web/Test/TestByteA.cs new file mode 100644 index 00000000..bad66d98 --- /dev/null +++ b/web/Test/TestByteA.cs @@ -0,0 +1,87 @@ +using NUnit.Framework; +using System; +using System.Configuration; +using Npgsql; + +namespace Yavsc +{ + [TestFixture ()] + public class TestByteA: IDisposable + { + //string cnxName = "yavsc"; + string ConnectionString { get { + return "Server=127.0.0.1;Port=5432;Database=mae;User Id=mae;Password=admin;Encoding=Unicode;" ; + // return ConfigurationManager.ConnectionStrings [cnxName].ConnectionString; + + } } + + [TestFixtureSetUp] + public void Init() + { + // create the table + Console.WriteLine ("cnx:"+ConnectionString); + using (NpgsqlConnection cnx = new NpgsqlConnection (ConnectionString)) + { + cnx.Open (); + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "drop table testbytea"; + try { cmd.ExecuteNonQuery (); } + catch (NpgsqlException) { + } + cmd.CommandText = "create table testbytea( t bytea )"; + cmd.ExecuteNonQuery (); + } + } + } + + [Test(Description="Test storing a byte array in a Postgresql table field")] + public void TestStoreByteA () + { + byte []a = new byte[3]; + a[0]=1; + a[1]=2; + a[2]=3; + using (NpgsqlConnection cnx = new NpgsqlConnection (ConnectionString)) { + cnx.Open (); + using (NpgsqlCommand cmd = cnx.CreateCommand ()) + { + cmd.CommandText = "insert into testbytea (t) values (@tv)"; + cmd.Parameters.Add ("@tv", a); + cmd.ExecuteNonQuery (); + } + + using (NpgsqlCommand cmd = cnx.CreateCommand ()) + { + cmd.CommandText = "select t from testbytea"; + cmd.Parameters.Add ("@tv", a); + + NpgsqlDataReader rdr = cmd.ExecuteReader (); + if (!rdr.Read ()) + throw new Exception ("Read failed"); + int i = rdr.GetOrdinal ("t"); + byte []rded = (byte[]) rdr.GetValue (i); + if (rded.Length!=a.Length) + throw new Exception("Lengthes don't match"); + } + } + } + + #region IDisposable implementation + + [TestFixtureTearDown] + public void Dispose () + { + // drop the table + using (NpgsqlConnection cnx = new NpgsqlConnection (ConnectionString)) { + cnx.Open (); + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "drop table testbytea"; + cmd.ExecuteNonQuery (); + } + } + } + + #endregion + } +} + diff --git a/web/Tests.cs b/web/Tests.cs new file mode 100644 index 00000000..975f22a3 --- /dev/null +++ b/web/Tests.cs @@ -0,0 +1,19 @@ + +#if TEST + +using System; +using NUnit.Framework; + +namespace Yavsc +{ + [TestFixture()] + public class Tests + { + [Test()] + public void TestCase () + { + } + } +} + +#endif diff --git a/web/TextWriterOutput.log b/web/TextWriterOutput.log new file mode 100644 index 00000000..e69de29b diff --git a/web/Thanks/ThanksConfigurationCollection.cs b/web/Thanks/ThanksConfigurationCollection.cs new file mode 100644 index 00000000..d97460a7 --- /dev/null +++ b/web/Thanks/ThanksConfigurationCollection.cs @@ -0,0 +1,22 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + public class ThanksConfigurationCollection : ConfigurationElementCollection + { + protected override object GetElementKey (ConfigurationElement element) + { + return ((ThanksConfigurationElement) element).Name; + } + protected override ConfigurationElement CreateNewElement () + { + return new ThanksConfigurationElement(); + } + public ThanksConfigurationElement GetElement (string name) + { + return this.BaseGet(name) as ThanksConfigurationElement; + } + } +} + diff --git a/web/Thanks/ThanksConfigurationElement.cs b/web/Thanks/ThanksConfigurationElement.cs new file mode 100644 index 00000000..a4b71f14 --- /dev/null +++ b/web/Thanks/ThanksConfigurationElement.cs @@ -0,0 +1,48 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + public class ThanksConfigurationElement : ConfigurationElement + { + [ConfigurationProperty("name", IsKey=true, IsRequired=true)] + public string Name { + get { + return (string) base ["name"]; + } + set { base ["name"] = value; } + } + + [ConfigurationProperty("url")] + public string Url { + get { + return (string) base ["url"]; + } + set { base ["url"] = value; } + } + + [ConfigurationProperty("image")] + public string Image { + get { + return (string) base ["image"]; + } + set { base ["image"] = value; } + } + + /// + /// Gets or sets the display. + /// + /// + /// The displaied text when no image is provided and we + /// don't want use the name attribute. + /// + [ConfigurationProperty("display")] + public string Display { + get { + return (string) base ["display"]; + } + set { base ["display"] = value; } + } + } +} + diff --git a/web/Thanks/ThanksConfigurationSection.cs b/web/Thanks/ThanksConfigurationSection.cs new file mode 100644 index 00000000..c86382ea --- /dev/null +++ b/web/Thanks/ThanksConfigurationSection.cs @@ -0,0 +1,39 @@ +using System; +using System.Configuration; + +namespace Yavsc +{ + public class ThanksConfigurationSection : ConfigurationSection + { + [ConfigurationProperty("to")] + public ThanksConfigurationCollection To { + get { + return (ThanksConfigurationCollection) this["to"]; + } + set { + this ["to"] = value; + } + } + + [ConfigurationProperty("html_class")] + public string HtmlClass { + get { + return (string)this ["html_class"]; + } + set { + this ["html_class"] = value; + } + } + + [ConfigurationProperty("title_format")] + public string TitleFormat { + get { + return (string)this ["title_format"]; + } + set { + this ["title_format"] = value; + } + } + } +} + diff --git a/web/Thanks/ThanksHelper.cs b/web/Thanks/ThanksHelper.cs new file mode 100644 index 00000000..3f5bbf72 --- /dev/null +++ b/web/Thanks/ThanksHelper.cs @@ -0,0 +1,38 @@ +using System; +using System.Configuration; +using System.Collections.Generic; + +namespace Yavsc +{ + public static class ThanksHelper { + + public static string[] Links () + { + List result = new List() ; + ThanksConfigurationSection s = (ThanksConfigurationSection) ConfigurationManager.GetSection ("system.web/thanks"); + if (s == null) return result.ToArray(); + if (s.To == null) return result.ToArray(); + foreach (ThanksConfigurationElement e in s.To) { + string link = ""; + if (!string.IsNullOrEmpty(e.Url)) + link = string.Format("",e.Url); + link += "
    "; + string dsp = (string.IsNullOrEmpty(e.Display))?e.Name:e.Display; + if (!string.IsNullOrEmpty(e.Image)) { + string ttl = (string.IsNullOrEmpty(s.TitleFormat))?"Go and see the website ({0})":s.TitleFormat; + ttl = string.Format(ttl,dsp); + link += string.Format( + "\"{0}\"", + dsp,e.Image,ttl); + } + else link += dsp; + link += "
    "; + if (e.Url!=null) + link += "
    "; + result.Add (link); + } + return result.ToArray(); + } + } + +} diff --git a/web/Views/Account/AddRole.aspx b/web/Views/Account/AddRole.aspx new file mode 100644 index 00000000..d0ba38b5 --- /dev/null +++ b/web/Views/Account/AddRole.aspx @@ -0,0 +1,19 @@ +<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Ajout d'un role

    +
    + + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("DoAddRole", "Account")) %> +<% { %> +Nom du rôle : +<%= Html.TextBox( "RoleName" ) %> +<%= Html.ValidationMessage("RoleName", "*") %>
    + +<% } %> +
    + + diff --git a/web/Views/Account/Admin.aspx b/web/Views/Account/Admin.aspx new file mode 100644 index 00000000..65e9df7c --- /dev/null +++ b/web/Views/Account/Admin.aspx @@ -0,0 +1,34 @@ +<%@ Page Title="Administration" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +

    Liste des administrateurs

    +
    + + +
    + + +<% foreach (string u in (string[])ViewData["admins"]) { %> + + +<% } %> +
    +<%= u %> <%= Html.ActionLink("Remove","RemoveFromRole",new { username = u, rolename="Admin", returnUrl = Request.Url.PathAndQuery })%> +
    +
    +
    +

    Ajout d'un administrateur +

    +

    <%= Html.ValidationSummary() %>

    + +<% using ( Html.BeginForm("Admin", "Account") ) { %> + +<%= Html.LabelFor(model => model.UserName) %> : +<%= Html.DropDownListFor(model => model.UserName, (List)ViewData["useritems"] ) %> +<%= Html.ValidationMessage("UserName", "*") %> + + + <% } %> + +
    +
    + diff --git a/web/Views/Account/ChangePassword.aspx b/web/Views/Account/ChangePassword.aspx new file mode 100644 index 00000000..d272736c --- /dev/null +++ b/web/Views/Account/ChangePassword.aspx @@ -0,0 +1,26 @@ +<%@ Page Title="Change your Password" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + + +<%= Html.ValidationSummary("Modification de mot de passe") %> +<% using(Html.BeginForm("ChangePassword", "Account")) { %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
    + + <%= Html.Password( "OldPassword" ) %> +<%= Html.ValidationMessage("OldPassword", "*") %>
    + + <%= Html.Password( "NewPassword" ) %> +<%= Html.ValidationMessage("NewPassword", "*") %>
    + + <%= Html.Password( "ConfirmPassword" ) %> +<%= Html.ValidationMessage("ConfirmPassword", "*") %> + +<% } %> + +
    + + diff --git a/web/Views/Account/ChangePasswordSuccess.aspx b/web/Views/Account/ChangePasswordSuccess.aspx new file mode 100644 index 00000000..1a3bf654 --- /dev/null +++ b/web/Views/Account/ChangePasswordSuccess.aspx @@ -0,0 +1,8 @@ +<%@ Page Title="Successfully changed your password" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +
    +<%= Html.ActionLink("Register","Register")%>
    +
    <%= Html.ActionLink("ChangePassword","ChangePassword")%>
    +
    diff --git a/web/Views/Account/Index.aspx b/web/Views/Account/Index.aspx new file mode 100644 index 00000000..a75eb950 --- /dev/null +++ b/web/Views/Account/Index.aspx @@ -0,0 +1,8 @@ +<%@ Page Title="Comptes utilisateur - Index" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Comptes utilisteur

    +
    + + diff --git a/web/Views/Account/Login.aspx b/web/Views/Account/Login.aspx new file mode 100644 index 00000000..a96ea09f --- /dev/null +++ b/web/Views/Account/Login.aspx @@ -0,0 +1,28 @@ +<%@ Page Title="Login" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + +
    +<%= Html.ValidationSummary("Ouverture de session") %> +<% using(Html.BeginForm("DoLogin", "Account")) %> +<% { %> +<%= Html.LabelFor(model => model.UserName) %> +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
    + +<%= Html.LabelFor(model => model.Password) %> +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
    + + +<%= Html.CheckBox("RememberMe") %> +<%= Html.ValidationMessage("RememberMe", "") %>
    +<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %> + + +<% } %> +
    +
    +<%= Html.ActionLink("S'enregistrer","Register",new {returnUrl=ViewData["returnUrl"]}) %>
    +
    diff --git a/web/Views/Account/Profile.aspx b/web/Views/Account/Profile.aspx new file mode 100644 index 00000000..113dde26 --- /dev/null +++ b/web/Views/Account/Profile.aspx @@ -0,0 +1,47 @@ +<%@ Page Title="Profile" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + +<%=ViewData["UserName"]%> : Profile - <%=YavscHelpers.SiteName%> + + +

    <%=ViewData["UserName"]%> : Profile - <%=YavscHelpers.SiteName%>

    +

    <%= Html.ActionLink("Changer de mot de passe","ChangePassword", "Account")%>

    +
    + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("UpdateProfile", "Account", FormMethod.Post, new { enctype = "multipart/form-data" })) %> +<% { %> + + + + + + + + + + +
    +<%= Html.LabelFor(model => model.Address) %> +<%= Html.TextBox("Address") %> +<%= Html.ValidationMessage("Address", "*") %>
    +<%= Html.LabelFor(model => model.CityAndState) %> +<%= Html.TextBox("CityAndState") %> +<%= Html.ValidationMessage("CityAndState", "*") %>
    +<%= Html.LabelFor(model => model.Country) %> +<%= Html.TextBox("Country") %> +<%= Html.ValidationMessage("Country", "*") %>
    +<%= Html.LabelFor(model => model.WebSite) %> +<%= Html.TextBox("WebSite") %> +<%= Html.ValidationMessage("WebSite", "*") %>
    +<%= Html.LabelFor(model => model.BlogVisible) %> +<%= Html.CheckBox("BlogVisible") %> +<%= Html.ValidationMessage("BlogVisible", "*") %>
    +<%= Html.LabelFor(model => model.BlogTitle) %> +<%= Html.TextBox("BlogTitle") %> +<%= Html.ValidationMessage("BlogTitle", "*") %>
    +Avatar " alt=""/> + +<%= Html.ValidationMessage("AvatarFile", "*") %>
    + +<% } %> +
    diff --git a/web/Views/Account/Register.aspx b/web/Views/Account/Register.aspx new file mode 100644 index 00000000..b501dddf --- /dev/null +++ b/web/Views/Account/Register.aspx @@ -0,0 +1,45 @@ +<%@ Page Title="Register" Language="C#" Inherits="Yavsc.RegisterPage" MasterPageFile="~/Models/App.master" %> + + + + +

    Créez votre compte utilisateur <%= Html.Encode(YavscHelpers.SiteName) %>

    +
    + + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("Register", "Account")) %> +<% { %> + + + + + +
    +<%= Html.LabelFor(model => model.UserName) %> + +<%= Html.TextBox( "UserName" ) %> +<%= Html.ValidationMessage("UserName", "*") %>
    +<%= Html.LabelFor(model => model.Password) %> + +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %> +
    +<%= Html.LabelFor(model => model.ConfirmPassword) %> + + <%= Html.Password( "ConfirmPassword" ) %> +<%= Html.ValidationMessage("ConfirmPassword", "*") %> +
    +<%= Html.LabelFor(model => model.Email) %> + +<%= Html.TextBox( "Email" ) %> +<%= Html.ValidationMessage("Email", "*") %> +
    +
    +<%= Html.Hidden("returnUrl",ViewData["returnUrl"]) %> + + +<% } %> +
    + + diff --git a/web/Views/Account/RegistrationPending.aspx b/web/Views/Account/RegistrationPending.aspx new file mode 100644 index 00000000..7bb96ab4 --- /dev/null +++ b/web/Views/Account/RegistrationPending.aspx @@ -0,0 +1,17 @@ +<%@ Page Title="Comptes utilisateur - Index" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Comptes utilisteur

    +
    + +

    +Votre compte utilisateur +<%= Html.Encode(YavscHelpers.SiteName) %> +a été créé, un e-mail de validation de votre compte a été envoyé a l'adresse fournie:
    +<<%= Html.Encode(ViewData["email"]) %>>.
    +Vous devriez le recevoir rapidement.
    +Pour valider votre compte, suivez le lien indiqué dans cet e-mail. +

    +">Retour +
    diff --git a/web/Views/Account/RemoveRoleQuery.aspx b/web/Views/Account/RemoveRoleQuery.aspx new file mode 100644 index 00000000..a6bc14b4 --- /dev/null +++ b/web/Views/Account/RemoveRoleQuery.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="User removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Suppression d'un rôle

    +
    + +
    +<%= Html.ValidationSummary() %> +<% using ( Html.BeginForm("RemoveRole") ) { %> +Supprimer le rôle +<%= Html.Encode( ViewData["roletoremove"] ) %> ? +
    +"/> + + +<% } %> +
    + +
    + + diff --git a/web/Views/Account/RemoveUserQuery.aspx b/web/Views/Account/RemoveUserQuery.aspx new file mode 100644 index 00000000..8e5fd740 --- /dev/null +++ b/web/Views/Account/RemoveUserQuery.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="User removal" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Suppression d'un utilisateur

    +
    + +
    +<%= Html.ValidationSummary() %> +<% using ( Html.BeginForm("RemoveUser","Account") ) { %> +Supprimer l'utilisateur +<%= Html.Encode( ViewData["usertoremove"] ) %> ? +
    +"/> + + +<% } %> +
    + +
    + + diff --git a/web/Views/Account/RoleList.aspx b/web/Views/Account/RoleList.aspx new file mode 100644 index 00000000..573fb065 --- /dev/null +++ b/web/Views/Account/RoleList.aspx @@ -0,0 +1,23 @@ +<%@ Page Title="Role list" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Liste des rôles

    +
    + +Roles: +
      + <%foreach (string rolename in (string[]) Model){ %> + +
    • <%=rolename%> <% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink("Supprimer","RemoveRole", new { rolename = rolename }, new { @class="actionlink" } ) %> +<% } %>
    • + <% } %> + +
    + <% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink("Ajouter un rôle","AddRole", null, new { @class="actionlink" } ) %> +<% } %> +
    + + diff --git a/web/Views/Account/UserList.aspx b/web/Views/Account/UserList.aspx new file mode 100644 index 00000000..b506bd92 --- /dev/null +++ b/web/Views/Account/UserList.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="User List" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Liste des utilisateurs

    +
    + + +
      + <%foreach (MembershipUser user in Model){ %> + +
    • <%=user.UserName%> <%=user.Email%> <%=(!user.IsApproved)?"(Not Approuved)":""%> <%=user.IsOnline?"Online":"Offline"%> +<% if (Roles.IsUserInRole("Admin")) { %> + <%= Html.ActionLink("Supprimer","RemoveUserQuery", new { username = user.UserName }, new { @class="actionlink" } ) %> +<% } %> +
    • + + <% }%> +
    + +
    + diff --git a/web/Views/Account/Validate.aspx b/web/Views/Account/Validate.aspx new file mode 100644 index 00000000..a26c70d5 --- /dev/null +++ b/web/Views/Account/Validate.aspx @@ -0,0 +1,8 @@ +<%@ Page Title="Comptes utilisateur - Validation" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Validation d'un compte utilisateur

    +
    + + diff --git a/web/Views/BackOffice/BackupCreated.aspx b/web/Views/BackOffice/BackupCreated.aspx new file mode 100644 index 00000000..a965d9d5 --- /dev/null +++ b/web/Views/BackOffice/BackupCreated.aspx @@ -0,0 +1,13 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + +

    Backup created

    +
    + +

    Error message

    <%= Html.Encode(Model.Error) %>
    +

    Message

    <%= Html.Encode(Model.Message) %>
    +

    File name

    <%= Html.Encode(Model.FileName) %>
    +

    Exit Code

    <%= Html.Encode(Model.ExitCode) %>
    + +
    diff --git a/web/Views/BackOffice/Backups.aspx b/web/Views/BackOffice/Backups.aspx new file mode 100644 index 00000000..5f625d33 --- /dev/null +++ b/web/Views/BackOffice/Backups.aspx @@ -0,0 +1,12 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + +Backups + + +

    Backups

    +
    + + +<%=Html.ActionLink("Create a database backup", "CreateBackup", "BackOffice")%>
    +<%=Html.ActionLink("Restaurations", "Restore", "BackOffice")%>
    +
    diff --git a/web/Views/BackOffice/CreateBackup.aspx b/web/Views/BackOffice/CreateBackup.aspx new file mode 100644 index 00000000..c287ffe7 --- /dev/null +++ b/web/Views/BackOffice/CreateBackup.aspx @@ -0,0 +1,27 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + +<%= Html.ValidationSummary("CreateBackup") %> +<% using (Html.BeginForm("CreateBackup","BackOffice")) { %> + +<%= Html.LabelFor(model => model.Host) %>: +<%= Html.TextBox( "Host" ) %> +<%= Html.ValidationMessage("Host", "*") %>
    +<%= Html.LabelFor(model => model.Port) %>: +<%= Html.TextBox( "Port" ) %> +<%= Html.ValidationMessage("Port", "*") %>
    +<%= Html.LabelFor(model => model.Dbname) %>: +<%= Html.TextBox( "Dbname" ) %> +<%= Html.ValidationMessage("Dbname", "*") %>
    +<%= Html.LabelFor(model => model.Dbuser) %>: +<%= Html.TextBox( "Dbuser" ) %> +<%= Html.ValidationMessage("Dbuser", "*") %>
    +<%= Html.LabelFor(model => model.Password) %>: +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
    + +<% } %> +
    diff --git a/web/Views/BackOffice/Index.aspx b/web/Views/BackOffice/Index.aspx new file mode 100644 index 00000000..0a999001 --- /dev/null +++ b/web/Views/BackOffice/Index.aspx @@ -0,0 +1,8 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + +<%= Html.ActionLink("Backups","Backups","BackOffice") %> + diff --git a/web/Views/BackOffice/Restore.aspx b/web/Views/BackOffice/Restore.aspx new file mode 100644 index 00000000..523e2b77 --- /dev/null +++ b/web/Views/BackOffice/Restore.aspx @@ -0,0 +1,43 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + + +<%= Html.ValidationSummary("Restore a database backup") %> +<% using (Html.BeginForm("Restore","BackOffice")) { %> + +<% string [] bckdirs = Model.GetBackupDirs(); %> + + +<%= Html.CheckBox("dataOnly")%> + +<%= Html.LabelFor(model => model.Host) %>: +<%= Html.TextBox( "Host" ) %> +<%= Html.ValidationMessage("Host", "*") %>
    +<%= Html.LabelFor(model => model.Port) %>: +<%= Html.TextBox( "Port" ) %> +<%= Html.ValidationMessage("Port", "*") %>
    +<%= Html.LabelFor(model => model.Dbname) %>: +<%= Html.TextBox( "Dbname" ) %> +<%= Html.ValidationMessage("Dbname", "*") %>
    +<%= Html.LabelFor(model => model.Dbuser) %>: +<%= Html.TextBox( "Dbuser" ) %> +<%= Html.ValidationMessage("Dbuser", "*") %>
    +<%= Html.LabelFor(model => model.Password) %>: +<%= Html.Password( "Password" ) %> +<%= Html.ValidationMessage("Password", "*") %>
    + + +<% } %> +
    diff --git a/web/Views/BackOffice/Restored.aspx b/web/Views/BackOffice/Restored.aspx new file mode 100644 index 00000000..cb320315 --- /dev/null +++ b/web/Views/BackOffice/Restored.aspx @@ -0,0 +1,12 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + +

    <%=Html.Encode(ViewData["BackupName"])%> Restauration

    +

    Error message

    <%= Html.Encode(Model.Error) %>
    +

    Message

    <%= Html.Encode(Model.Message) %>
    +

    Exit Code

    <%= Html.Encode(Model.ExitCode) %>
    + +
    diff --git a/web/Views/Blogs/Edit.aspx b/web/Views/Blogs/Edit.aspx new file mode 100644 index 00000000..da110bf5 --- /dev/null +++ b/web/Views/Blogs/Edit.aspx @@ -0,0 +1,67 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + + <%= Html.Encode(ViewData["BlogTitle"]) %> edition + - <%=Html.Encode(YavscHelpers.SiteName) %> + + + + +

    + "> + " alt="from <%=ViewData["UserName"]%>"/> + <%= Html.Encode(ViewData["BlogTitle"]) %> - + <%= Html.Encode(Model.Title) %> - + Édition

    + + + +
    + <%= Html.Encode(ViewData["Message"]) %> +
    +
    + + + +<% if (Model != null ) if (Model.Content != null ) { + BBCodeHelper.Init (); %> + <%= Html.ActionLink(Model.Title,"UserPost",new{user=Model.UserName,title=Model.Title}) %> +
    +<%= BBCodeHelper.Parser.ToHtml(Model.Content) %> +
    +<% } %> +Usage BBcodes : +
    +<% + foreach (string usage in BBCodeHelper.BBTagsUsage) { %> +
    <%= usage %>
    +<% } %> +
    + +<%= Html.ValidationSummary("Edition du billet") %> + +<% using(Html.BeginForm("ValidateEdit", "Blogs")) { %> +<%= Html.LabelFor(model => model.Title) %>:
    +<%= Html.TextBox( "Title" ) %> +<%= Html.ValidationMessage("Title", "*") %> +
    +<%= Html.LabelFor(model => model.Content) %>:
    +<%= Html.TextArea( "Content" , new { @class="editblog", @rows="15" }) %> +<%= Html.ValidationMessage("Content", "*") %> +
    +<%= Html.CheckBox( "Visible" ) %> +<%= Html.LabelFor(model => model.Visible) %> +<%= Html.ValidationMessage("Visible", "*") %> +
    +<%= Html.CheckBox( "Preview" ) %> +<%= Html.LabelFor(model => model.Preview) %> +<%= Html.ValidationMessage("Preview", "*") %> + <%= Html.Hidden("Id") %> + <%= Html.Hidden("UserName") %> + +
    + +<% } %> + + +
    + diff --git a/web/Views/Blogs/Error.aspx b/web/Views/Blogs/Error.aspx new file mode 100644 index 00000000..e49602ac --- /dev/null +++ b/web/Views/Blogs/Error.aspx @@ -0,0 +1,14 @@ +<%@ Page Title="Comptes utilisateur - Index" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    Comptes utilisteur

    +
    + + +
    +<%= Html.Encode(ViewData["Message"]) %>
    +Your UID : +<%= Html.Encode(ViewData ["UID"]) %>
    +">Retour +
    diff --git a/web/Views/Blogs/Index.aspx b/web/Views/Blogs/Index.aspx new file mode 100644 index 00000000..9f262830 --- /dev/null +++ b/web/Views/Blogs/Index.aspx @@ -0,0 +1,34 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> + + <%= "Les dernières parutions - " + Html.Encode(YavscHelpers.SiteName) + "" %> + + +

    Les dernières parutions

    +
    + + +<% foreach (Npgsql.Web.Blog.DataModel.BlogEntry e in this.Model) { %> +
    +

    +<%= Html.ActionLink(e.Title,"UserPost", new { user=e.UserName, title = e.Title }) %> +

    +
    (<%=Html.Encode(e.UserName)%> <%=e.Modified.ToString("yyyy/MM/dd") %>)
    +<% if (Membership.GetUser()!=null) + if (Membership.GetUser().UserName==e.UserName) + { %> + <%= Html.ActionLink("Editer","Edit", new { user = e.UserName, title = e.Title }, new { @class="actionlink" }) %> + <%= Html.ActionLink("Supprimer","Remove", new { user = e.UserName, title = e.Title }, new { @class="actionlink" } ) %> + <% } %> + +
    + +<% } %> +
    + <% rp1.ResultCount = (int) ViewData["RecordCount"]; + rp1.CurrentPage = (int) ViewData["PageIndex"]; %> + + +
    +
    + diff --git a/web/Views/Blogs/Post.aspx b/web/Views/Blogs/Post.aspx new file mode 100644 index 00000000..b8cd1e39 --- /dev/null +++ b/web/Views/Blogs/Post.aspx @@ -0,0 +1,67 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + + <%= Html.Encode(ViewData["BlogTitle"]) %> - Nouveau billet + - <%=Html.Encode(YavscHelpers.SiteName) %> + + + +

    + "> + " alt="from <%=ViewData["UserName"]%>"/> + <%= Html.Encode(ViewData["BlogTitle"]) %> - +Nouveau billet - +<%= Html.Encode(YavscHelpers.SiteName) %>

    + +
    + <%= Html.Encode(ViewData["Message"]) %> +
    +
    + + +
    + <%= Html.Encode(ViewData["Message"]) %> +
    + <% if (Model != null ) if (Model.Content != null ) { %> +
    +<%= BBCodeHelper.Parser.ToHtml(Model.Content) %> +
    +<% } %> +
    + + +<%= Html.ValidationSummary() %> +<% using(Html.BeginForm("ValidatePost", "Blogs")) %> +<% { %> + +<%= Html.LabelFor(model => model.Title) %>:
    +<%= Html.TextBox( "Title" ) %> +<%= Html.ValidationMessage("Title", "*") %> +
    +
    + Usage BBcodes : +
      +<% + foreach (string usage in BBCodeHelper.BBTagsUsage) { %> +
    • <%= usage %>
    • +<% } %> +
    + +
    +<%= Html.LabelFor(model => model.Content) %>:
    +<%= Html.TextArea( "Content", new { @class="editblog", @rows="15" }) %> +<%= Html.ValidationMessage("Content", "*") %> +
    +<%= Html.CheckBox( "Visible" ) %> +<%= Html.LabelFor(model => model.Visible) %> +<%= Html.ValidationMessage("Visible", "*") %> +
    +<%= Html.CheckBox( "Preview" ) %> <%= Html.LabelFor(model => model.Preview) %> +<%= Html.ValidationMessage("Preview", "*") %> +
    + <%= Html.Hidden("Id") %> + +<% } %> + +
    +
    + diff --git a/web/Views/Blogs/TitleNotFound.aspx b/web/Views/Blogs/TitleNotFound.aspx new file mode 100644 index 00000000..4aa369a4 --- /dev/null +++ b/web/Views/Blogs/TitleNotFound.aspx @@ -0,0 +1,17 @@ + +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + + + + + + + + Pas d'article trouvé @ "<%= Html.Encode(ViewData["PostTitle"]) %>" + <% if (ViewData["UserName"]!=null) { %> + +
    + <%= Html.ActionLink("Poster?","Post/", new { user=ViewData["UserName"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %> + <% } %> +
    + diff --git a/web/Views/Blogs/UserPost.aspx b/web/Views/Blogs/UserPost.aspx new file mode 100644 index 00000000..f8b4a188 --- /dev/null +++ b/web/Views/Blogs/UserPost.aspx @@ -0,0 +1,47 @@ +<%@ Page Title="Billet" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +<%=Html.Encode(Model.Title)%> - <%=Html.Encode(ViewData["BlogTitle"])%> + +

    <%= Html.ActionLink(Model.Title,"UserPost",new{user=Model.UserName,title=Model.Title}) %> - + <%=ViewData["BlogTitle"]%>

    + +
    (Id:<%=Model.Id%>, <%= Model.Posted.ToString("yyyy/MM/dd") %> + - <%= Model.Modified.ToString("yyyy/MM/dd") %> <%= Model.Visible? "":", Invisible!" %>) +<% if (Membership.GetUser()!=null) + if (Membership.GetUser().UserName==Model.UserName) + { %> + <%= Html.ActionLink("Editer","Edit", new { user=Model.UserName, title = Model.Title }, new { @class="actionlink" }) %> + <%= Html.ActionLink("Supprimer","Remove", new { user=Model.UserName, title = Model.Title }, new { @class="actionlink" } ) %> + <% } %> +
    +
    + +
    +
    + <% BBCodeHelper.Init(); %> +<%= BBCodeHelper.Parser.ToHtml(Model.Content) %> +
    + <% + string username = ""; + if (Membership.GetUser()!=null) + username = Membership.GetUser().UserName; %> + +<% foreach (var c in (Comment[])ViewData["Comments"]) { %> + +
    <%=c.From%> +<%= BBCodeHelper.Parser.ToHtml(c.CommentText) %> + <% if ( username == Model.UserName || c.From == username ) { %> + <%= Html.ActionLink("Supprimer","RemoveComment", new { cmtid = c.Id } )%> + <% } %> +
    +<% } %> +
    + <% using (Html.BeginForm("Comment","Blogs")) { %> + <%=Html.Hidden("UserName")%> + <%=Html.Hidden("Title")%> + <%=Html.TextArea("CommentText","")%> + <%=Html.Hidden("PostId",Model.Id)%> + + <% } %> +
    +
    +
    diff --git a/web/Views/Blogs/UserPosts.aspx b/web/Views/Blogs/UserPosts.aspx new file mode 100644 index 00000000..30809c65 --- /dev/null +++ b/web/Views/Blogs/UserPosts.aspx @@ -0,0 +1,42 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %> +<%=Html.Encode(ViewData["BlogTitle"])%> + +

    "> + " alt=""/> + <%=ViewData["BlogTitle"]%>

    +
    <%= Html.Encode(ViewData["Message"])%>
    +
    + + +<% + foreach (BlogEntry e in this.Model) { %> +
    style="background-color:#022;" <% } %>> + +

    <%= Html.ActionLink(e.Title,"UserPost", new { user=e.UserName, title = e.Title }) %>

    +
    (<%= e.Posted.ToString("yyyy/MM/dd") %> + - <%= e.Modified.ToString("yyyy/MM/dd") %> <%= e.Visible? "":", Invisible!" %>) +
    +<% if (Membership.GetUser()!=null) + if (Membership.GetUser().UserName==e.UserName) + { %> + <%= Html.ActionLink("Editer","Edit", new { user = e.UserName, title = e.Title }, new { @class="actionlink" }) %> + <%= Html.ActionLink("Supprimer","Remove", new { user = e.UserName, title = e.Title }, new { @class="actionlink" } ) %> + <% } %> +
    +<% } %> + +
    + <% + rp1.ResultCount = (int) ViewData["RecordCount"]; + rp1.CurrentPage = (int) ViewData["PageIndex"]; + user.Value = (string) ViewData["BlogUser"]; + +%> + + + +
    + + +
    \ No newline at end of file diff --git a/web/Views/FileSystem/Create.aspx b/web/Views/FileSystem/Create.aspx new file mode 100644 index 00000000..c994d646 --- /dev/null +++ b/web/Views/FileSystem/Create.aspx @@ -0,0 +1,20 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + +<% using(Html.BeginForm("Create", "FileSystem", FormMethod.Post, new { enctype = "multipart/form-data" })) { %> +
    + + + <%= Html.ValidationMessage("AFile") %> + +
    + + + +
    + + +
    + <% } %> +
    diff --git a/web/Views/FileSystem/Delete.aspx b/web/Views/FileSystem/Delete.aspx new file mode 100644 index 00000000..e6c14b90 --- /dev/null +++ b/web/Views/FileSystem/Delete.aspx @@ -0,0 +1,7 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + diff --git a/web/Views/FileSystem/Details.aspx b/web/Views/FileSystem/Details.aspx new file mode 100644 index 00000000..79bec8b3 --- /dev/null +++ b/web/Views/FileSystem/Details.aspx @@ -0,0 +1,15 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + +<%= Model.Name %>
    +Création : +<%= Model.CreationTime %>
    +Dérnière modification : +<%= Model.LastWriteTime %>
    +Dernier accès : +<%= Model.LastAccessTime %>
    +Lien permanent : ">/<%= ViewData["Content"] %> +
    diff --git a/web/Views/FileSystem/Edit.aspx b/web/Views/FileSystem/Edit.aspx new file mode 100644 index 00000000..4e92b60b --- /dev/null +++ b/web/Views/FileSystem/Edit.aspx @@ -0,0 +1,9 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + +<%= Html.ActionLink("Delete","FileSystem") %> +<%= Html.ActionLink("Rename","FileSystem") %> + diff --git a/web/Views/FileSystem/Index.aspx b/web/Views/FileSystem/Index.aspx new file mode 100644 index 00000000..345305d4 --- /dev/null +++ b/web/Views/FileSystem/Index.aspx @@ -0,0 +1,16 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + +

    Index of <%=ViewData["UserName"] %>'s files (<%= Html.Encode(Model.Count) %>)

    +
      +<% foreach (System.IO.FileInfo fi in Model) { %> +
    • <%= Html.ActionLink(fi.Name,"Details",new {id = fi.Name}) %>
    • +<% } %> +
    + +<%= Html.ActionLink("Ajouter des fichiers","Create") %> +
    diff --git a/web/Views/FrontOffice/Brand.aspx b/web/Views/FrontOffice/Brand.aspx new file mode 100644 index 00000000..a1177ab8 --- /dev/null +++ b/web/Views/FrontOffice/Brand.aspx @@ -0,0 +1,32 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +

    <% if (Model.Logo!=null) { %> + <%=Model.Logo.Alt%> + <% } %> + <%=Html.Encode(Model.Name)%>

    +

    <%=Html.Encode(Model.Slogan)%>

    +
    + +<% foreach (ProductCategory pc in Model.Categories ) { %> +
    +

    <%= Html.ActionLink( pc.Name, "ProductCategory", new { id = Model.Name, pc = pc.Reference }, new { @class="actionlink" } ) %>

    +
    + + <% foreach (Product p in pc.Products ) { %> +
    +

    <%= Html.ActionLink( p.Name, "Product", new { id = Model.Name, pc = pc.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

    +

    + <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

    +
    +<% } %> +<% } %> + + +
    diff --git a/web/Views/FrontOffice/Catalog.aspx b/web/Views/FrontOffice/Catalog.aspx new file mode 100644 index 00000000..fdc51f15 --- /dev/null +++ b/web/Views/FrontOffice/Catalog.aspx @@ -0,0 +1,32 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + + + +<% foreach (Brand b in Model.Brands ) { %>
    +

    <%= Html.ActionLink( b.Name, "Brand", new { id = b.Name }, new { @class="actionlink" } ) %>

    +

    <%= Html.Encode( b.Slogan ) %>

    + <% foreach (ProductCategory pc in b.Categories ) { %> +
    +

    <%= Html.ActionLink( pc.Name, "ProductCategory", new { id = b.Name, pc = pc.Reference }, new { @class="actionlink" } ) %>

    +
    + + <% foreach (Product p in pc.Products ) { %> +
    +

    <%= Html.ActionLink( p.Name, "Product", new { id = b.Name, pc = pc.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

    +

    + <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

    +
    +<% } %> +<% } %> +
    <% } %> +
    + + diff --git a/web/Views/FrontOffice/Command.aspx b/web/Views/FrontOffice/Command.aspx new file mode 100644 index 00000000..65933f74 --- /dev/null +++ b/web/Views/FrontOffice/Command.aspx @@ -0,0 +1,7 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + diff --git a/web/Views/FrontOffice/Product.aspx b/web/Views/FrontOffice/Product.aspx new file mode 100644 index 00000000..0aeb5a48 --- /dev/null +++ b/web/Views/FrontOffice/Product.aspx @@ -0,0 +1,30 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +<%= Html.Encode(Model.Name) %> + + +

    <%= Html.Encode(Model.Name) %>

    +<%= Html.Encode(Model.Reference) %>
    + +
    +

    <%= Html.Encode(Model.Description) %>

    +<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %> +<%=i.Alt%> +<% } %> +<% if (Model.UnitaryPrice !=null) { %> +Prix unitaire : <%= Html.Encode(Model.UnitaryPrice.Quantity.ToString())%> +<%= Html.Encode(Model.UnitaryPrice.Unit.Name)%> +<% } else { %> Gratuit! <% } %> +
    +
    +<% if (Model.CommandForm!=null) { %> +Défaut de formulaire de commande!!! +<% } else { Response.Write( Html.CommandForm(Model,"Ajouter au panier")); } %> + +<% if (Model.CommandValidityDates!=null) { %> +Offre valable du <%= Model.CommandValidityDates.StartDate.ToString("dd/MM/yyyy") %> au +<%= Model.CommandValidityDates.EndDate.ToString("dd/MM/yyyy") %>. +<% } %> + +
    +
    diff --git a/web/Views/FrontOffice/ProductCategory.aspx b/web/Views/FrontOffice/ProductCategory.aspx new file mode 100644 index 00000000..063a6365 --- /dev/null +++ b/web/Views/FrontOffice/ProductCategory.aspx @@ -0,0 +1,23 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + + + +<% foreach (Product p in Model.Products ) { %> + +

    <%= Html.ActionLink( p.Name, "Product", new { id = ViewData["BrandName"], pc = Model.Reference , pref = p.Reference }, new { @class="actionlink" } ) %>

    + +

    + <%= p.Description %> + <% if (p.Images !=null) + foreach (ProductImage i in p.Images ) { %> + <%=i.Alt%> + <% } %> +

    + + + <% } %> + + +
    diff --git a/web/Views/FrontOffice/ReferenceNotFound.aspx b/web/Views/FrontOffice/ReferenceNotFound.aspx new file mode 100644 index 00000000..e6c14b90 --- /dev/null +++ b/web/Views/FrontOffice/ReferenceNotFound.aspx @@ -0,0 +1,7 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + diff --git a/web/Views/FrontOffice/Service.aspx b/web/Views/FrontOffice/Service.aspx new file mode 100644 index 00000000..d61c5e19 --- /dev/null +++ b/web/Views/FrontOffice/Service.aspx @@ -0,0 +1,31 @@ +<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + +<%= Html.Encode(Model.Name) %> + + +

    <%=ViewData ["BrandName"]%> - <%=ViewData ["ProdCatName"]%> - <%= Html.ActionLink( Model.Name, "Product", new { id = ViewData ["BrandName"], pc = ViewData ["ProdCatRef"] , pref = Model.Reference } ) %>

    + +
    + +
    +

    <%= Html.Encode(Model.Description) %>

    +<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %> +<%=i.Alt%> +<% } %> +<% if (Model.HourPrice !=null) { %> +Prix horaire de la prestation : +<%= Html.Encode(Model.HourPrice.Quantity.ToString())%> +<%= Html.Encode(Model.HourPrice.Unit.Name)%> +<% } %> +
    + +
    +<%= Html.CommandForm(Model,"Ajouter au panier") %> + +<% if (Model.CommandValidityDates!=null) { %> +Offre valable du <%= Model.CommandValidityDates.StartDate.ToString("dd/MM/yyyy") %> au +<%= Model.CommandValidityDates.EndDate.ToString("dd/MM/yyyy") %>. +<% } %> + +
    +
    diff --git a/web/Views/Home/AOEMail.aspx b/web/Views/Home/AOEMail.aspx new file mode 100644 index 00000000..e6c14b90 --- /dev/null +++ b/web/Views/Home/AOEMail.aspx @@ -0,0 +1,7 @@ +<%@ Page Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + diff --git a/web/Views/Home/Index.aspx b/web/Views/Home/Index.aspx new file mode 100644 index 00000000..c25d9f59 --- /dev/null +++ b/web/Views/Home/Index.aspx @@ -0,0 +1,8 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> +Indexe + +
    +<%= Html.ActionLink("blogs","Index","Blogs") %> +
    +
    + diff --git a/web/Views/Home/NCView.aspx b/web/Views/Home/NCView.aspx new file mode 100644 index 00000000..7f7a81d1 --- /dev/null +++ b/web/Views/Home/NCView.aspx @@ -0,0 +1,3 @@ +<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="" %> + + diff --git a/web/Views/Home/NView.aspx b/web/Views/Home/NView.aspx new file mode 100644 index 00000000..37fe01d5 --- /dev/null +++ b/web/Views/Home/NView.aspx @@ -0,0 +1,12 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %> + + + + + + +
    + +
    + + diff --git a/web/Views/Home/Thanks.ascx b/web/Views/Home/Thanks.ascx new file mode 100644 index 00000000..11b0f5d6 --- /dev/null +++ b/web/Views/Home/Thanks.ascx @@ -0,0 +1,17 @@ +<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +

    + <% var ts = ((string[,])ViewData["Thanks"]); + if (ts != null) { %> +


    Powered by
    + <% for (int i = 0; i <= ts.GetUpperBound(0); i++) + { + + %> + <%= "" + + ts[i,0]+"" + %> + <% + }} + %> +

    + diff --git a/web/Views/RegisterPage.cs b/web/Views/RegisterPage.cs new file mode 100644 index 00000000..7215e9f5 --- /dev/null +++ b/web/Views/RegisterPage.cs @@ -0,0 +1,28 @@ +using System; +using System.Web.UI.WebControls; +using yavscModel.RolesAndMembers; + + +namespace Yavsc +{ + public class RegisterPage : System.Web.Mvc.ViewPage + { + public RegisterPage () + { + } + + public CreateUserWizard Createuserwizard1; + + public void OnRegisterSendMail(object sender, MailMessageEventArgs e) + { + // Set MailMessage fields. + e.Message.IsBodyHtml = false; + e.Message.Subject = "New user on Web site."; + // Replace placeholder text in message body with information + // provided by the user. + e.Message.Body = e.Message.Body.Replace("<%PasswordQuestion%>", Createuserwizard1.Question); + e.Message.Body = e.Message.Body.Replace("<%PasswordAnswer%>", Createuserwizard1.Answer); +} + } +} + diff --git a/web/Views/Web.config b/web/Views/Web.config new file mode 100644 index 00000000..065b867b --- /dev/null +++ b/web/Views/Web.config @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/Views/WorkFlow/Index.aspx b/web/Views/WorkFlow/Index.aspx new file mode 100644 index 00000000..dd7860b9 --- /dev/null +++ b/web/Views/WorkFlow/Index.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master"%> + + <%= "Index - " + Html.Encode(YavscHelpers.SiteName) + "" %> + + +
    +<%= Html.ActionLink("blogs","Index","WorkFlow") %> +
    + +
    + diff --git a/web/Views/WorkFlow/NewProject.aspx b/web/Views/WorkFlow/NewProject.aspx new file mode 100644 index 00000000..7ae525e7 --- /dev/null +++ b/web/Views/WorkFlow/NewProject.aspx @@ -0,0 +1,22 @@ +<%@ Page Title="Nouveau projet" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %> + + + +
    +<%= Html.ValidationSummary("Nouveau projet") %> +<% using ( Html.BeginForm("NewProject", "WorkFlow") ) { %> +<%= Html.LabelFor(model => model.Name) %> : +<%= Html.TextBox( "Name" ) %> +<%= Html.ValidationMessage("Name", "*") %>
    +<%= Html.LabelFor(model => model.Manager) %> : +<%= Html.TextBox( "Manager" ) %> +<%= Html.ValidationMessage("Manager", "*") %>
    +<%= Html.LabelFor(model => model.Description) %> : +<%= Html.TextBox( "Description" ) %> +<%= Html.ValidationMessage("Description", "*") %>
    + +<% } %> +
    +
    + + diff --git a/web/Web.config b/web/Web.config new file mode 100644 index 00000000..b5fe46e4 --- /dev/null +++ b/web/Web.config @@ -0,0 +1,215 @@ + + + + + + +
    + +
    +
    +
    +
    + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/Web.csproj b/web/Web.csproj new file mode 100644 index 00000000..25f1c718 --- /dev/null +++ b/web/Web.csproj @@ -0,0 +1,260 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {77044C92-D2F1-45BD-80DD-AA25B311B027} + {349C5851-65DF-11DA-9384-00065B846F21};{603C0E0B-DB56-11DC-BE95-000D561079B0};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Yavsc + v4.5 + + + true + full + false + bin + DEBUG;TEST + prompt + 4 + false + + + + Yavsc + true + + + none + true + bin + prompt + 4 + false + Yavsc + true + + + false + bin + DEBUG,TEST,WEBAPI + 4 + maeweb + true + + + + + + + + + + + + + + + + + + + + + False + + + lib\CodeKicker.BBCode.dll + + + False + + + False + + + + + + + + False + monodevelop + + + ..\..\..\..\..\usr\lib\mono\4.5\System.Web.Http.WebHost.dll + False + + + + + False + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + Global.asax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {BBA7175D-7F92-4278-96FC-84C495A2B5A6} + NpgsqlMRPProviders + + + {C6E9E91B-97D3-48D9-8AA7-05356929E162} + NpgsqlBlogProvider + + + {90BF2234-7252-4CD5-B2A4-17501B19279B} + SalesCatalog + + + {821FF72D-9F4B-4A2C-B95C-7B965291F119} + WorkFlowProvider + + + {68F5B80A-616E-4C3C-91A0-828AA40000BD} + yavscModel + + + {59E1DF7B-FFA0-4DEB-B5F3-76EBD98D5356} + WebControls + + + diff --git a/web/WebDeploy.targets b/web/WebDeploy.targets new file mode 100644 index 00000000..43660ada --- /dev/null +++ b/web/WebDeploy.targets @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrorPages.sln b/web/errors/CustomErrorPages/CustomErrorPages.sln new file mode 100644 index 00000000..b4fe3c23 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrorPages.sln @@ -0,0 +1,9 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + EndGlobalSection +EndGlobal diff --git a/web/errors/CustomErrorPages/CustomErrorPages.userprefs b/web/errors/CustomErrorPages/CustomErrorPages.userprefs new file mode 100644 index 00000000..aa4d9b8b --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrorPages.userprefs @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web/errors/CustomErrorPages/CustomErrors1/AssemblyInfo.cs b/web/errors/CustomErrorPages/CustomErrors1/AssemblyInfo.cs new file mode 100644 index 00000000..cced87bf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/AssemblyInfo.cs @@ -0,0 +1,62 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the "project output directory". The location of the project output +// directory is dependent on whether you are working with a local or web project. +// For local projects, the project output directory is defined as +// \obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// For web projects, the project output directory is defined as +// %HOMEPATH%\VSWebCache\\\obj\. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/web/errors/CustomErrorPages/CustomErrors1/CustomErrors1.csproj b/web/errors/CustomErrorPages/CustomErrors1/CustomErrors1.csproj new file mode 100644 index 00000000..64572a63 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/CustomErrors1.csproj @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors1/Default.aspx b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx new file mode 100644 index 00000000..777ee40d --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx @@ -0,0 +1,11 @@ +<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors1._Default" %> + + + + Default page + + +
    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.cs b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.cs new file mode 100644 index 00000000..d0775ca6 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.cs @@ -0,0 +1,41 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors1 +{ + /// + /// Summary description for _Default. + /// + public class _Default : PageBase + { + private void Page_Load (object sender, System.EventArgs e) + { + // ------------------------------------------------------ + // No one is sane mind would throw an exception just for + // the heck of it, but for demonstration purposes this + // should work. + // ------------------------------------------------------ + throw new Exception ("Silly exception"); + } + + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.resx b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.resx new file mode 100644 index 00000000..7f99b555 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Default.aspx.resx @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + Private + + + False + + \ No newline at end of file diff --git a/web/errors/CustomErrorPages/CustomErrors1/Global.asax b/web/errors/CustomErrorPages/CustomErrors1/Global.asax new file mode 100644 index 00000000..2fc937da --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="CustomErrors1.Global" %> diff --git a/web/errors/CustomErrorPages/CustomErrors1/Global.asax.cs b/web/errors/CustomErrorPages/CustomErrors1/Global.asax.cs new file mode 100644 index 00000000..d5da8f54 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Global.asax.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Web; +using System.Web.SessionState; + +namespace CustomErrors1 +{ + /// + /// Summary description for Global. + /// + public class Global : System.Web.HttpApplication + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + public Global() + { + InitializeComponent(); + } + + protected void Application_Start(Object sender, EventArgs e) + { + + } + + protected void Session_Start(Object sender, EventArgs e) + { + + } + + protected void Application_BeginRequest(Object sender, EventArgs e) + { + + } + + protected void Application_EndRequest(Object sender, EventArgs e) + { + + } + + protected void Application_AuthenticateRequest(Object sender, EventArgs e) + { + + } + + protected void Application_Error(Object sender, EventArgs e) + { + + } + + protected void Session_End(Object sender, EventArgs e) + { + + } + + protected void Application_End(Object sender, EventArgs e) + { + + } + + #region Web Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + } + #endregion + } +} + diff --git a/web/errors/CustomErrorPages/CustomErrors1/Global.asax.resx b/web/errors/CustomErrorPages/CustomErrors1/Global.asax.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Global.asax.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors1/PageBase.cs b/web/errors/CustomErrorPages/CustomErrors1/PageBase.cs new file mode 100644 index 00000000..1102ad8b --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/PageBase.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; +using System.Web.UI; + +namespace AspNetResources.CustomErrors1 +{ + public class PageBase : System.Web.UI.Page + { + protected override void OnError(EventArgs e) + { + // At this point we have information about the error + HttpContext ctx = HttpContext.Current; + + Exception exception = ctx.Server.GetLastError (); + + string errorInfo = "
    Offending URL: " + ctx.Request.Url.ToString () + + "
    Source: " + exception.Source + + "
    Message: " + exception.Message + + "
    Stack trace: " + exception.StackTrace; + + ctx.Response.Write (errorInfo); + + // -------------------------------------------------- + // To let the page finish running we clear the error + // -------------------------------------------------- + ctx.Server.ClearError (); + + base.OnError (e); + } + + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors1/Web.config b/web/errors/CustomErrorPages/CustomErrors1/Web.config new file mode 100644 index 00000000..43f74faf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors1/Web.config @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors2/AssemblyInfo.cs b/web/errors/CustomErrorPages/CustomErrors2/AssemblyInfo.cs new file mode 100644 index 00000000..cced87bf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/AssemblyInfo.cs @@ -0,0 +1,62 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the "project output directory". The location of the project output +// directory is dependent on whether you are working with a local or web project. +// For local projects, the project output directory is defined as +// \obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// For web projects, the project output directory is defined as +// %HOMEPATH%\VSWebCache\\\obj\. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/web/errors/CustomErrorPages/CustomErrors2/CustomErrors2.csproj b/web/errors/CustomErrorPages/CustomErrors2/CustomErrors2.csproj new file mode 100644 index 00000000..295fbe9c --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/CustomErrors2.csproj @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors2/Default.aspx b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx new file mode 100644 index 00000000..3e402345 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx @@ -0,0 +1,12 @@ +<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors2._Default" %> + + + + Default + + +
    + +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.cs b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.cs new file mode 100644 index 00000000..f1233611 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.cs @@ -0,0 +1,39 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors2 +{ + /// + /// Summary description for _Default. + /// + public class _Default : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // ------------------------------------------------------ + // No one is sane mind would throw an exception just for + // the heck of it, but for demonstration purposes this + // should work. Your event handler in Global.asax will + // catch the exception. + // ------------------------------------------------------ + throw new Exception ("Silly exception"); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.resx b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Default.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors2/Global.asax b/web/errors/CustomErrorPages/CustomErrors2/Global.asax new file mode 100644 index 00000000..50b4978e --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="CustomErrors2.Global" %> diff --git a/web/errors/CustomErrorPages/CustomErrors2/Global.asax.cs b/web/errors/CustomErrorPages/CustomErrors2/Global.asax.cs new file mode 100644 index 00000000..36f66bed --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Global.asax.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Web; +using System.Web.SessionState; + +namespace CustomErrors2 +{ + /// + /// Summary description for Global. + /// + public class Global : System.Web.HttpApplication + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + public Global() + { + InitializeComponent(); + } + + protected void Application_Start(Object sender, EventArgs e) + { + + } + + protected void Session_Start(Object sender, EventArgs e) + { + + } + + protected void Application_BeginRequest(Object sender, EventArgs e) + { + + } + + protected void Application_EndRequest(Object sender, EventArgs e) + { + + } + + protected void Application_AuthenticateRequest(Object sender, EventArgs e) + { + + } + + protected void Application_Error(Object sender, EventArgs e) + { + // At this point we have information about the error + HttpContext ctx = HttpContext.Current; + + Exception exception = ctx.Server.GetLastError (); + + string errorInfo = "
    Offending URL: " + ctx.Request.Url.ToString () + + "
    Source: " + exception.Source + + "
    Message: " + exception.Message + + "
    Stack trace: " + exception.StackTrace; + + ctx.Response.Write (errorInfo); + + // -------------------------------------------------- + // To let the page finish running we clear the error + // -------------------------------------------------- + ctx.Server.ClearError (); + } + + protected void Session_End(Object sender, EventArgs e) + { + + } + + protected void Application_End(Object sender, EventArgs e) + { + + } + + #region Web Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + } + #endregion + } +} + diff --git a/web/errors/CustomErrorPages/CustomErrors2/Global.asax.resx b/web/errors/CustomErrorPages/CustomErrors2/Global.asax.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Global.asax.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors2/Web.config b/web/errors/CustomErrorPages/CustomErrors2/Web.config new file mode 100644 index 00000000..43f74faf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors2/Web.config @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/AssemblyInfo.cs b/web/errors/CustomErrorPages/CustomErrors3/AssemblyInfo.cs new file mode 100644 index 00000000..cced87bf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/AssemblyInfo.cs @@ -0,0 +1,62 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the "project output directory". The location of the project output +// directory is dependent on whether you are working with a local or web project. +// For local projects, the project output directory is defined as +// \obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// For web projects, the project output directory is defined as +// %HOMEPATH%\VSWebCache\\\obj\. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/web/errors/CustomErrorPages/CustomErrors3/CustomErrors3.csproj b/web/errors/CustomErrorPages/CustomErrors3/CustomErrors3.csproj new file mode 100644 index 00000000..22676070 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/CustomErrors3.csproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/Default.aspx b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx new file mode 100644 index 00000000..974aba6f --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx @@ -0,0 +1,17 @@ +<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors3._Default" %> + + + + Default + + +
    +

    To see custom error pages +

      +
    1. request a page that doesn't exist, eg: test.aspx, or
    2. +
    3. uncomment the code in Page_OnLoad and let it throw an exception
    4. +
    +

    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.cs b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.cs new file mode 100644 index 00000000..7d71806e --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.cs @@ -0,0 +1,39 @@ +using System; +using System.Web; +using System.Web.UI; + +namespace AspNetResources.CustomErrors3 +{ + /// + /// Summary description for _Default. + /// + public class _Default : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // ------------------------------------------------------ + // No one is sane mind would throw an exception just for + // the heck of it, but for demonstration purposes this + // should work. + // ------------------------------------------------------ + // throw new Exception ("Silly exception"); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.resx b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Default.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/Global.asax b/web/errors/CustomErrorPages/CustomErrors3/Global.asax new file mode 100644 index 00000000..611e4d65 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="CustomErrors3.Global" %> diff --git a/web/errors/CustomErrorPages/CustomErrors3/Global.asax.cs b/web/errors/CustomErrorPages/CustomErrors3/Global.asax.cs new file mode 100644 index 00000000..39f4149f --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Global.asax.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Web; +using System.Web.SessionState; + +namespace CustomErrors3 +{ + /// + /// Summary description for Global. + /// + public class Global : System.Web.HttpApplication + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + public Global() + { + InitializeComponent(); + } + + protected void Application_Start(Object sender, EventArgs e) + { + + } + + protected void Session_Start(Object sender, EventArgs e) + { + + } + + protected void Application_BeginRequest(Object sender, EventArgs e) + { + + } + + protected void Application_EndRequest(Object sender, EventArgs e) + { + + } + + protected void Application_AuthenticateRequest(Object sender, EventArgs e) + { + + } + + protected void Application_Error(Object sender, EventArgs e) + { + + } + + protected void Session_End(Object sender, EventArgs e) + { + + } + + protected void Application_End(Object sender, EventArgs e) + { + + } + + #region Web Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + } + #endregion + } +} + diff --git a/web/errors/CustomErrorPages/CustomErrors3/Global.asax.resx b/web/errors/CustomErrorPages/CustomErrors3/Global.asax.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Global.asax.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/Web.config b/web/errors/CustomErrorPages/CustomErrors3/Web.config new file mode 100644 index 00000000..765207b5 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/Web.config @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx new file mode 100644 index 00000000..8e6f7b25 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" Codebehind="GeneralError.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors3.GeneralError" %> + + + + Server error + + +
    +

    Sorry

    +

    The server is experiencing a problem with the page you requested. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.cs b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.cs new file mode 100644 index 00000000..247d0184 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors3 +{ + /// + /// Summary description for GeneralError. + /// + public class GeneralError : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.resx b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.resx new file mode 100644 index 00000000..97063148 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/GeneralError.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms9 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Culture=neutral + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx new file mode 100644 index 00000000..51c96687 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" Codebehind="PageNotFound.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors3.PageNotFound" %> + + + + PageNotFound + + +
    +

    Sorry

    +

    We cannot find the page you are looking for. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.cs b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.cs new file mode 100644 index 00000000..0a2abb1f --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors3 +{ + /// + /// Summary description for PageNotFound. + /// + public class PageNotFound : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.resx b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.resx new file mode 100644 index 00000000..3f337e08 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors3/errors/PageNotFound.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/AssemblyInfo.cs b/web/errors/CustomErrorPages/CustomErrors4/AssemblyInfo.cs new file mode 100644 index 00000000..cced87bf --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/AssemblyInfo.cs @@ -0,0 +1,62 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the "project output directory". The location of the project output +// directory is dependent on whether you are working with a local or web project. +// For local projects, the project output directory is defined as +// \obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// For web projects, the project output directory is defined as +// %HOMEPATH%\VSWebCache\\\obj\. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/web/errors/CustomErrorPages/CustomErrors4/CustomErrors4.csproj b/web/errors/CustomErrorPages/CustomErrors4/CustomErrors4.csproj new file mode 100644 index 00000000..3ef63f47 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/CustomErrors4.csproj @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/Default.aspx b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx new file mode 100644 index 00000000..839f3fac --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx @@ -0,0 +1,11 @@ +<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors4._Default" %> + + + + WebForm1 + + +
    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.cs b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.cs new file mode 100644 index 00000000..8ed47d66 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.cs @@ -0,0 +1,40 @@ +using System; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; + +namespace AspNetResources.CustomErrors4 +{ + /// + /// Summary description for _Default. + /// + public class _Default : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + // ------------------------------------------------------ + // No one is sane mind would throw an exception just for + // the heck of it, but for demonstration purposes this + // should work. + // ------------------------------------------------------ + //throw new Exception ("Silly exception"); + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.resx b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Default.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/ErrorModule.cs b/web/errors/CustomErrorPages/CustomErrors4/ErrorModule.cs new file mode 100644 index 00000000..6496d03d --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/ErrorModule.cs @@ -0,0 +1,35 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors4 +{ + public class MyErrorModule : IHttpModule + { + public void Init (HttpApplication app) + { + app.Error += new System.EventHandler (OnError); + } + + public void OnError (object obj, EventArgs args) + { + // At this point we have information about the error + HttpContext ctx = HttpContext.Current; + + Exception exception = ctx.Server.GetLastError (); + + string errorInfo = "
    Offending URL: " + ctx.Request.Url.ToString () + + "
    Source: " + exception.Source + + "
    Message: " + exception.Message + + "
    Stack trace: " + exception.StackTrace; + + ctx.Response.Write (errorInfo); + + // -------------------------------------------------- + // To let the page finish running we clear the error + // -------------------------------------------------- + //ctx.Server.ClearError (); + } + + public void Dispose () {} + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors4/Global.asax b/web/errors/CustomErrorPages/CustomErrors4/Global.asax new file mode 100644 index 00000000..14794241 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="CustomErrors4.Global" %> diff --git a/web/errors/CustomErrorPages/CustomErrors4/Global.asax.cs b/web/errors/CustomErrorPages/CustomErrors4/Global.asax.cs new file mode 100644 index 00000000..128864c7 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Global.asax.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Web; +using System.Web.SessionState; + +namespace CustomErrors4 +{ + /// + /// Summary description for Global. + /// + public class Global : System.Web.HttpApplication + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + public Global() + { + InitializeComponent(); + } + + protected void Application_Start(Object sender, EventArgs e) + { + + } + + protected void Session_Start(Object sender, EventArgs e) + { + + } + + protected void Application_BeginRequest(Object sender, EventArgs e) + { + + } + + protected void Application_EndRequest(Object sender, EventArgs e) + { + + } + + protected void Application_AuthenticateRequest(Object sender, EventArgs e) + { + + } + + protected void Application_Error(Object sender, EventArgs e) + { + + } + + protected void Session_End(Object sender, EventArgs e) + { + + } + + protected void Application_End(Object sender, EventArgs e) + { + + } + + #region Web Form Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + } + #endregion + } +} + diff --git a/web/errors/CustomErrorPages/CustomErrors4/Global.asax.resx b/web/errors/CustomErrorPages/CustomErrors4/Global.asax.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Global.asax.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/Web.config b/web/errors/CustomErrorPages/CustomErrors4/Web.config new file mode 100644 index 00000000..e2ed8087 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/Web.config @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx new file mode 100644 index 00000000..8e6f7b25 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" Codebehind="GeneralError.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors3.GeneralError" %> + + + + Server error + + +
    +

    Sorry

    +

    The server is experiencing a problem with the page you requested. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.cs b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.cs new file mode 100644 index 00000000..247d0184 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors3 +{ + /// + /// Summary description for GeneralError. + /// + public class GeneralError : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.resx b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/GeneralError.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx new file mode 100644 index 00000000..51c96687 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" Codebehind="PageNotFound.aspx.cs" AutoEventWireup="false" Inherits="AspNetResources.CustomErrors3.PageNotFound" %> + + + + PageNotFound + + +
    +

    Sorry

    +

    We cannot find the page you are looking for. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.cs b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.cs new file mode 100644 index 00000000..0a2abb1f --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; + +namespace AspNetResources.CustomErrors3 +{ + /// + /// Summary description for PageNotFound. + /// + public class PageNotFound : System.Web.UI.Page + { + private void Page_Load(object sender, System.EventArgs e) + { + } + + #region Web Form Designer generated code + override protected void OnInit(EventArgs e) + { + InitializeComponent(); + base.OnInit(e); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Load += new System.EventHandler(this.Page_Load); + } + #endregion + } +} diff --git a/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.resx b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.resx new file mode 100644 index 00000000..dd0ea4d8 --- /dev/null +++ b/web/errors/CustomErrorPages/CustomErrors4/errors/PageNotFound.aspx.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/web/errors/GeneralError.aspx b/web/errors/GeneralError.aspx new file mode 100644 index 00000000..969463d1 --- /dev/null +++ b/web/errors/GeneralError.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" AutoEventWireup="false" %> + + + + Server error + + +
    +

    Sorry

    +

    The server is experiencing a problem with the page you requested. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/errors/PageNotFound.aspx b/web/errors/PageNotFound.aspx new file mode 100644 index 00000000..f17d94e1 --- /dev/null +++ b/web/errors/PageNotFound.aspx @@ -0,0 +1,14 @@ +<%@ Page language="c#" AutoEventWireup="false" %> + + + + PageNotFound + + +
    +

    Sorry

    +

    We cannot find the page you are looking for. We apologize for + the inconvenience. We will resolve this issue shortly.

    +
    + + diff --git a/web/favicon.ico b/web/favicon.ico new file mode 100644 index 00000000..c73dc91a Binary files /dev/null and b/web/favicon.ico differ diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 00000000..1abcbea6 Binary files /dev/null and b/web/favicon.png differ diff --git a/web/genpot.sh b/web/genpot.sh new file mode 100644 index 00000000..f3b4d0d5 --- /dev/null +++ b/web/genpot.sh @@ -0,0 +1,9 @@ +Le script a débuté sur ven. 03 janv. 2014 00:34:11 CET +paul@pazms:~/workspace/mae/mae$ ../GettextNet/Bin/Release/GNU.Gettext.Xgettext.exe -D ./ --recursive -o ./po/Message s.pot +Template file '/home/paul/workspace/mae/mae/po/Messages.pot' generated +paul@pazms:~/workspace/mae/mae$ ../GettextNet/Bin/Release/GNU.Gettext.Msgfmt.exe -l fr-FR -d ../bin/Debug -r Examples .Hello.Messages -L ../../Bin/Debug fr.po +File fr.po not found +Error accepting options +paul@pazms:~/workspace/mae/mae$ exit + +Script terminé sur ven. 03 janv. 2014 00:35:36 CET diff --git a/web/images/Banner.png b/web/images/Banner.png new file mode 100644 index 00000000..12dfaa2b Binary files /dev/null and b/web/images/Banner.png differ diff --git a/web/images/Mono-powered.png b/web/images/Mono-powered.png new file mode 100644 index 00000000..3f69e4f5 Binary files /dev/null and b/web/images/Mono-powered.png differ diff --git a/web/images/apache_pb.gif b/web/images/apache_pb.gif new file mode 100644 index 00000000..f8cba34d Binary files /dev/null and b/web/images/apache_pb.gif differ diff --git a/web/images/apache_pbw.gif b/web/images/apache_pbw.gif new file mode 100644 index 00000000..b0fe4008 Binary files /dev/null and b/web/images/apache_pbw.gif differ diff --git a/web/images/apache_pbw.png b/web/images/apache_pbw.png new file mode 100644 index 00000000..b8fba2af Binary files /dev/null and b/web/images/apache_pbw.png differ diff --git a/web/images/apache_pby.gif b/web/images/apache_pby.gif new file mode 100644 index 00000000..6e115032 Binary files /dev/null and b/web/images/apache_pby.gif differ diff --git a/web/images/debian-logo.png b/web/images/debian-logo.png new file mode 100644 index 00000000..fdb4e62a Binary files /dev/null and b/web/images/debian-logo.png differ diff --git a/web/images/debian-pb.gif b/web/images/debian-pb.gif new file mode 100644 index 00000000..92cbdf17 Binary files /dev/null and b/web/images/debian-pb.gif differ diff --git a/web/images/debian-powered.png b/web/images/debian-powered.png new file mode 100644 index 00000000..10e12225 Binary files /dev/null and b/web/images/debian-powered.png differ diff --git a/web/images/logoDev.png b/web/images/logoDev.png new file mode 100644 index 00000000..1abcbea6 Binary files /dev/null and b/web/images/logoDev.png differ diff --git a/web/images/logoDev.xcf b/web/images/logoDev.xcf new file mode 100644 index 00000000..8ac3a940 Binary files /dev/null and b/web/images/logoDev.xcf differ diff --git a/web/images/noavatar.png b/web/images/noavatar.png new file mode 100644 index 00000000..22c5049c Binary files /dev/null and b/web/images/noavatar.png differ diff --git a/web/images/pgsql.jpeg b/web/images/pgsql.jpeg new file mode 100644 index 00000000..c90756e4 Binary files /dev/null and b/web/images/pgsql.jpeg differ diff --git a/web/images/pgsql.png b/web/images/pgsql.png new file mode 100644 index 00000000..3da83f15 Binary files /dev/null and b/web/images/pgsql.png differ diff --git a/web/images/pgsql.xcf b/web/images/pgsql.xcf new file mode 100644 index 00000000..cd0a9b4f Binary files /dev/null and b/web/images/pgsql.xcf differ diff --git a/web/instdbws.sql b/web/instdbws.sql new file mode 100644 index 00000000..28ed5950 --- /dev/null +++ b/web/instdbws.sql @@ -0,0 +1,68 @@ + +CREATE TABLE users +( + pkid character varying NOT NULL, + username character varying(255) NOT NULL, + applicationname character varying(255) NOT NULL, + email character varying(128) NOT NULL, + comment character varying(255), + passw character varying(128) NOT NULL, + passwordquestion character varying(255), + passwordanswer character varying(255), + isapproved boolean, + lastactivitydate date, + lastlogindate date, + lastpasswordchangeddate date, + creationdate date, + isonline boolean, + islockedout boolean, + lastlockedoutdate date, + failedpasswordattemptcount integer, + failedpasswordattemptwindowstart date, + failedpasswordanswerattemptcount integer, + failedpasswordanswerattemptwindowstart date, + CONSTRAINT users_pkey PRIMARY KEY (pkid ), + CONSTRAINT uniquelogin UNIQUE (applicationname, email ), + CONSTRAINT uniquemail UNIQUE (applicationname, username ) +) +WITH ( + OIDS=FALSE +); + +-- Table: roles + +-- DROP TABLE roles; + +CREATE TABLE roles +( + rolename character varying(255) NOT NULL, + applicationname character varying(255) NOT NULL, + comment character varying(255) NOT NULL, + CONSTRAINT roles_pkey PRIMARY KEY (rolename , applicationname ) +) +WITH ( + OIDS=FALSE +); +COMMENT ON TABLE roles + IS 'Web application roles'; + +-- Table: usersroles + +-- DROP TABLE usersroles; + +CREATE TABLE usersroles +( + applicationname character varying (255) NOT NULL, + rolename character varying (255) NOT NULL, + username character varying (255) NOT NULL, + CONSTRAINT attrroles_pkey PRIMARY KEY (applicationname, rolename , username ), + CONSTRAINT usersroles_fk_role FOREIGN KEY (applicationname,rolename) + REFERENCES roles (applicationname,rolename) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE, + CONSTRAINT usersroles_fk_user FOREIGN KEY (applicationname,username) + REFERENCES users (applicationname,username) MATCH SIMPLE + ON UPDATE CASCADE ON DELETE CASCADE +) +WITH ( + OIDS=FALSE +); diff --git a/web/lib/CodeKicker.BBCode.XML b/web/lib/CodeKicker.BBCode.XML new file mode 100644 index 00000000..ff614dcd --- /dev/null +++ b/web/lib/CodeKicker.BBCode.XML @@ -0,0 +1,53 @@ + + + + CodeKicker.BBCode + + + + + This class is useful for creating a custom parser. You can customize which tags are available + and how they are translated to HTML. + In order to use this library, we require a link to http://codekicker.de/ from you. Licensed unter the Creative Commons Attribution 3.0 Licence: http://creativecommons.org/licenses/by/3.0/. + + + + + Every syntax error throws a BBCodeParsingException. + + + + + Syntax errors with obvious meaning will be corrected automatically. + + + + + The parser will never throw an exception. Invalid tags like "array[0]" will be interpreted as text. + + + + + Transforms the given BBCode into safe HTML with the default configuration from http://codekicker.de + This method is thread safe. + In order to use this library, we require a link to http://codekicker.de/ from you. Licensed unter the Creative Commons Attribution 3.0 Licence: http://creativecommons.org/licenses/by/3.0/. + + A non-null string of valid BBCode. + + + + + Encodes an arbitrary string to be valid BBCode. Example: "[b]" => "\[b\]". The resulting string is safe against + BBCode-Injection attacks. + In order to use this library, we require a link to http://codekicker.de/ from you. Licensed unter the Creative Commons Attribution 3.0 Licence: http://creativecommons.org/licenses/by/3.0/. + + + + + Decodes a string of BBCode that only contains text (no tags). Example: "\[b\]" => "[b]". This is the reverse + oepration of EscapeText. + In order to use this library, we require a link to http://codekicker.de/ from you. Licensed unter the Creative Commons Attribution 3.0 Licence: http://creativecommons.org/licenses/by/3.0/. + + + + diff --git a/web/lib/CodeKicker.BBCode.dll b/web/lib/CodeKicker.BBCode.dll new file mode 100644 index 00000000..99a7dbb6 Binary files /dev/null and b/web/lib/CodeKicker.BBCode.dll differ diff --git a/web/lib/CodeKicker.BBCode.pdb b/web/lib/CodeKicker.BBCode.pdb new file mode 100644 index 00000000..0399a968 Binary files /dev/null and b/web/lib/CodeKicker.BBCode.pdb differ diff --git a/web/lib/de-DE/CodeKicker.BBCode.resources.dll b/web/lib/de-DE/CodeKicker.BBCode.resources.dll new file mode 100644 index 00000000..14a11c6e Binary files /dev/null and b/web/lib/de-DE/CodeKicker.BBCode.resources.dll differ diff --git a/web/lib/it-IT/CodeKicker.BBCode.resources.dll b/web/lib/it-IT/CodeKicker.BBCode.resources.dll new file mode 100644 index 00000000..9615c2f6 Binary files /dev/null and b/web/lib/it-IT/CodeKicker.BBCode.resources.dll differ diff --git a/web/messages.po b/web/messages.po new file mode 100644 index 00000000..fba97620 --- /dev/null +++ b/web/messages.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-12-06 23:46+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Controllers/HomeController.cs:51 +msgid "Bienvenue" +msgstr "" + +#: Controllers/HomeController.cs:52 +msgid "Vous etes au bon endroit" +msgstr "" diff --git a/web/sourcefiles b/web/sourcefiles new file mode 100644 index 00000000..72140257 --- /dev/null +++ b/web/sourcefiles @@ -0,0 +1,36 @@ +./Test/TestProject.cs +./Providers/BlogProvidersConfigurationCollection.cs +./Providers/BlogProvider.cs +./Providers/BlogHelper.cs +./Providers/BlogEntry.cs +./Providers/BlogEntryCollection.cs +./Providers/BlogProvidersConfigurationSection.cs +./Providers/NpgsqlBlogProvider.cs +./Providers/BlogProviderConfigurationElement.cs +./Providers/NpgsqlProfileProvider.cs +./Providers/FindBlogEntryFlags.cs +./Controllers/AccountController.cs +./Controllers/HomeController.cs +./Controllers/WorkFlowController.cs +./Controllers/BlogController.cs +./Security/RegisterViewPage.cs +./Security/NpgsqlMembershipProvider.cs +./Security/NpgsqlRoleProvider.cs +./Security/LoginViewPage.cs +./Security/PasswordConfirmationAttribute.cs +./Security/ChangePasswordViewPage.cs +./Security/DataModel/ChangePasswordModel.cs +./Security/DataModel/RegisterViewModel.cs +./Security/DataModel/LoginModel.cs +./Security/DataModel/NewAdminModel.cs +./Security/AdminViewPage.cs +./Security/UserListViewPage.cs +./DataModel/NewProjectView.cs +./DataModel/ProfileModel.cs +./DataModel/NewProjectModel.cs +./DataModel/BlogEntryModel.cs +./DataModel/BlogEditView.cs +./DataModel/NpgsqlContentProvider.cs +./DataModel/ContentProviders.cs +./DataModel/IContentProvider.cs +./Global.asax.cs diff --git a/web/style.css b/web/style.css new file mode 100644 index 00000000..2b4e2c9f --- /dev/null +++ b/web/style.css @@ -0,0 +1,149 @@ + +body { + background: black; + background-image: url('/images/Banner.png'); + background-repeat: no-repeat; + color: #D0FFD0; + margin:1em; + padding:1em; + font-family: 'Dancing Script', cursive; + line-height:135%; +} + +video,img { + max-width:100%; + max-height:75%; + padding:.2em; + margin:0; + position:relative; + top:.7em; + } + +#login { + position: fixed; + right:3px; + font-size:x-small; + background-color:rgba(0,0,0,0.8); + color:rgb(0,254,0); +} + +#login a { + background-color:rgba(0,0,64,0.8); + } + +a { + text-decoration: none; + color: #B0B080; + right:2px; + padding: 2px; + border-radius:5px; + border-style: dotted; + border-width: .2px; + background-color:rgba(0,0,3,0.5); +} + +a.athanks { + background-color:rgba(0,0,0,0);; + } + +a:hover { + background-color:rgba(30,0,124,0.5); +border-color: white; +} + +a:visited { + color: #90B090; +} +label { + font-size: medium; +} + + +.thanks { + display: inline; + font-size: small; +} +.blogpost { + border-top: solid 0.5px; + border-bottom: dashed 0.5px; + padding-top: 3px; +} +.editblog { + width: 95%; + height: 95%; +} +.metablog { + font-style: italic; + font-size: small; + text-align: right; + display: inline; +} + +.blogtitle { + display:inline; +} +.contenu { +padding-left: 20px; +} + +.validation-summary-errors{ + color: #f88; +} +.pied { +} + +.actionlink { + color: #B0B080; + border: solid .5px; + right:3px; + padding: 4px; + border-radius:25px; + background-color:rgba(0,0,64,0.7); +} + +.code { + font-family: "monospace"; + background-color: rgba(0,0,256,0.1); + border-radius:25px; + white-space: pre-wrap; +} + +.layout { + border-width: 0; + } + +.avatar { + max-width: 64px; + max-height: 64px; +} + + .shoh { display:inline; } +.hiduh { + display:none; + } + .shoh:hover { + background-color: rgba(0,60,40,.3); + border: solid rgb(256,256,0); + } +.shoh:hover + .hiduh { + display:block; position:absolute; left:20px; right:20px; + background-color: rgb(0,0,40); border: solid rgb(256,256,0); + } +.comment { + border-radius:25px; + border-width:1px; + border-style: solid; + border-color:rgb(0,64,0); + } + +@media print { + body {background-color:white;color:black;} + .postcomment,#login,.actionlink{ display:none;} + } + +@media all and (max-width: 15em) { + section, aside { + float: none; + width: auto; + } +} diff --git a/web/table.tdeps.sql b/web/table.tdeps.sql new file mode 100644 index 00000000..e185d1ac --- /dev/null +++ b/web/table.tdeps.sql @@ -0,0 +1,6 @@ +CREATE TABLE TaskDeps (idtask bigint NOT NULL , +iddep bigint NOT NULL , +CONSTRAINT TaskDeps_pk_new PRIMARY KEY (idtask,iddep), +CONSTRAINT TaskDeps_fk_new FOREIGN KEY (idtask) REFERENCES public.tasks (id), +CONSTRAINT TaskDeps_fk_new FOREIGN KEY (iddep) REFERENCES public.tasks (id) +); diff --git a/web/test-results/maeweb.csproj-Debug-2013-11-28.xml b/web/test-results/maeweb.csproj-Debug-2013-11-28.xml new file mode 100644 index 00000000..cc156fde --- /dev/null +++ b/web/test-results/maeweb.csproj-Debug-2013-11-28.xml @@ -0,0 +1,112 @@ + + + + + + + + + 2013-11-28T00:57:03 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-11-28T01:02:44 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + 2013-11-28T00:57:03 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-11-28T01:02:44 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-11-28T01:04:49 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + \ No newline at end of file diff --git a/web/test-results/maeweb.csproj-Debug-2013-12-12.xml b/web/test-results/maeweb.csproj-Debug-2013-12-12.xml new file mode 100644 index 00000000..db708bac --- /dev/null +++ b/web/test-results/maeweb.csproj-Debug-2013-12-12.xml @@ -0,0 +1,141 @@ + + + + + 2013-12-12T00:23:40 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-12-12T01:29:23 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + 2013-12-12T00:23:40 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-12-12T01:29:23 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + 2013-12-12T00:23:40 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-12-12T01:29:23 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + 2013-12-12T00:23:40 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + 2013-12-12T01:29:23 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + \ No newline at end of file diff --git a/web/test-results/maeweb.csproj-Debug-2013-12-16.xml b/web/test-results/maeweb.csproj-Debug-2013-12-16.xml new file mode 100644 index 00000000..dbf13644 --- /dev/null +++ b/web/test-results/maeweb.csproj-Debug-2013-12-16.xml @@ -0,0 +1,19 @@ + + + + + 2013-12-16T03:01:39 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + \ No newline at end of file diff --git a/web/test-results/maeweb.csproj.test-cache b/web/test-results/maeweb.csproj.test-cache new file mode 100644 index 00000000..cb1e00be Binary files /dev/null and b/web/test-results/maeweb.csproj.test-cache differ diff --git a/web/uninstdb.sql b/web/uninstdb.sql new file mode 100644 index 00000000..8537c0c0 --- /dev/null +++ b/web/uninstdb.sql @@ -0,0 +1,6 @@ + + DROP TABLE hr; + DROP TABLE taskdeps; + DROP TABLE tasks; + DROP TABLE projet; + diff --git a/web/uninstdbws.sql b/web/uninstdbws.sql new file mode 100644 index 00000000..29482b18 --- /dev/null +++ b/web/uninstdbws.sql @@ -0,0 +1,5 @@ + + DROP table usersroles CASCADE; + drop table roles CASCADE; + Drop table users CASCADE; + diff --git a/yavscModel/Admin/DataAccess.cs b/yavscModel/Admin/DataAccess.cs new file mode 100644 index 00000000..0106bc6e --- /dev/null +++ b/yavscModel/Admin/DataAccess.cs @@ -0,0 +1,84 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace yavscModel.Admin +{ + public class DataAccess { + private string host = "localhost"; + + [StringLength(2056)] + public string Host { + get { + return host; + } + set { + host = value; + } + } + + private int port = 5432; + + public int Port { + get { + return port; + } + set { + port = value; + } + } + + private string dbname = "yavsc"; + + public string Dbname { + get { + return dbname; + } + set { + dbname = value; + } + } + + private string dbuser = "postgres"; + + public string Dbuser { + get { + return dbuser; + } + set { + dbuser = value; + } + } + + private string dbpassword ; + private string backupPrefix= "backup/global.backup"; + + public string BackupPrefix { + get { + return backupPrefix; + } + set { + backupPrefix = value; + } + } + + [Required(ErrorMessage ="Please, specify a password")] + public string Password { + get { return dbpassword; } + set { dbpassword = value; } + } + + public string [] GetBackupDirs() + { + List res = new List (); + string bkpdir = new FileInfo (backupPrefix).DirectoryName; + DirectoryInfo bkpdiri = new DirectoryInfo(bkpdir); + foreach (DirectoryInfo di in bkpdiri.EnumerateDirectories()) + res.Add (Path.Combine(bkpdir,di.Name)); + return res.ToArray (); + } + } + +} diff --git a/yavscModel/Admin/RestoreQuery.cs b/yavscModel/Admin/RestoreQuery.cs new file mode 100644 index 00000000..022c99a6 --- /dev/null +++ b/yavscModel/Admin/RestoreQuery.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace yavscModel.Admin +{ + public class RestoreQuery: DataAccess + { + [Required] + [StringLength(2056)] + public string FileName { get; set ; } + + public RestoreQuery () + { + } + } +} + diff --git a/yavscModel/Blogs/BlogEditCommentModel.cs b/yavscModel/Blogs/BlogEditCommentModel.cs new file mode 100644 index 00000000..cd514ec3 --- /dev/null +++ b/yavscModel/Blogs/BlogEditCommentModel.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Npgsql.Web.Blog.DataModel; + +namespace yavscModel +{ + public class BlogEditCommentModel:Comment + { + [DisplayName("Prévisualiser")] + [Required] + public bool Preview { get; set; } + /* TODO Clean + public BlogEditCommentModel(Comment be) { + this.Preview = true; + this.Content = be.Content; + this.Posted = be.Posted; + this.Modified = be.Modified; + this.Visible = be.Visible; + this.From = be.From; + this.PostId = be.PostId; + this.Id = be.Id; + } */ + } +} + diff --git a/yavscModel/Blogs/BlogEditEntryModel.cs b/yavscModel/Blogs/BlogEditEntryModel.cs new file mode 100644 index 00000000..d454ca3c --- /dev/null +++ b/yavscModel/Blogs/BlogEditEntryModel.cs @@ -0,0 +1,29 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Npgsql.Web.Blog.DataModel; + +namespace yavscModel +{ + public class BlogEditEntryModel:BlogEntry + { + [DisplayName("Prévisualiser")] + [Required] + public bool Preview { get; set; } + public BlogEditEntryModel () + { + } + + public BlogEditEntryModel(BlogEntry be) { + this.Preview = true; + this.Content = be.Content; + this.Title = be.Title; + this.Posted = be.Posted; + this.Modified = be.Modified; + this.Visible = be.Visible; + this.UserName = be.UserName; + this.Id = be.Id; + } + } +} + diff --git a/yavscModel/FileSystem/FileInfoCollection.cs b/yavscModel/FileSystem/FileInfoCollection.cs new file mode 100644 index 00000000..3a2897b6 --- /dev/null +++ b/yavscModel/FileSystem/FileInfoCollection.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; +using System.Collections.Generic; + +namespace FileSystem +{ + public class FileInfoCollection: List + { + + } +} + diff --git a/yavscModel/Properties/AssemblyInfo.cs b/yavscModel/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..a22ab5b7 --- /dev/null +++ b/yavscModel/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("YavscModel")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("paul")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/yavscModel/RolesAndMemebers/ChangePasswordModel.cs b/yavscModel/RolesAndMemebers/ChangePasswordModel.cs new file mode 100644 index 00000000..cf20cc38 --- /dev/null +++ b/yavscModel/RolesAndMemebers/ChangePasswordModel.cs @@ -0,0 +1,22 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace yavscModel.RolesAndMembers +{ + public class ChangePasswordModel + { + [Required(ErrorMessage = "Please enter a Username")] + public string Username { get; set; } + + [Required(ErrorMessage = "Please your old Password")] + public string OldPassword { get; set; } + + [Required(ErrorMessage = "Please enter a new Password")] + public string NewPassword { get; set; } + + [Required(ErrorMessage = "Please confirm the new Password")] + public string ConfirmPassword { get; set; } + + } +} + diff --git a/yavscModel/RolesAndMemebers/LoginModel.cs b/yavscModel/RolesAndMemebers/LoginModel.cs new file mode 100644 index 00000000..2636a0ef --- /dev/null +++ b/yavscModel/RolesAndMemebers/LoginModel.cs @@ -0,0 +1,22 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace yavscModel.RolesAndMembers +{ + public class LoginModel + { + [DisplayName("Nom d'utilisateur")] + [Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur ([a-z]|[A-Z]|[-_.~])+")] + [RegularExpression("([a-z]|[A-Z]|[-_.~])+")] + public string UserName { get; set; } + + [DisplayName("Mot de passe")] + [Required(ErrorMessage = "S'il vous plait, entez un mot de passe")] + [RegularExpression("([a-z]|[A-Z]|[-_.~#{}`'\\^])+")] + public string Password { get; set; } + + [Display(Name = "Se souvenir du mot de passe")] + public bool RememberMe { get; set; } + } +} diff --git a/yavscModel/RolesAndMemebers/NewAdminModel.cs b/yavscModel/RolesAndMemebers/NewAdminModel.cs new file mode 100644 index 00000000..cc1a3ed6 --- /dev/null +++ b/yavscModel/RolesAndMemebers/NewAdminModel.cs @@ -0,0 +1,13 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace yavscModel.RolesAndMembers +{ + public class NewAdminModel + { + [Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur")] + [Display(Name = "Nom du nouvel administrateur", Description="Nom de l'utilisateur à enregistrer comme administrateur")] + public string UserName { get; set ; } + } +} + diff --git a/yavscModel/RolesAndMemebers/NewRoleModel.cs b/yavscModel/RolesAndMemebers/NewRoleModel.cs new file mode 100644 index 00000000..5a295878 --- /dev/null +++ b/yavscModel/RolesAndMemebers/NewRoleModel.cs @@ -0,0 +1,15 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace yavscModel.RolesAndMembers +{ + public class NewRoleModel + { + [Required] + [StringLength(255)] + [DisplayName("Nom du rôle")] + public string RoleName { get; set; } + } +} + diff --git a/yavscModel/RolesAndMemebers/Profile.cs b/yavscModel/RolesAndMemebers/Profile.cs new file mode 100644 index 00000000..d3bc21ae --- /dev/null +++ b/yavscModel/RolesAndMemebers/Profile.cs @@ -0,0 +1,63 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Web.Profile; + +namespace yavscModel.RolesAndMembers +{ + public class Profile + { + [DisplayName("Adresse")] + [StringLength(2047)] + public string Address { get; set; } + + [DisplayName("Ville")] + [StringLength(255)] + public string CityAndState { get; set; } + + [DisplayName("Code Postal")] + [StringLength(9)] + public string ZipCode { get; set; } + + [DisplayName("Pays")] + [StringLength(99)] + public string Country { get; set; } + + [DisplayName("Site Web")] + [StringLength(255)] + public string WebSite { get; set; } + + [DisplayName("Blog visible")] + public bool BlogVisible { get; set; } + + [DisplayName("Titre du blog")] + public string BlogTitle { get; set; } + + public void FromProfileBase(ProfileBase profile) + { + object b = profile.GetPropertyValue ("BlogVisible"); + BlogVisible = (b is DBNull) ? true : (bool)b; + + object s = profile.GetPropertyValue ("BlogTitle"); + BlogTitle = (s is DBNull) ? null : (string)s; + + s = profile.GetPropertyValue("Address"); + Address = (s is DBNull)?null:(string)s; + + s = profile.GetPropertyValue("CityAndState"); + CityAndState = (s is DBNull)?null:(string)s; + + s = profile.GetPropertyValue("Country"); + Country = (s is DBNull)?null:(string)s; + + s = profile.GetPropertyValue("ZipCode"); + ZipCode = (s is DBNull)?null:(string)s; + + + s = profile.GetPropertyValue ("WebSite"); + WebSite = (s is DBNull) ? null : (string)s; + + } + } +} + diff --git a/yavscModel/RolesAndMemebers/RegisterViewModel.cs b/yavscModel/RolesAndMemebers/RegisterViewModel.cs new file mode 100644 index 00000000..306b7848 --- /dev/null +++ b/yavscModel/RolesAndMemebers/RegisterViewModel.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace yavscModel.RolesAndMembers +{ + public class RegisterViewModel + { + [DisplayName("Nom d'utilisateur")] + [Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur")] + public string UserName { get; set; } + + [DisplayName("Mot de passe")] + [Required(ErrorMessage = "S'il vous plait, entez un mot de passe")] + public string Password { get; set; } + + [DisplayName("Confirmation du mot de passe")] + public string ConfirmPassword { get; set; } + + [DisplayName("Adresse e-mail")] + [Required(ErrorMessage = "S'il vous plait, entrez un e-mail valide")] + public string Email { get; set; } + } +} + diff --git a/yavscModel/WorkFlow/Estimate.cs b/yavscModel/WorkFlow/Estimate.cs new file mode 100644 index 00000000..0444ad8f --- /dev/null +++ b/yavscModel/WorkFlow/Estimate.cs @@ -0,0 +1,22 @@ +using System; + +namespace yavscModel.WorkFlow +{ + public class Estimate + { + public Estimate () + { + } + public string Description { get; set; } + public decimal Ciffer { + get { + decimal total = 0; + foreach (Writting l in Lines) + total += l.UnitaryCost * l.Count; + return total; + } + } + public Writting[] Lines { get; set; } + } +} + diff --git a/yavscModel/WorkFlow/IContent.cs b/yavscModel/WorkFlow/IContent.cs new file mode 100644 index 00000000..f608f3f9 --- /dev/null +++ b/yavscModel/WorkFlow/IContent.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace yavscModel.WorkFlow +{ + public interface IContent + { + object Data { get; set; } + string MimeType { get; set; } + + } +} + diff --git a/yavscModel/WorkFlow/IContentProvider.cs b/yavscModel/WorkFlow/IContentProvider.cs new file mode 100644 index 00000000..6d47549e --- /dev/null +++ b/yavscModel/WorkFlow/IContentProvider.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace yavscModel.WorkFlow +{ + public interface IContentProvider: IDisposable + { + string Order (IWFCommand c); + IContent Get (string orderId); + } +} + diff --git a/yavscModel/WorkFlow/IWFCommand.cs b/yavscModel/WorkFlow/IWFCommand.cs new file mode 100644 index 00000000..7de8dcb8 --- /dev/null +++ b/yavscModel/WorkFlow/IWFCommand.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace yavscModel.WorkFlow +{ + public interface IWFCommand + { + } +} + diff --git a/yavscModel/WorkFlow/IWFModule.cs b/yavscModel/WorkFlow/IWFModule.cs new file mode 100644 index 00000000..6b65ae02 --- /dev/null +++ b/yavscModel/WorkFlow/IWFModule.cs @@ -0,0 +1,13 @@ +using System; +using yavscModel.WorkFlow; +using System.Web.Mvc; + +namespace WorkFlow +{ + public interface IWFModule + { + int GetState (IWFCommand c); + int Handle (IWFCommand c,FormCollection collection); + } +} + diff --git a/yavscModel/WorkFlow/NewProjectModel.cs b/yavscModel/WorkFlow/NewProjectModel.cs new file mode 100644 index 00000000..5daf7771 --- /dev/null +++ b/yavscModel/WorkFlow/NewProjectModel.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace yavscModel.WorkFlow +{ + public class NewProjectModel + { + [DisplayName("Nom du projet")] + [Required()] + public string Name { get; set; } + + [DisplayName("Manager du projet")] + [Required] + public string Manager { get; set; } + + [DisplayName("Description du projet")] + [Required] + public string Description { get; set; } + + } +} + diff --git a/yavscModel/WorkFlow/WFOrder.cs b/yavscModel/WorkFlow/WFOrder.cs new file mode 100644 index 00000000..77378a18 --- /dev/null +++ b/yavscModel/WorkFlow/WFOrder.cs @@ -0,0 +1,39 @@ +using System; +using SalesCatalog.Model; +using yavscModel.WorkFlow; + +namespace WorkFlow +{ + public class WFOrder : IWFCommand + { + private Product p; + private DateTime date; + private string catref; + public WFOrder(Product prod,string catalogReference){ + date = DateTime.Now; + catref=catalogReference; + p = prod; + } + public override string ToString () + { + return string.Format ("[Commande date={0} prodref={1}, cat={2}]",date,p.Reference,catref); + } + + #region IWFCommand implementation + + public string CatalogReference { + get { + return catref; + } + } + + public DateTime OrderDate { + get { + return date; + } + } + + #endregion + } +} + diff --git a/yavscModel/WorkFlow/Writting.cs b/yavscModel/WorkFlow/Writting.cs new file mode 100644 index 00000000..c5710edd --- /dev/null +++ b/yavscModel/WorkFlow/Writting.cs @@ -0,0 +1,13 @@ +using System; + +namespace yavscModel.WorkFlow +{ + public class Writting + { + public decimal UnitaryCost { get; set; } + public int Count { get; set; } + public string ProductReference { get; set; } + public string Description { get; set; } + } +} + diff --git a/yavscModel/yavscModel.csproj b/yavscModel/yavscModel.csproj new file mode 100644 index 00000000..6737e2f5 --- /dev/null +++ b/yavscModel/yavscModel.csproj @@ -0,0 +1,89 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {68F5B80A-616E-4C3C-91A0-828AA40000BD} + Library + yavscModel + yavscModel + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {C6E9E91B-97D3-48D9-8AA7-05356929E162} + NpgsqlBlogProvider + + + {90BF2234-7252-4CD5-B2A4-17501B19279B} + SalesCatalog + + + + + + + + + + + + \ No newline at end of file diff --git a/yavscclient/MyClass.cs b/yavscclient/MyClass.cs new file mode 100644 index 00000000..6e2594aa --- /dev/null +++ b/yavscclient/MyClass.cs @@ -0,0 +1,78 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using SalesCatalog.Model; +using System.Net.Http.Headers; +using System.Collections.Generic; +using System.Net.Http.Formatting; +using Newtonsoft.Json; + +namespace Yavsc +{ + public class MainClass + { + public static string ServiceUrl{ get; set; } + + public static void Main(string [] args) + { + foreach (string s in args) { + if (Uri.IsWellFormedUriString (s,UriKind.Absolute)) { + // TODO create a client + } + GetCatalog (); + } + } + static HttpClient GetClient() + { + HttpClient client = new HttpClient (); + + client.BaseAddress = new Uri (ServiceUrl); + + // Add an Accept header for JSON format. + client.DefaultRequestHeaders.Accept.Add ( + new MediaTypeWithQualityHeaderValue ("application/json")); + return client; + } + + static void GetCatalog() { + HttpClient client = GetClient (); + + HttpResponseMessage response = client.GetAsync("api/FrontOffice/Catalog").Result; // Blocking call! + if (response.IsSuccessStatusCode) + { + + var jsonFormatter = new JsonMediaTypeFormatter(); + jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto; + jsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + // Parse the response body. Blocking! + Catalog cat = response.Content.ReadAsAsync(new List{jsonFormatter},null).Result; + foreach (var p in cat.Brands) + { + Console.WriteLine("{0}\t{1};\t{2}", p.Name, p.Categories.Length, p.Slogan); + } + } + else + { + Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); + } + } + + public void UpLoad(string fileName) + { + using (var client = GetClient()) + { + using (var content = new MultipartFormDataContent()) + { + var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(fileName));//(); + fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") + { + FileName = fileName + }; + content.Add(fileContent); + var result = client.PostAsync(ServiceUrl, content).Result; + } + } + } + } +} + diff --git a/yavscclient/Properties/AssemblyInfo.cs b/yavscclient/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..8ac65528 --- /dev/null +++ b/yavscclient/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("YavscClient")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Paul Schneider")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/yavscclient/YavscClient.csproj b/yavscclient/YavscClient.csproj new file mode 100644 index 00000000..ace26675 --- /dev/null +++ b/yavscclient/YavscClient.csproj @@ -0,0 +1,55 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {EEFCECE6-3B7F-4BBE-B7AF-69377AF3CF39} + Exe + maeclient + yavscclient + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + true + + + full + true + bin\Release + prompt + 4 + false + true + + + + + + + ..\..\..\..\..\usr\lib\mono\4.5\System.Net.Http.Formatting.dll + False + + + + + + + + + + + {90BF2234-7252-4CD5-B2A4-17501B19279B} + SalesCatalog + + + \ No newline at end of file