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 ("{1} ", 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 ("{1} \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 ("{2} ", 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 ("{2} \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\"> {0}:ResultPages>")
+ ]
+ 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",
+ "" +
+ "
" +
+ "
${content}",
+ "
",
+ false, true,
+ Section2Transformer,
+ new BBAttribute ("title", "",TitleContentTransformer),
+ new BBAttribute ("title", "title", TitleContentTransformer),
+ new BBAttribute ("para", "para", L2ContentTransformer));
+ BBTag bbs1=new BBTag ("sect1",
+ "" +
+ "
" +
+ "
${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",
+ "" +
+ "
" +
+ "
${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" %>
+
+
+
+
+
+
+
+
+
+
+ <%= 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" ) %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= 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(
+ "
",
+ 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" %>
+
+
+
+
+
+<%= 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" %>
+
+
+
+
+
+
+<% 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")) { %>
+User Name:
+<%= Html.TextBox( "UserName" ) %>
+<%= Html.ValidationMessage("UserName", "*") %>
+Old password:
+ <%= Html.Password( "OldPassword" ) %>
+<%= Html.ValidationMessage("OldPassword", "*") %>
+New password:
+ <%= Html.Password( "NewPassword" ) %>
+<%= Html.ValidationMessage("NewPassword", "*") %>
+Confirm password:
+ <%= 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" %>
+
+
+
+
+
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", "*") %>
+
+Se souvenir du mot de passe:
+<%= 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%>
+
+
+
+<%= Html.ValidationSummary() %>
+<% using(Html.BeginForm("UpdateProfile", "Account", FormMethod.Post, new { enctype = "multipart/form-data" })) %>
+<% { %>
+
+
+
+<% } %>
+
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" %>
+
+
+
+
+
+
+<%= 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" %>
+
+
+
+
+
+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" %>
+
+
+
+
+
+<%= 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" %>
+
+
+
+
+
+<%= 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" %>
+
+
+
+
+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" %>
+
+
+
+
+
+
+ <%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" %>
+
+
+
+
+
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" %>
+
+
+
+
+
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
+
+
+
+
+<%=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(); %>
+
+<% foreach (string s in bckdirs)
+{
+%>
+<%=s%>
+<%
+}
+%>
+
+Data only :
+<%= 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) %>
+
+
+
+
+
+
+<% 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" %>
+
+
+
+
+
+
+<%= 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) + " " %>
+
+
+
+
+<% 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" } ) %>
+ <% } %>
+
+
+
+<% } %>
+
+
+
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) %>
+
+
+
+
+
+
+ <%= 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"])%>
+
+
+
+
+ <% BBCodeHelper.Init(); %>
+<%= BBCodeHelper.Parser.ToHtml(Model.Content) %>
+
+ <%
+ string username = "";
+ if (Membership.GetUser()!=null)
+ username = Membership.GetUser().UserName; %>
+
+<% foreach (var c in (Comment[])ViewData["Comments"]) { %>
+
+
+<% } %>
+
+
+
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"])%>
+
+
+
+<%
+ 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" } ) %>
+ <% } %>
+
+<% } %>
+
+
+
+
+
\ 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" %>
+
+
+
+
+<% 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 ) { %>
+
+ <% } %>
+
+
+<% } %>
+<% } %>
+
+
+
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 ) { %>
+
+ <% } %>
+
+
+<% } %>
+<% } %>
+
<% } %>
+
+
+
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.Description) %>
+<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %>
+
+<% } %>
+<% 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 ) { %>
+
+ <% } %>
+
+
+
+ <% } %>
+
+
+
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) %>
+
+
+
+
+
<%= Html.Encode(Model.Description) %>
+<% if (Model.Images!=null) foreach (ProductImage i in Model.Images) { %>
+
+<% } %>
+<% 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
+
+
+
+
+
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
+
+
+
+
+
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
+
+
+
+
+
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
+
+
+
+
+
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
+
+
+
+
+
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
+
+
+
+
+
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
+
+
+
+
+
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
+
+ One or more child tests had errors
+
+
+ 2013-11-28T01:02:44
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+
+
+
+
+ 2013-11-28T00:57:03
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ System.Configuration.Provider.ProviderException : Operation aborted due to an exception (see Trace for details). See http://www.mono-project.com/FAQ:_ASP.NET#Common_Problems for additional suggestions.
+ at System.Web.Security.SqliteMembershipProvider.GetUser (System.String username, Boolean userIsOnline) [0x00000] in <filename unknown>:0
+ at System.Web.Security.SqliteMembershipProvider.CreateUser (System.String username, System.String password, System.String email, System.String passwordQuestion, System.String passwordAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password) [0x00000] in <filename unknown>:0
+ at mae.TestProject.TestCreateDropProject () [0x00000] in /home/paul/workspace/mae/mae/TestProject.cs:13
+ at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
+ at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
+
+
+
+
+ 2013-11-28T01:02:44
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ System.Configuration.Provider.ProviderException : Operation aborted due to an exception (see Trace for details). See http://www.mono-project.com/FAQ:_ASP.NET#Common_Problems for additional suggestions.
+ at System.Web.Security.SqliteMembershipProvider.GetUser (System.String username, Boolean userIsOnline) [0x00000] in <filename unknown>:0
+ at System.Web.Security.SqliteMembershipProvider.CreateUser (System.String username, System.String password, System.String email, System.String passwordQuestion, System.String passwordAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password) [0x00000] in <filename unknown>:0
+ at mae.TestProject.TestCreateDropProject () [0x00000] in /home/paul/workspace/mae/mae/TestProject.cs:13
+ at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
+ at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
+
+
+
+
+ 2013-11-28T01:04:49
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ System.Configuration.Provider.ProviderException : Operation aborted due to an exception (see Trace for details). See http://www.mono-project.com/FAQ:_ASP.NET#Common_Problems for additional suggestions.
+ at System.Web.Security.SqliteMembershipProvider.GetUser (System.String username, Boolean userIsOnline) [0x00000] in <filename unknown>:0
+ at System.Web.Security.SqliteMembershipProvider.CreateUser (System.String username, System.String password, System.String email, System.String passwordQuestion, System.String passwordAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password) [0x00000] in <filename unknown>:0
+ at mae.TestProject.TestCreateDropProject () [0x0000b] in /home/paul/workspace/mae/mae/TestProject.cs:14
+ at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
+ at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>: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
+
+ One or more child tests had errors
+
+
+ 2013-12-12T01:29:23
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+
+
+
+
+ 2013-12-12T00:23:40
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+ 2013-12-12T01:29:23
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+
+
+
+
+ 2013-12-12T00:23:40
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+ 2013-12-12T01:29:23
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ One or more child tests had errors
+
+
+
+
+
+
+ 2013-12-12T00:23:40
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ System.Configuration.Provider.ProviderException : Operation aborted due to an exception (see Trace for details). See http://www.mono-project.com/FAQ:_ASP.NET#Common_Problems for additional suggestions.
+ at System.Web.Security.SqliteMembershipProvider.GetUser (System.String username, Boolean userIsOnline) [0x00000] in <filename unknown>:0
+ at System.Web.Security.SqliteMembershipProvider.CreateUser (System.String username, System.String password, System.String email, System.String passwordQuestion, System.String passwordAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password) [0x00000] in <filename unknown>:0
+ at mae.TestProject.TestCreateDropProject () [0x00000] in /home/paul/workspace/mae/mae/Test/TestProject.cs:13
+ at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
+ at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
+
+
+
+
+ 2013-12-12T01:29:23
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ System.Configuration.Provider.ProviderException : Operation aborted due to an exception (see Trace for details). See http://www.mono-project.com/FAQ:_ASP.NET#Common_Problems for additional suggestions.
+ at System.Web.Security.SqliteMembershipProvider.GetUser (System.String username, Boolean userIsOnline) [0x00000] in <filename unknown>:0
+ at System.Web.Security.SqliteMembershipProvider.CreateUser (System.String username, System.String password, System.String email, System.String passwordQuestion, System.String passwordAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Object providerUserKey, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email, System.String pwdQuestion, System.String pwdAnswer, Boolean isApproved, System.Web.Security.MembershipCreateStatus& status) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password, System.String email) [0x00000] in <filename unknown>:0
+ at System.Web.Security.Membership.CreateUser (System.String username, System.String password) [0x00000] in <filename unknown>:0
+ at mae.TestProject.TestCreateDropProject () [0x00000] in /home/paul/workspace/mae/mae/Test/TestProject.cs:13
+ at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
+ at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>: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
+
+ Test réussi
+
+Durée d'exécution : 0,02 ms
+
+
+
\ 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