// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; #if DNX451 using System.Net.Mail; #endif using System.Threading.Tasks; namespace Microsoft.AspNet.Identity { /// /// Provides validation services for user classes. /// /// The type encapsulating a user. public class UserValidator : IUserValidator { /// /// Creates a new instance of / /// /// The used to provider error messages. public UserValidator(IdentityErrorDescriber errors = null) { Describer = errors ?? new IdentityErrorDescriber(); } /// /// Gets the used to provider error messages for the current . /// /// Yhe used to provider error messages for the current . public IdentityErrorDescriber Describer { get; private set; } /// /// Validates the specified as an asynchronous operation. /// /// The that can be used to retrieve user properties. /// The user to validate. /// The that represents the asynchronous operation, containing the of the validation operation. public virtual async Task ValidateAsync(UserManager manager, TUser user) where TUser : class { if (manager == null) { throw new ArgumentNullException(nameof(manager)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } var errors = new List(); await ValidateUserName(manager, user, errors); if (manager.Options.User.RequireUniqueEmail) { await ValidateEmail(manager, user, errors); } return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success; } private async Task ValidateUserName(UserManager manager, TUser user, ICollection errors) where TUser : class { var userName = await manager.GetUserNameAsync(user); if (string.IsNullOrWhiteSpace(userName)) { errors.Add(Describer.InvalidUserName(userName)); } else if (!string.IsNullOrEmpty(manager.Options.User.AllowedUserNameCharacters) && userName.Any(c => !manager.Options.User.AllowedUserNameCharacters.Contains(c))) { errors.Add(Describer.InvalidUserName(userName)); } else { var owner = await manager.FindByNameAsync(userName); if (owner != null && !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user))) { errors.Add(Describer.DuplicateUserName(userName)); } } } // make sure email is not empty, valid, and unique private async Task ValidateEmail(UserManager manager, TUser user, List errors) where TUser : class { var email = await manager.GetEmailAsync(user); if (string.IsNullOrWhiteSpace(email)) { errors.Add(Describer.InvalidEmail(email)); return; } #if DNX451 try { var m = new MailAddress(email); } catch (FormatException) { errors.Add(Describer.InvalidEmail(email)); return; } #endif var owner = await manager.FindByEmailAsync(email); if (owner != null && !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user))) { errors.Add(Describer.DuplicateEmail(email)); } } } }