diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-07-31 22:01:16 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-07-31 22:01:16 -0700 |
commit | c94c7f8197eda673947a9d1e0c0b3f3c4efca94f (patch) | |
tree | 0f978cfc2de70c54ac81e11d4339da04dff9f27f /samples/OAuthAuthorizationServer/Models/AccountModels.cs | |
parent | 7d38eefb65928a1e80036ec006b0e129dc2cface (diff) | |
download | DotNetOpenAuth-c94c7f8197eda673947a9d1e0c0b3f3c4efca94f.zip DotNetOpenAuth-c94c7f8197eda673947a9d1e0c0b3f3c4efca94f.tar.gz DotNetOpenAuth-c94c7f8197eda673947a9d1e0c0b3f3c4efca94f.tar.bz2 |
Split the OAuthServiceProvider sample into two samples: OAuthAuthorizationServer and OAuthResourceServer.
Renamed OAuthConsumer to OAuthClient.
Diffstat (limited to 'samples/OAuthAuthorizationServer/Models/AccountModels.cs')
-rw-r--r-- | samples/OAuthAuthorizationServer/Models/AccountModels.cs | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/samples/OAuthAuthorizationServer/Models/AccountModels.cs b/samples/OAuthAuthorizationServer/Models/AccountModels.cs new file mode 100644 index 0000000..3ab3c56 --- /dev/null +++ b/samples/OAuthAuthorizationServer/Models/AccountModels.cs @@ -0,0 +1,248 @@ +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; + +namespace OAuthAuthorizationServer.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")] + 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; } + } + #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 + +} |