/Web.Generics.WebMvc/ApplicationServices/Authentication/AccountModels.cs
C# | 288 lines | 230 code | 50 blank | 8 comment | 12 complexity | 39b52b1124fb4abdbbd3e7fd17e25746 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.ComponentModel.DataAnnotations;
- using System.Globalization;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Security;
- using Web.Generics.UserInterface.Validators;
-
- namespace Web.Generics.UserInterface.Models
- {
-
- #region Models
- [PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")]
- public class ChangePasswordModel
- {
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Current password")]
- public string OldPassword { get; set; }
-
- [Required]
- [ValidatePasswordLength]
- [DataType(DataType.Password)]
- [DisplayName("New password")]
- public string NewPassword { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Confirm new password")]
- public string ConfirmPassword { get; set; }
- }
-
- public class LogOnModel
- {
- [Required]
- [DisplayName("User name")]
- public string UserName { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Password")]
- public string Password { get; set; }
-
- [DisplayName("Remember me?")]
- public bool RememberMe { get; set; }
- }
-
- [PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "The password and confirmation password do not match.")]
- public class RegisterModel
- {
- [Required]
- [DisplayName("User name")]
- public string UserName { get; set; }
-
- [Required]
- [DataType(DataType.EmailAddress)]
- [DisplayName("Email address")]
- [Email]
- public string Email { get; set; }
-
- [Required]
- [ValidatePasswordLength]
- [DataType(DataType.Password)]
- [DisplayName("Password")]
- public string Password { get; set; }
-
- [Required]
- [DataType(DataType.Password)]
- [DisplayName("Confirm password")]
- public string ConfirmPassword { get; set; }
-
- public Boolean ShowMinimumCharaterLengthMessage { get; internal set; }
- public Int32 MinimumCharaterLength { get; internal set; }
- }
- #endregion
-
- #region Services
- // The FormsAuthentication type is sealed and contains static members, so it is difficult to
- // unit test code that calls its members. The interface and helper class below demonstrate
- // how to create an abstract wrapper around such a type in order to make the AccountController
- // code unit testable.
-
- public interface IMembershipService
- {
- int MinPasswordLength { get; }
-
- bool ValidateUser(string userName, string password);
- MembershipCreateStatus CreateUser(string userName, string password, string email);
- bool ChangePassword(string userName, string oldPassword, string newPassword);
- }
-
- public class AccountMembershipService : IMembershipService
- {
- private readonly MembershipProvider _provider;
-
- public AccountMembershipService()
- : this(null)
- {
- }
-
- public AccountMembershipService(MembershipProvider provider)
- {
- _provider = provider ?? Membership.Provider;
- }
-
- public int MinPasswordLength
- {
- get
- {
- return _provider.MinRequiredPasswordLength;
- }
- }
-
- public bool ValidateUser(string userName, string password)
- {
- if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
-
- return _provider.ValidateUser(userName, password);
- }
-
- public MembershipCreateStatus CreateUser(string userName, string password, string email)
- {
- if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
- if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
-
- MembershipCreateStatus status;
- _provider.CreateUser(userName, password, email, null, null, true, null, out status);
- return status;
- }
-
- public bool ChangePassword(string userName, string oldPassword, string newPassword)
- {
- if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
- if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("Value cannot be null or empty.", "oldPassword");
- if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("Value cannot be null or empty.", "newPassword");
-
- // The underlying ChangePassword() will throw an exception rather
- // than return false in certain failure scenarios.
- try
- {
- MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
- return currentUser.ChangePassword(oldPassword, newPassword);
- }
- catch (ArgumentException)
- {
- return false;
- }
- catch (MembershipPasswordException)
- {
- return false;
- }
- }
- }
-
- public interface IFormsAuthenticationService
- {
- void SignIn(string userName, bool createPersistentCookie);
- void SignOut();
- }
-
- public class FormsAuthenticationService : IFormsAuthenticationService
- {
- public void SignIn(string userName, bool createPersistentCookie)
- {
- if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
-
- FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
- }
-
- public void SignOut()
- {
- FormsAuthentication.SignOut();
- }
- }
- #endregion
-
- #region Validation
- public static class AccountValidation
- {
- public static string ErrorCodeToString(MembershipCreateStatus createStatus)
- {
- // See http://go.microsoft.com/fwlink/?LinkID=177550 for
- // a full list of status codes.
- switch (createStatus)
- {
- case MembershipCreateStatus.DuplicateUserName:
- return "Username already exists. Please enter a different user name.";
-
- case MembershipCreateStatus.DuplicateEmail:
- return "A username for that e-mail address already exists. Please enter a different e-mail address.";
-
- case MembershipCreateStatus.InvalidPassword:
- return "The password provided is invalid. Please enter a valid password value.";
-
- case MembershipCreateStatus.InvalidEmail:
- return "The e-mail address provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidAnswer:
- return "The password retrieval answer provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidQuestion:
- return "The password retrieval question provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.InvalidUserName:
- return "The user name provided is invalid. Please check the value and try again.";
-
- case MembershipCreateStatus.ProviderError:
- return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
-
- case MembershipCreateStatus.UserRejected:
- return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
-
- default:
- return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
- }
- }
- }
-
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
- public sealed class PropertiesMustMatchAttribute : ValidationAttribute
- {
- private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
- private readonly object _typeId = new object();
-
- public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
- : base(_defaultErrorMessage)
- {
- OriginalProperty = originalProperty;
- ConfirmProperty = confirmProperty;
- }
-
- public string ConfirmProperty { get; private set; }
- public string OriginalProperty { get; private set; }
-
- public override object TypeId
- {
- get
- {
- return _typeId;
- }
- }
-
- public override string FormatErrorMessage(string name)
- {
- return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
- OriginalProperty, ConfirmProperty);
- }
-
- public override bool IsValid(object value)
- {
- PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
- object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
- object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
- return Object.Equals(originalValue, confirmValue);
- }
- }
-
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
- public sealed class ValidatePasswordLengthAttribute : ValidationAttribute
- {
- private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long.";
- private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
-
- public ValidatePasswordLengthAttribute()
- : base(_defaultErrorMessage)
- {
- }
-
- public override string FormatErrorMessage(string name)
- {
- return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
- name, _minCharacters);
- }
-
- public override bool IsValid(object value)
- {
- string valueAsString = value as string;
- return (valueAsString != null && valueAsString.Length >= _minCharacters);
- }
- }
- #endregion
-
- }