using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Microsoft.AspNet.Identity { /// /// Used to validate some basic password policy like length and number of non alphanumerics /// public class PasswordValidator : IPasswordValidator { /// /// Minimum required length /// public int RequiredLength { get; set; } /// /// Require a non letter or digit character /// public bool RequireNonLetterOrDigit { get; set; } /// /// Require a lower case letter ('a' - 'z') /// public bool RequireLowercase { get; set; } /// /// Require an upper case letter ('A' - 'Z') /// public bool RequireUppercase { get; set; } /// /// Require a digit ('0' - '9') /// public bool RequireDigit { get; set; } /// /// Ensures that the string is of the required length and meets the configured requirements /// /// /// /// public virtual Task Validate(string item, CancellationToken cancellationToken = default(CancellationToken)) { if (item == null) { throw new ArgumentNullException("item"); } var errors = new List(); if (string.IsNullOrWhiteSpace(item) || item.Length < RequiredLength) { errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PasswordTooShort, RequiredLength)); } if (RequireNonLetterOrDigit && item.All(IsLetterOrDigit)) { errors.Add(Resources.PasswordRequireNonLetterOrDigit); } if (RequireDigit && !item.Any(IsDigit)) { errors.Add(Resources.PasswordRequireDigit); } if (RequireLowercase && !item.Any(IsLower)) { errors.Add(Resources.PasswordRequireLower); } if (RequireUppercase && !item.Any(IsUpper)) { errors.Add(Resources.PasswordRequireUpper); } return Task.FromResult(errors.Count == 0 ? IdentityResult.Success : IdentityResult.Failed(String.Join(" ", errors))); } /// /// Returns true if the character is a digit between '0' and '9' /// /// /// public virtual bool IsDigit(char c) { return c >= '0' && c <= '9'; } /// /// Returns true if the character is between 'a' and 'z' /// /// /// public virtual bool IsLower(char c) { return c >= 'a' && c <= 'z'; } /// /// Returns true if the character is between 'A' and 'Z' /// /// /// public virtual bool IsUpper(char c) { return c >= 'A' && c <= 'Z'; } /// /// Returns true if the character is upper, lower, or a digit /// /// /// public virtual bool IsLetterOrDigit(char c) { return IsUpper(c) || IsLower(c) || IsDigit(c); } } }