PageRenderTime 423ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Web.Generics.WebMvc/ApplicationServices/Authentication/AccountModels.cs

https://github.com/stephanspacov/Web.Generics
C# | 288 lines | 230 code | 50 blank | 8 comment | 12 complexity | 39b52b1124fb4abdbbd3e7fd17e25746 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.ComponentModel.DataAnnotations;
  5. using System.Globalization;
  6. using System.Linq;
  7. using System.Web;
  8. using System.Web.Mvc;
  9. using System.Web.Security;
  10. using Web.Generics.UserInterface.Validators;
  11. namespace Web.Generics.UserInterface.Models
  12. {
  13. #region Models
  14. [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")]
  15. public class ChangePasswordModel
  16. {
  17. [Required]
  18. [DataType(DataType.Password)]
  19. [DisplayName("Current password")]
  20. public string OldPassword { get; set; }
  21. [Required]
  22. [ValidatePasswordLength]
  23. [DataType(DataType.Password)]
  24. [DisplayName("New password")]
  25. public string NewPassword { get; set; }
  26. [Required]
  27. [DataType(DataType.Password)]
  28. [DisplayName("Confirm new password")]
  29. public string ConfirmPassword { get; set; }
  30. }
  31. public class LogOnModel
  32. {
  33. [Required]
  34. [DisplayName("User name")]
  35. public string UserName { get; set; }
  36. [Required]
  37. [DataType(DataType.Password)]
  38. [DisplayName("Password")]
  39. public string Password { get; set; }
  40. [DisplayName("Remember me?")]
  41. public bool RememberMe { get; set; }
  42. }
  43. [PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")]
  44. public class RegisterModel
  45. {
  46. [Required]
  47. [DisplayName("User name")]
  48. public string UserName { get; set; }
  49. [Required]
  50. [DataType(DataType.EmailAddress)]
  51. [DisplayName("Email address")]
  52. [Email]
  53. public string Email { get; set; }
  54. [Required]
  55. [ValidatePasswordLength]
  56. [DataType(DataType.Password)]
  57. [DisplayName("Password")]
  58. public string Password { get; set; }
  59. [Required]
  60. [DataType(DataType.Password)]
  61. [DisplayName("Confirm password")]
  62. public string ConfirmPassword { get; set; }
  63. public Boolean ShowMinimumCharaterLengthMessage { get; internal set; }
  64. public Int32 MinimumCharaterLength { get; internal set; }
  65. }
  66. #endregion
  67. #region Services
  68. // The FormsAuthentication type is sealed and contains static members, so it is difficult to
  69. // unit test code that calls its members. The interface and helper class below demonstrate
  70. // how to create an abstract wrapper around such a type in order to make the AccountController
  71. // code unit testable.
  72. public interface IMembershipService
  73. {
  74. int MinPasswordLength { get; }
  75. bool ValidateUser(string userName, string password);
  76. MembershipCreateStatus CreateUser(string userName, string password, string email);
  77. bool ChangePassword(string userName, string oldPassword, string newPassword);
  78. }
  79. public class AccountMembershipService : IMembershipService
  80. {
  81. private readonly MembershipProvider _provider;
  82. public AccountMembershipService()
  83. : this(null)
  84. {
  85. }
  86. public AccountMembershipService(MembershipProvider provider)
  87. {
  88. _provider = provider ?? Membership.Provider;
  89. }
  90. public int MinPasswordLength
  91. {
  92. get
  93. {
  94. return _provider.MinRequiredPasswordLength;
  95. }
  96. }
  97. public bool ValidateUser(string userName, string password)
  98. {
  99. if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
  100. if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
  101. return _provider.ValidateUser(userName, password);
  102. }
  103. public MembershipCreateStatus CreateUser(string userName, string password, string email)
  104. {
  105. if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
  106. if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
  107. if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
  108. MembershipCreateStatus status;
  109. _provider.CreateUser(userName, password, email, null, null, true, null, out status);
  110. return status;
  111. }
  112. public bool ChangePassword(string userName, string oldPassword, string newPassword)
  113. {
  114. if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
  115. if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("Value cannot be null or empty.", "oldPassword");
  116. if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("Value cannot be null or empty.", "newPassword");
  117. // The underlying ChangePassword() will throw an exception rather
  118. // than return false in certain failure scenarios.
  119. try
  120. {
  121. MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
  122. return currentUser.ChangePassword(oldPassword, newPassword);
  123. }
  124. catch (ArgumentException)
  125. {
  126. return false;
  127. }
  128. catch (MembershipPasswordException)
  129. {
  130. return false;
  131. }
  132. }
  133. }
  134. public interface IFormsAuthenticationService
  135. {
  136. void SignIn(string userName, bool createPersistentCookie);
  137. void SignOut();
  138. }
  139. public class FormsAuthenticationService : IFormsAuthenticationService
  140. {
  141. public void SignIn(string userName, bool createPersistentCookie)
  142. {
  143. if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
  144. FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
  145. }
  146. public void SignOut()
  147. {
  148. FormsAuthentication.SignOut();
  149. }
  150. }
  151. #endregion
  152. #region Validation
  153. public static class AccountValidation
  154. {
  155. public static string ErrorCodeToString(MembershipCreateStatus createStatus)
  156. {
  157. // See http://go.microsoft.com/fwlink/?LinkID=177550 for
  158. // a full list of status codes.
  159. switch (createStatus)
  160. {
  161. case MembershipCreateStatus.DuplicateUserName:
  162. return "Username already exists. Please enter a different user name.";
  163. case MembershipCreateStatus.DuplicateEmail:
  164. return "A username for that e-mail address already exists. Please enter a different e-mail address.";
  165. case MembershipCreateStatus.InvalidPassword:
  166. return "The password provided is invalid. Please enter a valid password value.";
  167. case MembershipCreateStatus.InvalidEmail:
  168. return "The e-mail address provided is invalid. Please check the value and try again.";
  169. case MembershipCreateStatus.InvalidAnswer:
  170. return "The password retrieval answer provided is invalid. Please check the value and try again.";
  171. case MembershipCreateStatus.InvalidQuestion:
  172. return "The password retrieval question provided is invalid. Please check the value and try again.";
  173. case MembershipCreateStatus.InvalidUserName:
  174. return "The user name provided is invalid. Please check the value and try again.";
  175. case MembershipCreateStatus.ProviderError:
  176. return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
  177. case MembershipCreateStatus.UserRejected:
  178. return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
  179. default:
  180. return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
  181. }
  182. }
  183. }
  184. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
  185. public sealed class PropertiesMustMatchAttribute : ValidationAttribute
  186. {
  187. private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
  188. private readonly object _typeId = new object();
  189. public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
  190. : base(_defaultErrorMessage)
  191. {
  192. OriginalProperty = originalProperty;
  193. ConfirmProperty = confirmProperty;
  194. }
  195. public string ConfirmProperty { get; private set; }
  196. public string OriginalProperty { get; private set; }
  197. public override object TypeId
  198. {
  199. get
  200. {
  201. return _typeId;
  202. }
  203. }
  204. public override string FormatErrorMessage(string name)
  205. {
  206. return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
  207. OriginalProperty, ConfirmProperty);
  208. }
  209. public override bool IsValid(object value)
  210. {
  211. PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
  212. object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
  213. object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
  214. return Object.Equals(originalValue, confirmValue);
  215. }
  216. }
  217. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  218. public sealed class ValidatePasswordLengthAttribute : ValidationAttribute
  219. {
  220. private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long.";
  221. private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
  222. public ValidatePasswordLengthAttribute()
  223. : base(_defaultErrorMessage)
  224. {
  225. }
  226. public override string FormatErrorMessage(string name)
  227. {
  228. return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
  229. name, _minCharacters);
  230. }
  231. public override bool IsValid(object value)
  232. {
  233. string valueAsString = value as string;
  234. return (valueAsString != null && valueAsString.Length >= _minCharacters);
  235. }
  236. }
  237. #endregion
  238. }