diff --git a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs index be17ab2866..90b7821565 100644 --- a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Identity /// Provides protection and validation of identity tokens. /// /// The type used to represent a user. - public class DataProtectorTokenProvider : IUserTokenProvider + public class DataProtectorTokenProvider : IUserTokenProvider where TUser : class { /// /// Initializes a new instance of the class. @@ -64,7 +64,7 @@ namespace Microsoft.AspNet.Identity /// The to retrieve user properties from. /// The the token will be generated from. /// A representing the generated token. - public virtual async Task GenerateAsync(string purpose, UserManager manager, TUser user) where TUser : class + public virtual async Task GenerateAsync(string purpose, UserManager manager, TUser user) { if (user == null) { @@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Identity /// A that represents the result of the asynchronous validation, /// containing true if the token is valid, otherwise false. /// - public virtual async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) where TUser : class + public virtual async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) { try { @@ -157,7 +157,7 @@ namespace Microsoft.AspNet.Identity /// containing true if a token generated by this instance can be used as a Two Factor Authentication token, otherwise false. /// /// This method will always return false for instances of . - public virtual Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) where TUser : class + public virtual Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) { return Task.FromResult(false); } @@ -169,7 +169,7 @@ namespace Microsoft.AspNet.Identity /// The to retrieve user properties from. /// The the token was generated for. /// A that represents the asynchronous notification. - public virtual Task NotifyAsync(string token, UserManager manager, TUser user) where TUser : class + public virtual Task NotifyAsync(string token, UserManager manager, TUser user) { return Task.FromResult(0); } diff --git a/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs b/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs index 2833f663cb..31d91de53a 100644 --- a/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs @@ -22,7 +22,8 @@ namespace Microsoft.AspNet.Identity /// TokenProvider that generates tokens from the user's security stamp and notifies a user via email. /// /// The type used to represent a user. - public class EmailTokenProvider : TotpSecurityStampBasedTokenProvider + public class EmailTokenProvider : TotpSecurityStampBasedTokenProvider + where TUser : class { /// /// Initializes a new instance of the class. @@ -60,7 +61,7 @@ namespace Microsoft.AspNet.Identity /// The to retrieve the from. /// The to check for the possibility of generating a two factor authentication token. /// True if the user has an email address set, otherwise false. - public override async Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) + public override async Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) { var email = await manager.GetEmailAsync(user); return !string.IsNullOrWhiteSpace(email) && await manager.IsEmailConfirmedAsync(user); @@ -73,7 +74,8 @@ namespace Microsoft.AspNet.Identity /// The to retrieve the from. /// The to check for the possibility of generating a two factor authentication token. /// A string suitable for use as entropy in token generation. - public override async Task GetUserModifierAsync(string purpose, UserManager manager, TUser user) + public override async Task GetUserModifierAsync(string purpose, UserManager manager, + TUser user) { var email = await manager.GetEmailAsync(user); return "Email:" + purpose + ":" + email; diff --git a/src/Microsoft.AspNet.Identity/IPasswordHasher.cs b/src/Microsoft.AspNet.Identity/IPasswordHasher.cs index c35d389791..b9afb36388 100644 --- a/src/Microsoft.AspNet.Identity/IPasswordHasher.cs +++ b/src/Microsoft.AspNet.Identity/IPasswordHasher.cs @@ -7,7 +7,7 @@ namespace Microsoft.AspNet.Identity /// Provides an abstraction for hashing passwords. /// /// The type used to represent a user. - public interface IPasswordHasher + public interface IPasswordHasher where TUser : class { /// /// Returns a hashed representation of the supplied for the specified . @@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Identity /// The user whose password is to be hashed. /// The password to hash. /// A hashed representation of the supplied for the specified . - string HashPassword(TUser user, string password) where TUser : class; + string HashPassword(TUser user, string password); /// /// Returns a indicating the result of a password hash comparison. @@ -25,6 +25,6 @@ namespace Microsoft.AspNet.Identity /// The password supplied for comparison. /// A indicating the result of a password hash comparison. /// Implementations of this method should be time consistent. - PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword) where TUser : class; + PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IPasswordValidator.cs b/src/Microsoft.AspNet.Identity/IPasswordValidator.cs index ac7083cc63..c9d9b1bb64 100644 --- a/src/Microsoft.AspNet.Identity/IPasswordValidator.cs +++ b/src/Microsoft.AspNet.Identity/IPasswordValidator.cs @@ -1,6 +1,7 @@ // 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.Threading; using System.Threading.Tasks; namespace Microsoft.AspNet.Identity @@ -9,7 +10,7 @@ namespace Microsoft.AspNet.Identity /// Provides an abstraction for validating passwords. /// /// The type that represents a user. - public interface IPasswordValidator + public interface IPasswordValidator where TUser : class { /// /// Validates a password as an asynchronous operation. @@ -18,6 +19,6 @@ namespace Microsoft.AspNet.Identity /// The user whose password should be validated. /// The password supplied for validation /// The task object representing the asynchronous operation. - Task ValidateAsync(UserManager manager, TUser user, string password) where TUser : class; + Task ValidateAsync(UserManager manager, TUser user, string password); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IRoleValidator.cs b/src/Microsoft.AspNet.Identity/IRoleValidator.cs index 080c371741..6659b60470 100644 --- a/src/Microsoft.AspNet.Identity/IRoleValidator.cs +++ b/src/Microsoft.AspNet.Identity/IRoleValidator.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Identity /// Provides an abstraction for a validating a role. /// /// The type encapsulating a role. - public interface IRoleValidator + public interface IRoleValidator where TRole : class { /// /// Validates a role as an asynchronous operation. @@ -17,6 +17,6 @@ namespace Microsoft.AspNet.Identity /// The managing the role store. /// The role to validate. /// A that represents the of the asynchronous validation. - Task ValidateAsync(RoleManager manager, TRole role) where TRole : class; + Task ValidateAsync(RoleManager manager, TRole role); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IUserTokenProvider.cs b/src/Microsoft.AspNet.Identity/IUserTokenProvider.cs index 1b559fe727..ce9ee317be 100644 --- a/src/Microsoft.AspNet.Identity/IUserTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/IUserTokenProvider.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Identity /// Provides an abstraction for token generators. /// /// The type encapsulating a user. - public interface IUserTokenProvider + public interface IUserTokenProvider where TUser : class { /// /// Gets the name of the token provider. @@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Identity /// Implementations of should validate that purpose is not null or empty to /// help with token separation. /// - Task GenerateAsync(string purpose, UserManager manager, TUser user) where TUser : class; + Task GenerateAsync(string purpose, UserManager manager, TUser user); /// /// Returns a flag indicating whether the specified is valid for the given @@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Identity /// of validating the for the specified and . /// The task will return true if the token is valid, otherwise false. /// - Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) where TUser : class; + Task ValidateAsync(string purpose, string token, UserManager manager, TUser user); /// /// Returns a flag indicating whether the token provider can generate a token suitable for two factor authentication token for @@ -64,6 +64,6 @@ namespace Microsoft.AspNet.Identity /// factor token could be generated by this provider for the specified and . /// The task will return true if a two factor authentication token could be generated, otherwise false. /// - Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) where TUser : class; + Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IUserValidator.cs b/src/Microsoft.AspNet.Identity/IUserValidator.cs index 6fb0a4782e..dc4511e9e2 100644 --- a/src/Microsoft.AspNet.Identity/IUserValidator.cs +++ b/src/Microsoft.AspNet.Identity/IUserValidator.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Identity /// Provides an abstraction for user validation. /// /// The type encapsulating a user. - public interface IUserValidator + public interface IUserValidator where TUser : class { /// /// Validates the specified as an asynchronous operation. @@ -18,6 +18,6 @@ namespace Microsoft.AspNet.Identity /// 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. - Task ValidateAsync(UserManager manager, TUser user) where TUser : class; + Task ValidateAsync(UserManager manager, TUser user); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs index f8f46e7a20..bfbbbcb78d 100644 --- a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs +++ b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs @@ -60,10 +60,9 @@ namespace Microsoft.AspNet.Identity /// /// The user type to validate. /// The . - public virtual IdentityBuilder AddUserValidator() where TValidator : class, IUserValidator + public virtual IdentityBuilder AddUserValidator() where T : class { - Services.AddScoped(); - return this; + return AddScoped(typeof(IUserValidator<>).MakeGenericType(UserType), typeof(T)); } /// @@ -71,10 +70,9 @@ namespace Microsoft.AspNet.Identity /// /// The role type to validate. /// The . - public virtual IdentityBuilder AddRoleValidator() where TValidator : class, IRoleValidator + public virtual IdentityBuilder AddRoleValidator() where T : class { - Services.AddScoped(); - return this; + return AddScoped(typeof(IRoleValidator<>).MakeGenericType(RoleType), typeof(T)); } /// @@ -93,10 +91,9 @@ namespace Microsoft.AspNet.Identity /// /// The user type whose password will be validated. /// The . - public virtual IdentityBuilder AddPasswordValidator() where TValidator : class,IPasswordValidator + public virtual IdentityBuilder AddPasswordValidator() where T : class { - Services.AddScoped(); - return this; + return AddScoped(typeof(IPasswordValidator<>).MakeGenericType(UserType), typeof(T)); } /// @@ -124,10 +121,19 @@ namespace Microsoft.AspNet.Identity /// /// The type of the token provider to add. /// The . - public virtual IdentityBuilder AddTokenProvider() where TProvider : class, IUserTokenProvider + public virtual IdentityBuilder AddTokenProvider() where TProvider : class { - Services.AddScoped(); - return this; + return AddTokenProvider(typeof(TProvider)); + } + + /// + /// Adds a token provider for the . + /// + /// The type of the to add. + /// The . + public virtual IdentityBuilder AddTokenProvider(Type provider) + { + return AddScoped(typeof(IUserTokenProvider<>).MakeGenericType(UserType), provider); } /// @@ -141,9 +147,9 @@ namespace Microsoft.AspNet.Identity options.Name = Resources.DefaultTokenProvider; }); - return AddTokenProvider() - .AddTokenProvider() - .AddTokenProvider(); + return AddTokenProvider(typeof(DataProtectorTokenProvider<>).MakeGenericType(UserType)) + .AddTokenProvider(typeof(PhoneNumberTokenProvider<>).MakeGenericType(UserType)) + .AddTokenProvider(typeof(EmailTokenProvider<>).MakeGenericType(UserType)); } /// diff --git a/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs index 8fc52dc376..c3f60840e2 100644 --- a/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs @@ -83,11 +83,11 @@ namespace Microsoft.Framework.DependencyInjection services.AddAuthentication(); // Identity services - services.TryAdd(ServiceDescriptor.Scoped()); - services.TryAdd(ServiceDescriptor.Scoped()); - services.TryAdd(ServiceDescriptor.Scoped()); + services.TryAdd(ServiceDescriptor.Scoped, UserValidator>()); + services.TryAdd(ServiceDescriptor.Scoped, PasswordValidator>()); + services.TryAdd(ServiceDescriptor.Scoped, PasswordHasher>()); services.TryAdd(ServiceDescriptor.Scoped()); - services.TryAdd(ServiceDescriptor.Scoped()); + services.TryAdd(ServiceDescriptor.Scoped, RoleValidator>()); // No interface for the error describer so we can add errors without rev'ing the interface services.TryAdd(ServiceDescriptor.Scoped()); services.TryAdd(ServiceDescriptor.Scoped>()); diff --git a/src/Microsoft.AspNet.Identity/PasswordHasher.cs b/src/Microsoft.AspNet.Identity/PasswordHasher.cs index 2ae91e261d..31397802d9 100644 --- a/src/Microsoft.AspNet.Identity/PasswordHasher.cs +++ b/src/Microsoft.AspNet.Identity/PasswordHasher.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Identity /// Implements the standard Identity password hashing. /// /// The type used to represent a user. - public class PasswordHasher: IPasswordHasher + public class PasswordHasher : IPasswordHasher where TUser : class { /* ======================= * HASHED PASSWORD FORMATS @@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Identity /// The user whose password is to be hashed. /// The password to hash. /// A hashed representation of the supplied for the specified . - public virtual string HashPassword(TUser user, string password) where TUser : class + public virtual string HashPassword(TUser user, string password) { if (password == null) { @@ -168,7 +168,7 @@ namespace Microsoft.AspNet.Identity /// The password supplied for comparison. /// A indicating the result of a password hash comparison. /// Implementations of this method should be time consistent. - public virtual PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword) where TUser : class + public virtual PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword) { if (hashedPassword == null) { diff --git a/src/Microsoft.AspNet.Identity/PasswordValidator.cs b/src/Microsoft.AspNet.Identity/PasswordValidator.cs index 3ec3ea366c..6cf08804bf 100644 --- a/src/Microsoft.AspNet.Identity/PasswordValidator.cs +++ b/src/Microsoft.AspNet.Identity/PasswordValidator.cs @@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Identity /// Provides the default password policy for Identity. /// /// The type that represents a user. - public class PasswordValidator : IPasswordValidator + public class PasswordValidator : IPasswordValidator where TUser : class { /// - /// Constructions a new instance of . + /// Constructions a new instance of . /// /// The to retrieve error text from. public PasswordValidator(IdentityErrorDescriber errors = null) @@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Identity /// The user whose password should be validated. /// The password supplied for validation /// The task object representing the asynchronous operation. - public virtual Task ValidateAsync(UserManager manager, TUser user, string password) where TUser : class + public virtual Task ValidateAsync(UserManager manager, TUser user, string password) { if (password == null) { diff --git a/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs b/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs index 3fbbcf4dbf..f90b3a02f3 100644 --- a/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs @@ -23,7 +23,8 @@ namespace Microsoft.AspNet.Identity /// sends them to the user via their phone number. /// /// The type encapsulating a user. - public class PhoneNumberTokenProvider : TotpSecurityStampBasedTokenProvider + public class PhoneNumberTokenProvider : TotpSecurityStampBasedTokenProvider + where TUser : class { /// /// Creates a new instance of with the specified . @@ -62,7 +63,7 @@ namespace Microsoft.AspNet.Identity /// The task will return true if a two factor authentication token could be generated as the user has /// a telephone number, otherwise false. /// - public override async Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) + public override async Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) { if (manager == null) { @@ -82,7 +83,7 @@ namespace Microsoft.AspNet.Identity /// The that represents the asynchronous operation, containing a constant modifier for the specified /// and . /// - public override async Task GetUserModifierAsync(string purpose, UserManager manager, TUser user) + public override async Task GetUserModifierAsync(string purpose, UserManager manager, TUser user) { if (manager == null) { diff --git a/src/Microsoft.AspNet.Identity/RoleManager.cs b/src/Microsoft.AspNet.Identity/RoleManager.cs index 1ee3a6e93f..345d6ffb75 100644 --- a/src/Microsoft.AspNet.Identity/RoleManager.cs +++ b/src/Microsoft.AspNet.Identity/RoleManager.cs @@ -4,9 +4,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Framework.Logging; @@ -32,7 +34,7 @@ namespace Microsoft.AspNet.Identity /// The logger used to log messages, warnings and errors. /// The accessor used to access the . public RoleManager(IRoleStore store, - IEnumerable roleValidators, + IEnumerable> roleValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, ILogger> logger, @@ -75,7 +77,7 @@ namespace Microsoft.AspNet.Identity /// Gets a list of validators for roles to call before persistence. /// /// A list of validators for roles to call before persistence. - internal IList RoleValidators { get; } = new List(); + internal IList> RoleValidators { get; } = new List>(); /// /// Gets the used to provider error messages. diff --git a/src/Microsoft.AspNet.Identity/RoleValidator.cs b/src/Microsoft.AspNet.Identity/RoleValidator.cs index 060e6efd44..0f4c94e8b6 100644 --- a/src/Microsoft.AspNet.Identity/RoleValidator.cs +++ b/src/Microsoft.AspNet.Identity/RoleValidator.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Identity /// Provides the default validation of roles. /// /// The type encapsulating a role. - public class RoleValidator : IRoleValidator + public class RoleValidator : IRoleValidator where TRole : class { /// /// Creates a new instance of / @@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Identity /// The managing the role store. /// The role to validate. /// A that represents the of the asynchronous validation. - public virtual async Task ValidateAsync(RoleManager manager, TRole role) where TRole : class + public virtual async Task ValidateAsync(RoleManager manager, TRole role) { if (manager == null) { @@ -49,8 +49,8 @@ namespace Microsoft.AspNet.Identity return IdentityResult.Success; } - private async Task ValidateRoleName(RoleManager manager, TRole role, - ICollection errors) where TRole : class + private async Task ValidateRoleName(RoleManager manager, TRole role, + ICollection errors) { var roleName = await manager.GetRoleNameAsync(role); if (string.IsNullOrWhiteSpace(roleName)) diff --git a/src/Microsoft.AspNet.Identity/TotpSecurityStampBasedTokenProvider.cs b/src/Microsoft.AspNet.Identity/TotpSecurityStampBasedTokenProvider.cs index 03369781b8..d77872a449 100644 --- a/src/Microsoft.AspNet.Identity/TotpSecurityStampBasedTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/TotpSecurityStampBasedTokenProvider.cs @@ -9,7 +9,8 @@ namespace Microsoft.AspNet.Identity /// Represents a token provider that generates time based codes using the user's security stamp. /// /// The type encapsulating a user. - public abstract class TotpSecurityStampBasedTokenProvider : IUserTokenProvider + public abstract class TotpSecurityStampBasedTokenProvider : IUserTokenProvider + where TUser : class { /// /// Gets the name of the token provider. @@ -36,7 +37,7 @@ namespace Microsoft.AspNet.Identity /// Implementations of should validate that purpose is not null or empty to /// help with token separation. /// - public virtual async Task GenerateAsync(string purpose, UserManager manager, TUser user) where TUser : class + public virtual async Task GenerateAsync(string purpose, UserManager manager, TUser user) { if (manager == null) { @@ -60,7 +61,7 @@ namespace Microsoft.AspNet.Identity /// of validating the for the specified and . /// The task will return true if the token is valid, otherwise false. /// - public virtual async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) where TUser : class + public virtual async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) { if (manager == null) { @@ -86,7 +87,7 @@ namespace Microsoft.AspNet.Identity /// The that represents the asynchronous operation, containing a constant modifier for the specified /// and . /// - public virtual async Task GetUserModifierAsync(string purpose, UserManager manager, TUser user) where TUser : class + public virtual async Task GetUserModifierAsync(string purpose, UserManager manager, TUser user) { if (manager == null) { @@ -107,6 +108,6 @@ namespace Microsoft.AspNet.Identity /// factor token could be generated by this provider for the specified and . /// The task will return true if a two factor authentication token could be generated, otherwise false. /// - public abstract Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) where TUser : class; + public abstract Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/UserManager.cs b/src/Microsoft.AspNet.Identity/UserManager.cs index 05ea7babcc..a8fcbe9a70 100644 --- a/src/Microsoft.AspNet.Identity/UserManager.cs +++ b/src/Microsoft.AspNet.Identity/UserManager.cs @@ -23,8 +23,8 @@ namespace Microsoft.AspNet.Identity /// The type encapsulating a user. public class UserManager : IDisposable where TUser : class { - private readonly Dictionary _tokenProviders = - new Dictionary(); + private readonly Dictionary> _tokenProviders = + new Dictionary>(); private TimeSpan _defaultLockout = TimeSpan.Zero; private bool _disposed; @@ -46,12 +46,12 @@ namespace Microsoft.AspNet.Identity /// The accessor used to access the . public UserManager(IUserStore store, IOptions optionsAccessor, - IPasswordHasher passwordHasher, - IEnumerable userValidators, - IEnumerable passwordValidators, + IPasswordHasher passwordHasher, + IEnumerable> userValidators, + IEnumerable> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, - IEnumerable tokenProviders, + IEnumerable> tokenProviders, ILogger> logger, IHttpContextAccessor contextAccessor) { @@ -105,11 +105,11 @@ namespace Microsoft.AspNet.Identity /// protected internal virtual ILogger Logger { get; set; } - internal IPasswordHasher PasswordHasher { get; set; } + internal IPasswordHasher PasswordHasher { get; set; } - internal IList UserValidators { get; } = new List(); + internal IList> UserValidators { get; } = new List>(); - internal IList PasswordValidators { get; } = new List(); + internal IList> PasswordValidators { get; } = new List>(); internal ILookupNormalizer KeyNormalizer { get; set; } @@ -1557,7 +1557,7 @@ namespace Microsoft.AspNet.Identity /// Registers a token provider. /// /// The provider to register. - public virtual void RegisterTokenProvider(IUserTokenProvider provider) + public virtual void RegisterTokenProvider(IUserTokenProvider provider) { ThrowIfDisposed(); if (provider == null) diff --git a/src/Microsoft.AspNet.Identity/UserValidator.cs b/src/Microsoft.AspNet.Identity/UserValidator.cs index a7656ce7fa..686e3b92b7 100644 --- a/src/Microsoft.AspNet.Identity/UserValidator.cs +++ b/src/Microsoft.AspNet.Identity/UserValidator.cs @@ -7,6 +7,8 @@ using System.Linq; #if DNX451 using System.Net.Mail; #endif +using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; namespace Microsoft.AspNet.Identity @@ -15,7 +17,7 @@ namespace Microsoft.AspNet.Identity /// Provides validation services for user classes. /// /// The type encapsulating a user. - public class UserValidator : IUserValidator + public class UserValidator : IUserValidator where TUser : class { /// /// Creates a new instance of / @@ -38,7 +40,7 @@ namespace Microsoft.AspNet.Identity /// 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 + public virtual async Task ValidateAsync(UserManager manager, TUser user) { if (manager == null) { @@ -57,7 +59,7 @@ namespace Microsoft.AspNet.Identity return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success; } - private async Task ValidateUserName(UserManager manager, TUser user, ICollection errors) where TUser : class + private async Task ValidateUserName(UserManager manager, TUser user, ICollection errors) { var userName = await manager.GetUserNameAsync(user); if (string.IsNullOrWhiteSpace(userName)) @@ -81,7 +83,7 @@ namespace Microsoft.AspNet.Identity } // make sure email is not empty, valid, and unique - private async Task ValidateEmail(UserManager manager, TUser user, List errors) where TUser : class + private async Task ValidateEmail(UserManager manager, TUser user, List errors) { var email = await manager.GetEmailAsync(user); if (string.IsNullOrWhiteSpace(email)) diff --git a/test/Microsoft.AspNet.Identity.Test/IdentityBuilderTest.cs b/test/Microsoft.AspNet.Identity.Test/IdentityBuilderTest.cs index 5093f42b4c..7724233c86 100644 --- a/test/Microsoft.AspNet.Identity.Test/IdentityBuilderTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/IdentityBuilderTest.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Identity.Test { var services = new ServiceCollection(); services.AddIdentity().AddRoleValidator(); - var thingy = services.BuildServiceProvider().GetRequiredService() as MyUberThingy; + var thingy = services.BuildServiceProvider().GetRequiredService>() as MyUberThingy; Assert.NotNull(thingy); } @@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Identity.Test { var services = new ServiceCollection(); services.AddIdentity().AddUserValidator(); - var thingy = services.BuildServiceProvider().GetRequiredService() as MyUberThingy; + var thingy = services.BuildServiceProvider().GetRequiredService>() as MyUberThingy; Assert.NotNull(thingy); } @@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Identity.Test { var services = new ServiceCollection(); services.AddIdentity().AddPasswordValidator(); - var thingy = services.BuildServiceProvider().GetRequiredService() as MyUberThingy; + var thingy = services.BuildServiceProvider().GetRequiredService>() as MyUberThingy; Assert.NotNull(thingy); } @@ -88,13 +88,13 @@ namespace Microsoft.AspNet.Identity.Test services.AddIdentity(); var provider = services.BuildServiceProvider(); - var userValidator = provider.GetRequiredService() as UserValidator; + var userValidator = provider.GetRequiredService>() as UserValidator; Assert.NotNull(userValidator); - var pwdValidator = provider.GetRequiredService() as PasswordValidator; + var pwdValidator = provider.GetRequiredService>() as PasswordValidator; Assert.NotNull(pwdValidator); - var hasher = provider.GetRequiredService() as PasswordHasher; + var hasher = provider.GetRequiredService>() as PasswordHasher; Assert.NotNull(hasher); } @@ -105,11 +105,11 @@ namespace Microsoft.AspNet.Identity.Test services.AddIdentity().AddDefaultTokenProviders(); var provider = services.BuildServiceProvider(); - var tokenProviders = provider.GetRequiredService>(); + var tokenProviders = provider.GetRequiredService>>(); Assert.Equal(3, tokenProviders.Count()); } - private class MyUberThingy : IUserValidator, IPasswordValidator, IRoleValidator, IUserStore, IRoleStore + private class MyUberThingy : IUserValidator, IPasswordValidator, IRoleValidator, IUserStore, IRoleStore { public Task CreateAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken)) { @@ -221,21 +221,6 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task ValidateAsync(RoleManager manager, TRole role) where TRole : class - { - throw new NotImplementedException(); - } - - public Task ValidateAsync(UserManager manager, TUser user) where TUser : class - { - throw new NotImplementedException(); - } - - public Task ValidateAsync(UserManager manager, TUser user, string password) where TUser : class - { - throw new NotImplementedException(); - } - Task IRoleStore.FindByIdAsync(string roleId, CancellationToken cancellationToken) { throw new NotImplementedException(); @@ -255,7 +240,7 @@ namespace Microsoft.AspNet.Identity.Test private class MyRoleManager : RoleManager { public MyRoleManager(IRoleStore store, - IEnumerable roleValidators) : base(store, null, null, null, null, null) + IEnumerable> roleValidators) : base(store, null, null, null, null, null) { } diff --git a/test/Microsoft.AspNet.Identity.Test/PasswordHasherTest.cs b/test/Microsoft.AspNet.Identity.Test/PasswordHasherTest.cs index cae91e3550..76ccbcb7a5 100644 --- a/test/Microsoft.AspNet.Identity.Test/PasswordHasherTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/PasswordHasherTest.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Identity.Test // Act & assert var ex = Assert.Throws(() => { - new TestPasswordHasher(compatMode: (PasswordHasherCompatibilityMode)(-1)); + new PasswordHasher(compatMode: (PasswordHasherCompatibilityMode)(-1)); }); Assert.Equal("The provided PasswordHasherCompatibilityMode is invalid.", ex.Message); } @@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test // Act & assert var ex = Assert.Throws(() => { - new TestPasswordHasher(iterCount: iterCount); + new PasswordHasher(iterCount: iterCount); }); Assert.Equal("The iteration count must be a positive integer.", ex.Message); } @@ -40,15 +40,15 @@ namespace Microsoft.AspNet.Identity.Test public void FullRoundTrip(PasswordHasherCompatibilityMode compatMode) { // Arrange - var hasher = new TestPasswordHasher(compatMode: compatMode); + var hasher = new PasswordHasher(compatMode: compatMode); // Act & assert - success case - var hashedPassword = hasher.HashPassword(null, "password 1"); - var successResult = hasher.VerifyHashedPassword(null, hashedPassword, "password 1"); + var hashedPassword = hasher.HashPassword(null, "password 1"); + var successResult = hasher.VerifyHashedPassword(null, hashedPassword, "password 1"); Assert.Equal(PasswordVerificationResult.Success, successResult); // Act & assert - failure case - var failedResult = hasher.VerifyHashedPassword(null, hashedPassword, "password 2"); + var failedResult = hasher.VerifyHashedPassword(null, hashedPassword, "password 2"); Assert.Equal(PasswordVerificationResult.Failed, failedResult); } @@ -56,10 +56,10 @@ namespace Microsoft.AspNet.Identity.Test public void HashPassword_DefaultsToVersion3() { // Arrange - var hasher = new TestPasswordHasher(compatMode: null); + var hasher = new PasswordHasher(compatMode: null); // Act - string retVal = hasher.HashPassword(null, "my password"); + string retVal = hasher.HashPassword(null, "my password"); // Assert Assert.Equal("AQAAAAEAACcQAAAAEAABAgMEBQYHCAkKCwwNDg+yWU7rLgUwPZb1Itsmra7cbxw2EFpwpVFIEtP+JIuUEw==", retVal); @@ -69,10 +69,10 @@ namespace Microsoft.AspNet.Identity.Test public void HashPassword_Version2() { // Arrange - var hasher = new TestPasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV2); + var hasher = new PasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV2); // Act - string retVal = hasher.HashPassword(null, "my password"); + string retVal = hasher.HashPassword(null, "my password"); // Assert Assert.Equal("AAABAgMEBQYHCAkKCwwNDg+ukCEMDf0yyQ29NYubggHIVY0sdEUfdyeM+E1LtH1uJg==", retVal); @@ -82,10 +82,10 @@ namespace Microsoft.AspNet.Identity.Test public void HashPassword_Version3() { // Arrange - var hasher = new TestPasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV3); + var hasher = new PasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV3); // Act - string retVal = hasher.HashPassword(null, "my password"); + string retVal = hasher.HashPassword(null, "my password"); // Assert Assert.Equal("AQAAAAEAACcQAAAAEAABAgMEBQYHCAkKCwwNDg+yWU7rLgUwPZb1Itsmra7cbxw2EFpwpVFIEtP+JIuUEw==", retVal); @@ -106,7 +106,7 @@ namespace Microsoft.AspNet.Identity.Test var hasher = new PasswordHasher(); // Act - var result = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); + var result = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); // Assert Assert.Equal(PasswordVerificationResult.Failed, result); @@ -123,10 +123,10 @@ namespace Microsoft.AspNet.Identity.Test public void VerifyHashedPassword_Version2CompatMode_SuccessCases(string hashedPassword) { // Arrange - var hasher = new TestPasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV2); + var hasher = new PasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV2); // Act - var result = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); + var result = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); // Assert Assert.Equal(PasswordVerificationResult.Success, result); @@ -143,18 +143,18 @@ namespace Microsoft.AspNet.Identity.Test public void VerifyHashedPassword_Version3CompatMode_SuccessCases(string hashedPassword, PasswordVerificationResult expectedResult) { // Arrange - var hasher = new TestPasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV3); + var hasher = new PasswordHasher(compatMode: PasswordHasherCompatibilityMode.IdentityV3); // Act - var actualResult = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); + var actualResult = hasher.VerifyHashedPassword(null, hashedPassword, "my password"); // Assert Assert.Equal(expectedResult, actualResult); } - private sealed class TestPasswordHasher : PasswordHasher + private sealed class PasswordHasher : PasswordHasher { - public TestPasswordHasher(PasswordHasherCompatibilityMode? compatMode = null, int? iterCount = null) + public PasswordHasher(PasswordHasherCompatibilityMode? compatMode = null, int? iterCount = null) : base(BuildOptions(compatMode, iterCount)) { } diff --git a/test/Microsoft.AspNet.Identity.Test/PasswordValidatorTest.cs b/test/Microsoft.AspNet.Identity.Test/PasswordValidatorTest.cs index 4a0131b776..3ef4288d44 100644 --- a/test/Microsoft.AspNet.Identity.Test/PasswordValidatorTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/PasswordValidatorTest.cs @@ -26,12 +26,12 @@ namespace Microsoft.AspNet.Identity.Test public async Task ValidateThrowsWithNullTest() { // Setup - var validator = new PasswordValidator(); + var validator = new PasswordValidator(); // Act // Assert - await Assert.ThrowsAsync("password", () => validator.ValidateAsync(null, null, null)); - await Assert.ThrowsAsync("manager", () => validator.ValidateAsync(null, null, "foo")); + await Assert.ThrowsAsync("password", () => validator.ValidateAsync(null, null, null)); + await Assert.ThrowsAsync("manager", () => validator.ValidateAsync(null, null, "foo")); } @@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Identity.Test { const string error = "Passwords must be at least 6 characters."; var manager = MockHelpers.TestUserManager(); - var valid = new PasswordValidator(); + var valid = new PasswordValidator(); manager.Options.Password.RequireUppercase = false; manager.Options.Password.RequireNonLetterOrDigit = false; manager.Options.Password.RequireLowercase = false; @@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task SuccessIfLongEnoughTests(string input) { var manager = MockHelpers.TestUserManager(); - var valid = new PasswordValidator(); + var valid = new PasswordValidator(); manager.Options.Password.RequireUppercase = false; manager.Options.Password.RequireNonLetterOrDigit = false; manager.Options.Password.RequireLowercase = false; @@ -71,7 +71,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task FailsWithoutRequiredNonAlphanumericTests(string input) { var manager = MockHelpers.TestUserManager(); - var valid = new PasswordValidator(); + var valid = new PasswordValidator(); manager.Options.Password.RequireUppercase = false; manager.Options.Password.RequireNonLetterOrDigit = true; manager.Options.Password.RequireLowercase = false; @@ -88,7 +88,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task SucceedsWithRequiredNonAlphanumericTests(string input) { var manager = MockHelpers.TestUserManager(); - var valid = new PasswordValidator(); + var valid = new PasswordValidator(); manager.Options.Password.RequireUppercase = false; manager.Options.Password.RequireNonLetterOrDigit = true; manager.Options.Password.RequireLowercase = false; @@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Identity.Test const string digitError = "Passwords must have at least one digit ('0'-'9')."; const string lengthError = "Passwords must be at least 6 characters."; var manager = MockHelpers.TestUserManager(); - var valid = new PasswordValidator(); + var valid = new PasswordValidator(); var errors = new List(); if ((errorMask & Errors.Length) != Errors.None) { diff --git a/test/Microsoft.AspNet.Identity.Test/RoleValidatorTest.cs b/test/Microsoft.AspNet.Identity.Test/RoleValidatorTest.cs index 1fe45a9230..2c559f7ce1 100644 --- a/test/Microsoft.AspNet.Identity.Test/RoleValidatorTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/RoleValidatorTest.cs @@ -13,12 +13,12 @@ namespace Microsoft.AspNet.Identity.Test public async Task ValidateThrowsWithNull() { // Setup - var validator = new RoleValidator(); + var validator = new RoleValidator(); var manager = MockHelpers.TestRoleManager(); // Act // Assert - await Assert.ThrowsAsync("manager", async () => await validator.ValidateAsync(null, null)); + await Assert.ThrowsAsync("manager", async () => await validator.ValidateAsync(null, null)); await Assert.ThrowsAsync("role", async () => await validator.ValidateAsync(manager, null)); } @@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task ValidateFailsWithTooShortRoleName(string input) { // Setup - var validator = new RoleValidator(); + var validator = new RoleValidator(); var manager = MockHelpers.TestRoleManager(); var user = new TestRole {Name = input}; diff --git a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs index 99f57d8771..f156d5a7a7 100644 --- a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs @@ -415,7 +415,7 @@ namespace Microsoft.AspNet.Identity.Test { // Setup var store = new Mock>(); - var hasher = new Mock(); + var hasher = new Mock>(); var user = new TestUser { UserName = "Foo" }; var pwd = "password"; var hashed = "hashed"; @@ -630,9 +630,9 @@ namespace Microsoft.AspNet.Identity.Test // TODO: Can switch to Mock eventually var manager = MockHelpers.TestUserManager(new EmptyStore()); manager.PasswordValidators.Clear(); - manager.PasswordValidators.Add(new BadPasswordValidator()); + manager.PasswordValidators.Add(new BadPasswordValidator()); IdentityResultAssert.IsFailure(await manager.CreateAsync(new TestUser(), "password"), - BadPasswordValidator.ErrorMessage); + BadPasswordValidator.ErrorMessage); } [Fact] @@ -819,11 +819,11 @@ namespace Microsoft.AspNet.Identity.Test await Assert.ThrowsAsync(() => manager.ConfirmEmailAsync(null, null)); } - private class BadPasswordValidator : IPasswordValidator + private class BadPasswordValidator : IPasswordValidator where TUser : class { public static readonly IdentityError ErrorMessage = new IdentityError { Description = "I'm Bad." }; - Task IPasswordValidator.ValidateAsync(UserManager manager, TUser user, string password) + public Task ValidateAsync(UserManager manager, TUser user, string password) { return Task.FromResult(IdentityResult.Failed(ErrorMessage)); } @@ -1090,21 +1090,26 @@ namespace Microsoft.AspNet.Identity.Test } } - private class NoOpTokenProvider : IUserTokenProvider + private class NoOpTokenProvider : IUserTokenProvider { public string Name { get; } = "Noop"; - public Task GenerateAsync(string purpose, UserManager manager, TUser user) where TUser : class + public Task GenerateAsync(string purpose, UserManager manager, TestUser user) { return Task.FromResult("Test"); } - public Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) where TUser : class + public Task ValidateAsync(string purpose, string token, UserManager manager, TestUser user) { return Task.FromResult(true); } - public Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) where TUser : class + public Task NotifyAsync(string token, UserManager manager, TestUser user) + { + return Task.FromResult(0); + } + + public Task CanGenerateTwoFactorTokenAsync(UserManager manager, TestUser user) { return Task.FromResult(true); } diff --git a/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs b/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs index 2429ee97e7..1fc1553f9e 100644 --- a/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs @@ -14,11 +14,11 @@ namespace Microsoft.AspNet.Identity.Test { // Setup var manager = MockHelpers.TestUserManager(new NoopUserStore()); - var validator = new UserValidator(); + var validator = new UserValidator(); // Act // Assert - await Assert.ThrowsAsync("manager", () => validator.ValidateAsync(null, null)); + await Assert.ThrowsAsync("manager", () => validator.ValidateAsync(null, null)); await Assert.ThrowsAsync("user", () => validator.ValidateAsync(manager, null)); } @@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test { // Setup var manager = MockHelpers.TestUserManager(new NoopUserStore()); - var validator = new UserValidator(); + var validator = new UserValidator(); var user = new TestUser {UserName = input}; // Act @@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Identity.Test { // Setup var manager = MockHelpers.TestUserManager(new NoopUserStore()); - var validator = new UserValidator(); + var validator = new UserValidator(); var user = new TestUser {UserName = userName}; // Act @@ -78,7 +78,7 @@ namespace Microsoft.AspNet.Identity.Test // Setup var manager = MockHelpers.TestUserManager(new NoopUserStore()); manager.Options.User.AllowedUserNameCharacters = null; - var validator = new UserValidator(); + var validator = new UserValidator(); var user = new TestUser {UserName = userName}; // Act diff --git a/test/Shared/MockHelpers.cs b/test/Shared/MockHelpers.cs index a939bb1e1c..bf2a025992 100644 --- a/test/Shared/MockHelpers.cs +++ b/test/Shared/MockHelpers.cs @@ -22,16 +22,16 @@ namespace Microsoft.AspNet.Identity.Test { var store = new Mock>(); var mgr = new Mock>(store.Object, null, null, null, null, null, null, null, null, null); - mgr.Object.UserValidators.Add(new UserValidator()); - mgr.Object.PasswordValidators.Add(new PasswordValidator()); + mgr.Object.UserValidators.Add(new UserValidator()); + mgr.Object.PasswordValidators.Add(new PasswordValidator()); return mgr; } public static Mock> MockRoleManager(IRoleStore store = null) where TRole : class { store = store ?? new Mock>().Object; - var roles = new List(); - roles.Add(new RoleValidator()); + var roles = new List>(); + roles.Add(new RoleValidator()); return new Mock>(store, roles, null, null, null, null); } @@ -71,14 +71,14 @@ namespace Microsoft.AspNet.Identity.Test var idOptions = new IdentityOptions(); idOptions.Lockout.AllowedForNewUsers = false; options.Setup(o => o.Options).Returns(idOptions); - var userValidators = new List(); - var validator = new Mock(); + var userValidators = new List>(); + var validator = new Mock>(); userValidators.Add(validator.Object); - var pwdValidators = new List(); - pwdValidators.Add(new PasswordValidator()); - var userManager = new UserManager(store, options.Object, new PasswordHasher(), + var pwdValidators = new List>(); + pwdValidators.Add(new PasswordValidator()); + var userManager = new UserManager(store, options.Object, new PasswordHasher(), userValidators, pwdValidators, new UpperInvariantLookupNormalizer(), - new IdentityErrorDescriber(), Enumerable.Empty(), + new IdentityErrorDescriber(), Enumerable.Empty>(), new Mock>>().Object, null); validator.Setup(v => v.ValidateAsync(userManager, It.IsAny())) @@ -89,8 +89,8 @@ namespace Microsoft.AspNet.Identity.Test public static RoleManager TestRoleManager(IRoleStore store = null) where TRole : class { store = store ?? new Mock>().Object; - var roles = new List(); - roles.Add(new RoleValidator()); + var roles = new List>(); + roles.Add(new RoleValidator()); return new RoleManager(store, roles, new UpperInvariantLookupNormalizer(), new IdentityErrorDescriber(), diff --git a/test/Shared/UserManagerTestBase.cs b/test/Shared/UserManagerTestBase.cs index a3288bcf75..98750065cc 100644 --- a/test/Shared/UserManagerTestBase.cs +++ b/test/Shared/UserManagerTestBase.cs @@ -163,7 +163,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.Options.User.RequireUniqueEmail = true; - manager.UserValidators.Add(new UserValidator()); + manager.UserValidators.Add(new UserValidator()); var random = new Random(); var email = "foo" + random.Next() + "@example.com"; var newEmail = "bar" + random.Next() + "@example.com"; @@ -646,21 +646,26 @@ namespace Microsoft.AspNet.Identity.Test Assert.False(await manager.IsEmailConfirmedAsync(user)); } - private class StaticTokenProvider : IUserTokenProvider + private class StaticTokenProvider : IUserTokenProvider { public string Name { get; } = "Static"; - async Task IUserTokenProvider.GenerateAsync(string purpose, UserManager manager, TUser1 user) + public async Task GenerateAsync(string purpose, UserManager manager, TUser user) { return MakeToken(purpose, await manager.GetUserIdAsync(user)); } - async Task IUserTokenProvider.ValidateAsync(string purpose, string token, UserManager manager, TUser1 user) + public async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) { return token == MakeToken(purpose, await manager.GetUserIdAsync(user)); } - - Task IUserTokenProvider.CanGenerateTwoFactorTokenAsync(UserManager manager, TUser1 user) + + public Task NotifyAsync(string token, UserManager manager, TUser user) + { + return Task.FromResult(0); + } + + public Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) { return Task.FromResult(true); } @@ -976,21 +981,22 @@ namespace Microsoft.AspNet.Identity.Test Assert.True(await manager.RoleExistsAsync(roleName)); } - private class AlwaysBadValidator : IUserValidator, IRoleValidator, IPasswordValidator + private class AlwaysBadValidator : IUserValidator, IRoleValidator, + IPasswordValidator { public static readonly IdentityError ErrorMessage = new IdentityError { Description = "I'm Bad.", Code = "BadValidator" }; - Task IPasswordValidator.ValidateAsync(UserManager manager, T user, string password) + public Task ValidateAsync(UserManager manager, TUser user, string password) { return Task.FromResult(IdentityResult.Failed(ErrorMessage)); } - Task IRoleValidator.ValidateAsync(RoleManager manager, TRole1 role) + public Task ValidateAsync(RoleManager manager, TRole role) { return Task.FromResult(IdentityResult.Failed(ErrorMessage)); } - Task IUserValidator.ValidateAsync(UserManager manager, TUser1 user) + public Task ValidateAsync(UserManager manager, TUser user) { return Task.FromResult(IdentityResult.Failed(ErrorMessage)); }