From c80ec3f326a0709dae53105c7f876ffae4804599 Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Mon, 18 Aug 2014 11:42:26 -0700 Subject: [PATCH] IUserLogin API changes - Add ProviderDisplayName - AddLogin continues to take UserLoginInfo - Remove/Find now only take loginProvider/providerKey - Refactor unit tests to share a base class --- .../Controllers/ManageController.cs | 2 +- samples/IdentitySample.Mvc/LocalConfig.json | 4 +- .../RoleStore.cs | 6 +- .../UserStore.cs | 55 +- .../IUserLoginStore.cs | 10 +- .../IdentityUserLogin.cs | 5 + .../SignInManager.cs | 15 +- .../UserLoginInfo.cs | 9 +- src/Microsoft.AspNet.Identity/UserManager.cs | 34 +- .../HttpSignInTest.cs | 71 +- ...InMemoryTestServiceCollectionExtensions.cs | 19 +- .../InMemoryContext.cs | 9 +- .../InMemoryEFUserStoreTest.cs | 52 + .../InMemoryUser.cs | 107 -- .../InMemoryUserStore.cs | 66 +- .../InMemoryUserStoreTest.cs | 1659 ----------------- .../RoleStoreTest.cs | 2 +- .../TestIdentityFactory.cs | 8 +- .../SqlStoreTestBase.cs | 182 ++ .../UserStoreGuidKeyTest.cs | 18 +- .../UserStoreIntKeyTest.cs | 16 +- .../UserStoreStringKeyTest.cs | 17 +- .../UserStoreTest.cs | 1492 +-------------- .../UserStoreTestBase.cs | 1641 ---------------- .../InMemoryRoleStore.cs | 6 +- .../InMemoryStoreTest.cs | 10 +- .../InMemoryUserStore.cs | 58 +- .../NoopRoleStore.cs | 6 +- .../NoopUserStore.cs | 6 +- .../RoleManagerTest.cs | 6 +- .../UserManagerTest.cs | 42 +- test/Shared/UserManagerTestBase.cs | 565 +++--- 32 files changed, 872 insertions(+), 5326 deletions(-) create mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs delete mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUser.cs delete mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStoreTest.cs create mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs delete mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTestBase.cs diff --git a/samples/IdentitySample.Mvc/Controllers/ManageController.cs b/samples/IdentitySample.Mvc/Controllers/ManageController.cs index df0ccd613e..4a2c5d9e6b 100644 --- a/samples/IdentitySample.Mvc/Controllers/ManageController.cs +++ b/samples/IdentitySample.Mvc/Controllers/ManageController.cs @@ -64,7 +64,7 @@ namespace IdentitySample var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.RemoveLoginAsync(user, new UserLoginInfo(loginProvider, providerKey)); + var result = await UserManager.RemoveLoginAsync(user, loginProvider, providerKey); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false); diff --git a/samples/IdentitySample.Mvc/LocalConfig.json b/samples/IdentitySample.Mvc/LocalConfig.json index d2ce47ffbe..dd1dfa2c6b 100644 --- a/samples/IdentitySample.Mvc/LocalConfig.json +++ b/samples/IdentitySample.Mvc/LocalConfig.json @@ -3,10 +3,10 @@ "DefaultAdminPassword": "YouShouldChangeThisPassword1!", "Data": { "DefaultConnection": { - "Connectionstring": "Server=(localdb)\\v11.0;Database=IdentityMvcMusicStore;Trusted_Connection=True;MultipleActiveResultSets=true" + "Connectionstring": "Server=(localdb)\\v11.0;Database=IdentitySample-8-12-14;Trusted_Connection=True;MultipleActiveResultSets=true" }, "IdentityConnection": { - "Connectionstring": "Server=(localdb)\\v11.0;Database=IdentityMvc;Trusted_Connection=True;MultipleActiveResultSets=true" + "Connectionstring": "Server=(localdb)\\v11.0;Database=IdentityMvc-8-12-14;Trusted_Connection=True;MultipleActiveResultSets=true" } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs index 9964924857..32ff1aa50e 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs @@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework await SaveChanges(cancellationToken); } - public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -110,7 +110,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(ConvertIdToString(role.Id)); } - public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(role.Name); } - public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs index 5071adfb4e..96cad52530 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs @@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework //.Include(u => u.Logins) } - public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -91,7 +91,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(ConvertIdToString(user.Id)); } - public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(user.UserName); } - public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -114,7 +114,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(0); } - public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -125,7 +125,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(user.NormalizedUserName); } - public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -411,7 +411,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework private DbSet> UserRoles { get { return Context.Set>(); } } private DbSet> UserLogins { get { return Context.Set>(); } } - public Task> GetClaimsAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (user == null) @@ -422,7 +422,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult((IList)result); } - public Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = new CancellationToken()) + public Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (user == null) @@ -440,7 +440,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(0); } - public Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = new CancellationToken()) + public Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (user == null) @@ -461,7 +461,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(0); } - public virtual Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public virtual Task AddLoginAsync(TUser user, UserLoginInfo login, + CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -477,7 +478,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework { UserId = user.Id, ProviderKey = login.ProviderKey, - LoginProvider = login.LoginProvider + LoginProvider = login.LoginProvider, + ProviderDisplayName = login.ProviderDisplayName }; // TODO: fixup so we don't have to update both UserLogins.Add(l); @@ -485,7 +487,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework return Task.FromResult(0); } - public virtual Task RemoveLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public virtual Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, + CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -493,15 +496,9 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentNullException("user"); } - if (login == null) - { - throw new ArgumentNullException("login"); - } - var provider = login.LoginProvider; - var key = login.ProviderKey; var userId = user.Id; // todo: ensure logins loaded - var entry = UserLogins.SingleOrDefault(l => l.UserId.Equals(userId) && l.LoginProvider == provider && l.ProviderKey == key); + var entry = UserLogins.SingleOrDefault(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.ProviderKey == providerKey); if (entry != null) { UserLogins.Remove(entry); @@ -519,24 +516,19 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("user"); } // todo: ensure logins loaded - var result = user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList(); - return Task.FromResult((IList)result); + IList result = user.Logins + .Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToList(); + return Task.FromResult(result); } - public async virtual Task FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public async virtual Task FindByLoginAsync(string loginProvider, string providerKey, + CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); - if (login == null) - { - throw new ArgumentNullException("login"); - } // todo: ensure logins loaded - var provider = login.LoginProvider; - var key = login.ProviderKey; - // TODO: use FirstOrDefaultAsync - var userLogin = - UserLogins.FirstOrDefault(l => l.LoginProvider == provider && l.ProviderKey == key); + var userLogin = + UserLogins.FirstOrDefault(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); if (userLogin != null) { return await GetUserAggregate(u => u.Id.Equals(userLogin.UserId), cancellationToken); @@ -646,8 +638,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentNullException("user"); } - return - Task.FromResult(user.LockoutEnd); + return Task.FromResult(user.LockoutEnd); } /// diff --git a/src/Microsoft.AspNet.Identity/IUserLoginStore.cs b/src/Microsoft.AspNet.Identity/IUserLoginStore.cs index 7b2f78acc0..c9526f6863 100644 --- a/src/Microsoft.AspNet.Identity/IUserLoginStore.cs +++ b/src/Microsoft.AspNet.Identity/IUserLoginStore.cs @@ -27,10 +27,11 @@ namespace Microsoft.AspNet.Identity /// Removes the user login with the specified combination if it exists, returns true if found and removed /// /// - /// + /// + /// /// /// - Task RemoveLoginAsync(TUser user, UserLoginInfo login, + Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -45,10 +46,11 @@ namespace Microsoft.AspNet.Identity /// /// Returns the user associated with this login /// - /// + /// + /// /// /// - Task FindByLoginAsync(UserLoginInfo login, + Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IdentityUserLogin.cs b/src/Microsoft.AspNet.Identity/IdentityUserLogin.cs index 8731ef2eff..c53f9b9872 100644 --- a/src/Microsoft.AspNet.Identity/IdentityUserLogin.cs +++ b/src/Microsoft.AspNet.Identity/IdentityUserLogin.cs @@ -23,6 +23,11 @@ namespace Microsoft.AspNet.Identity /// public virtual string ProviderKey { get; set; } + /// + /// Display name for the login + /// + public virtual string ProviderDisplayName { get; set; } + /// /// User Id for the user who owns this login /// diff --git a/src/Microsoft.AspNet.Identity/SignInManager.cs b/src/Microsoft.AspNet.Identity/SignInManager.cs index 8048358c87..50d6893bec 100644 --- a/src/Microsoft.AspNet.Identity/SignInManager.cs +++ b/src/Microsoft.AspNet.Identity/SignInManager.cs @@ -82,6 +82,11 @@ namespace Microsoft.AspNet.Identity AuthenticationManager.SignOut(Options.ClaimsIdentity.AuthenticationType); } + private async Task IsLockedOut(TUser user, CancellationToken token) + { + return UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user, token); + } + /// /// Validates that the claims identity has a security stamp matching the users /// Returns the user if it matches, null otherwise @@ -113,7 +118,7 @@ namespace Microsoft.AspNet.Identity { return SignInStatus.Failure; } - if (UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user, cancellationToken)) + if (await IsLockedOut(user, cancellationToken)) { return SignInStatus.LockedOut; } @@ -186,7 +191,7 @@ namespace Microsoft.AspNet.Identity { return SignInStatus.Failure; } - if (await UserManager.IsLockedOutAsync(user)) + if (await IsLockedOut(user, cancellationToken)) { return SignInStatus.LockedOut; } @@ -202,15 +207,15 @@ namespace Microsoft.AspNet.Identity return SignInStatus.Failure; } - public async Task ExternalLoginSignInAsync(UserLoginInfo loginInfo, bool isPersistent, + public async Task ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, CancellationToken cancellationToken = default(CancellationToken)) { - var user = await UserManager.FindByLoginAsync(loginInfo, cancellationToken); + var user = await UserManager.FindByLoginAsync(loginProvider, providerKey, cancellationToken); if (user == null) { return SignInStatus.Failure; } - if (await UserManager.IsLockedOutAsync(user, cancellationToken)) + if (await IsLockedOut(user, cancellationToken)) { return SignInStatus.LockedOut; } diff --git a/src/Microsoft.AspNet.Identity/UserLoginInfo.cs b/src/Microsoft.AspNet.Identity/UserLoginInfo.cs index e63aabd769..ecfde6f8dd 100644 --- a/src/Microsoft.AspNet.Identity/UserLoginInfo.cs +++ b/src/Microsoft.AspNet.Identity/UserLoginInfo.cs @@ -13,10 +13,12 @@ namespace Microsoft.AspNet.Identity /// /// /// - public UserLoginInfo(string loginProvider, string providerKey) + /// + public UserLoginInfo(string loginProvider, string providerKey, string displayName) { LoginProvider = loginProvider; ProviderKey = providerKey; + ProviderDisplayName = displayName; } /// @@ -28,5 +30,10 @@ namespace Microsoft.AspNet.Identity /// Key for the linked login at the provider /// public string ProviderKey { get; set; } + + /// + /// Display name for the provider + /// + public string ProviderDisplayName { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/UserManager.cs b/src/Microsoft.AspNet.Identity/UserManager.cs index f2845161d3..a496e1bc8a 100644 --- a/src/Microsoft.AspNet.Identity/UserManager.cs +++ b/src/Microsoft.AspNet.Identity/UserManager.cs @@ -769,7 +769,7 @@ namespace Microsoft.AspNet.Identity return await UpdateAsync(user, cancellationToken); } - // UpdateAsync the security stamp if the store supports it + // Update the security stamp if the store supports it internal async Task UpdateSecurityStampInternal(TUser user, CancellationToken cancellationToken) { if (SupportsUserSecurityStamp) @@ -795,14 +795,26 @@ namespace Microsoft.AspNet.Identity } /// - /// Returns the user associated with this login + /// Returns the user associated with this login /// + /// + /// + /// /// - public virtual Task FindByLoginAsync(UserLoginInfo login, + public virtual Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); - return GetLoginStore().FindByLoginAsync(login, cancellationToken); + var loginStore = GetLoginStore(); + if (loginProvider == null) + { + throw new ArgumentNullException("loginProvider"); + } + if (providerKey == null) + { + throw new ArgumentNullException("providerKey"); + } + return loginStore.FindByLoginAsync(loginProvider, providerKey, cancellationToken); } /// @@ -812,20 +824,24 @@ namespace Microsoft.AspNet.Identity /// /// /// - public virtual async Task RemoveLoginAsync(TUser user, UserLoginInfo login, + public virtual async Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); var loginStore = GetLoginStore(); - if (login == null) + if (loginProvider == null) { - throw new ArgumentNullException("login"); + throw new ArgumentNullException("loginProvider"); + } + if (providerKey == null) + { + throw new ArgumentNullException("providerKey"); } if (user == null) { throw new ArgumentNullException("user"); } - await loginStore.RemoveLoginAsync(user, login, cancellationToken); + await loginStore.RemoveLoginAsync(user, loginProvider, providerKey, cancellationToken); await UpdateSecurityStampInternal(user, cancellationToken); return await UpdateAsync(user, cancellationToken); } @@ -850,7 +866,7 @@ namespace Microsoft.AspNet.Identity { throw new ArgumentNullException("user"); } - var existingUser = await FindByLoginAsync(login, cancellationToken); + var existingUser = await FindByLoginAsync(login.LoginProvider, login.ProviderKey, cancellationToken); if (existingUser != null) { return IdentityResult.Failed(Resources.ExternalLoginExists); diff --git a/test/Microsoft.AspNet.Identity.Authentication.Test/HttpSignInTest.cs b/test/Microsoft.AspNet.Identity.Authentication.Test/HttpSignInTest.cs index e398887546..30c1c9934d 100644 --- a/test/Microsoft.AspNet.Identity.Authentication.Test/HttpSignInTest.cs +++ b/test/Microsoft.AspNet.Identity.Authentication.Test/HttpSignInTest.cs @@ -207,16 +207,21 @@ namespace Microsoft.AspNet.Identity.Authentication.Test contextAccessor.VerifyAll(); } - [Fact] - public async Task PasswordSignInRequiresVerification() + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task PasswordSignInRequiresVerification(bool supportsLockout) { // Setup var user = new TestUser { UserName = "Foo" }; var manager = MockHelpers.MockUserManager(); - manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable(); + manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable(); + if (supportsLockout) + { + manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable(); + } manager.Setup(m => m.SupportsUserTwoFactor).Returns(true).Verifiable(); manager.Setup(m => m.GetTwoFactorEnabledAsync(user, CancellationToken.None)).ReturnsAsync(true).Verifiable(); - manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable(); manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable(); manager.Setup(m => m.GetUserIdAsync(user, CancellationToken.None)).ReturnsAsync(user.Id).Verifiable(); manager.Setup(m => m.CheckPasswordAsync(user, "password", CancellationToken.None)).ReturnsAsync(true).Verifiable(); @@ -244,16 +249,66 @@ namespace Microsoft.AspNet.Identity.Authentication.Test } [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task CanTwoFactorSignIn(bool isPersistent) + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public async Task CanExternalSignIn(bool isPersistent, bool supportsLockout) + { + // Setup + var user = new TestUser { UserName = "Foo" }; + const string loginProvider = "login"; + const string providerKey = "fookey"; + var manager = MockHelpers.MockUserManager(); + manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable(); + if (supportsLockout) + { + manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable(); + } + manager.Setup(m => m.FindByLoginAsync(loginProvider, providerKey, CancellationToken.None)).ReturnsAsync(user).Verifiable(); + var context = new Mock(); + var response = new Mock(); + context.Setup(c => c.Response).Returns(response.Object).Verifiable(); + response.Setup(r => r.SignIn(It.Is(v => v.IsPersistent == isPersistent), It.IsAny())).Verifiable(); + var contextAccessor = new Mock>(); + contextAccessor.Setup(a => a.Value).Returns(context.Object); + var roleManager = MockHelpers.MockRoleManager(); + var identityOptions = new IdentityOptions(); + var claimsFactory = new Mock>(manager.Object, roleManager.Object); + claimsFactory.Setup(m => m.CreateAsync(user, identityOptions.ClaimsIdentity, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity("Microsoft.AspNet.Identity")).Verifiable(); + var options = new Mock>(); + options.Setup(a => a.Options).Returns(identityOptions); + var helper = new SignInManager(manager.Object, new HttpAuthenticationManager(contextAccessor.Object), claimsFactory.Object, options.Object); + + // Act + var result = await helper.ExternalLoginSignInAsync(loginProvider, providerKey, isPersistent); + + // Assert + Assert.Equal(SignInStatus.Success, result); + manager.VerifyAll(); + context.VerifyAll(); + response.VerifyAll(); + contextAccessor.VerifyAll(); + claimsFactory.VerifyAll(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(false, false)] + public async Task CanTwoFactorSignIn(bool isPersistent, bool supportsLockout) { // Setup var user = new TestUser { UserName = "Foo" }; var manager = MockHelpers.MockUserManager(); var provider = "twofactorprovider"; var code = "123456"; - manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable(); + manager.Setup(m => m.SupportsUserLockout).Returns(supportsLockout).Verifiable(); + if (supportsLockout) + { + manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable(); + } manager.Setup(m => m.FindByIdAsync(user.Id, CancellationToken.None)).ReturnsAsync(user).Verifiable(); manager.Setup(m => m.VerifyTwoFactorTokenAsync(user, provider, code, CancellationToken.None)).ReturnsAsync(true).Verifiable(); manager.Setup(m => m.GetUserIdAsync(user, CancellationToken.None)).ReturnsAsync(user.Id).Verifiable(); diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs index 90d59829bb..ebbb92a98d 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs @@ -10,15 +10,24 @@ namespace Microsoft.AspNet.Identity { public static class EntityInMemoryTestServiceCollectionExtensions { - public static IdentityBuilder AddIdentityInMemory(this ServiceCollection services) - where TUser : InMemoryUser + public static IdentityBuilder AddIdentityInMemory(this ServiceCollection services, InMemoryContext context) + { + return services.AddIdentityInMemory(context); + } + + public static IdentityBuilder AddIdentityInMemory(this ServiceCollection services, TDbContext context) + where TUser : IdentityUser where TRole : IdentityRole where TDbContext : DbContext { var builder = services.AddIdentity(); - services.AddScoped(); - services.AddScoped, InMemoryUserStore>(); - services.AddScoped, RoleStore>(); + services.AddInstance>(new InMemoryUserStore(context)); + var store = new RoleStore(context); + services.AddInstance>(store); + //services.AddInstance(context); + //services.AddScoped(); + //services.AddScoped, InMemoryUserStore>(); + //services.AddScoped, RoleStore>(); return builder; } } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs index b8a42f813d..39b09af851 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs @@ -8,7 +8,7 @@ using Microsoft.Data.Entity.Metadata; namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { public class InMemoryContext : - InMemoryContext + InMemoryContext { public InMemoryContext() { } public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { } @@ -16,14 +16,14 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test public class InMemoryContext : InMemoryContext - where TUser : InMemoryUser + where TUser : IdentityUser { public InMemoryContext() { } public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { } } public class InMemoryContext : DbContext - where TUser : InMemoryUser + where TUser : IdentityUser where TRole : IdentityRole where TUserLogin : IdentityUserLogin where TUserRole : IdentityUserRole @@ -42,7 +42,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test protected override void OnConfiguring(DbContextOptions builder) { - builder.UseInMemoryStore(); + // Want fresh in memory store for tests always for now + builder.UseInMemoryStore(persist: false); } protected override void OnModelCreating(ModelBuilder builder) diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs new file mode 100644 index 0000000000..37e8a298e1 --- /dev/null +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Identity.Test; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; + +namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test +{ + public class InMemoryEFUserStoreTest : UserManagerTestBase + { + protected override object CreateTestContext() + { + return new InMemoryContext(); + } + + protected override UserManager CreateManager(object context) + { + if (context == null) + { + context = CreateTestContext(); + } + var services = new ServiceCollection(); + services.Add(OptionsServices.GetDefaultServices()); + services.AddEntityFramework().AddInMemoryStore(); + services.AddIdentityInMemory((InMemoryContext)context); + services.SetupOptions(options => + { + options.Password.RequireDigit = false; + options.Password.RequireLowercase = false; + options.Password.RequireNonLetterOrDigit = false; + options.Password.RequireUppercase = false; + options.User.AllowOnlyAlphanumericNames = false; + }); + return services.BuildServiceProvider().GetService>(); + } + + protected override RoleManager CreateRoleManager(object context) + { + if (context == null) + { + context = CreateTestContext(); + } + var services = new ServiceCollection(); + services.Add(OptionsServices.GetDefaultServices()); + services.AddEntityFramework().AddInMemoryStore(); + services.AddIdentityInMemory((InMemoryContext)context); + return services.BuildServiceProvider().GetService>(); + } + } +} diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUser.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUser.cs deleted file mode 100644 index 958077349c..0000000000 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUser.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. 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; - -namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test -{ - public class InMemoryUser : InMemoryUser - { - public InMemoryUser() - { - Id = Guid.NewGuid().ToString(); - } - - public InMemoryUser(string userName) - : this() - { - UserName = userName; - } - } - - public class InMemoryUser - where TLogin : IdentityUserLogin - where TRole : IdentityUserRole - where TClaim : IdentityUserClaim - where TKey : IEquatable - { - public InMemoryUser() - { - Claims = new List(); - Roles = new List(); - Logins = new List(); - } - - public virtual TKey Id { get; set; } - public virtual string UserName { get; set; } - public virtual string NormalizedUserName { get; set; } - - /// - /// Email - /// - public virtual string Email { get; set; } - - /// - /// True if the email is confirmed, default is false - /// - public virtual bool EmailConfirmed { get; set; } - - /// - /// The salted/hashed form of the user password - /// - public virtual string PasswordHash { get; set; } - - /// - /// A random value that should change whenever a users credentials have changed (password changed, login removed) - /// - public virtual string SecurityStamp { get; set; } - - /// - /// PhoneNumber for the user - /// - public virtual string PhoneNumber { get; set; } - - /// - /// True if the phone number is confirmed, default is false - /// - public virtual bool PhoneNumberConfirmed { get; set; } - - /// - /// Is two factor enabled for the user - /// - public virtual bool TwoFactorEnabled { get; set; } - - /// - /// DateTime in UTC when lockout ends, any time in the past is considered not locked out. - /// - public virtual DateTime? LockoutEnd { get; set; } - - /// - /// Is lockout enabled for this user - /// - public virtual bool LockoutEnabled { get; set; } - - /// - /// Used to record failures for the purposes of lockout - /// - public virtual int AccessFailedCount { get; set; } - - /// - /// Navigation property for user roles - /// - public virtual ICollection Roles { get; private set; } - - /// - /// Navigation property for user claims - /// - public virtual ICollection Claims { get; private set; } - - /// - /// Navigation property for user logins - /// - public virtual ICollection Logins { get; private set; } - - } -} - diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs index 202b51dbcb..c66a2eb85b 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs @@ -13,19 +13,19 @@ using Microsoft.Data.Entity; namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { - public class InMemoryUserStore : InMemoryUserStore + public class InMemoryUserStore : InMemoryUserStore { public InMemoryUserStore(InMemoryContext context) : base(context) { } } public class InMemoryUserStore : InMemoryUserStore - where TUser : InMemoryUser + where TUser : IdentityUser { public InMemoryUserStore(InMemoryContext context) : base(context) { } } public class InMemoryUserStore : InMemoryUserStore - where TUser:InMemoryUser + where TUser:IdentityUser where TContext : DbContext { public InMemoryUserStore(TContext context) : base(context) { } @@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test IUserTwoFactorStore, IUserLockoutStore where TKey : IEquatable - where TUser : InMemoryUser + where TUser : IdentityUser where TRole : IdentityRole where TUserLogin : IdentityUserLogin, new() where TUserRole : IdentityUserRole, new() @@ -83,7 +83,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test //.Include(u => u.Logins) } - public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -94,7 +94,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return Task.FromResult(Convert.ToString(user.Id, CultureInfo.InvariantCulture)); } - public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return Task.FromResult(user.UserName); } - public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return Task.FromResult(0); } - public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -128,7 +128,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return Task.FromResult(user.NormalizedUserName); } - public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -213,7 +213,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test get { return Context.Set(); } } - public async virtual Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public async virtual Task AddLoginAsync(TUser user, UserLoginInfo login, + CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -221,21 +222,19 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { throw new ArgumentNullException("user"); } - if (login == null) - { - throw new ArgumentNullException("login"); - } var l = new TUserLogin { UserId = user.Id, ProviderKey = login.ProviderKey, - LoginProvider = login.LoginProvider + LoginProvider = login.LoginProvider, + ProviderDisplayName = login.ProviderDisplayName }; await Context.Set().AddAsync(l, cancellationToken); user.Logins.Add(l); } - public virtual Task RemoveLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public virtual Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, + CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); @@ -243,17 +242,11 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { throw new ArgumentNullException("user"); } - if (login == null) - { - throw new ArgumentNullException("login"); - } - var provider = login.LoginProvider; - var key = login.ProviderKey; - var entry = user.Logins.SingleOrDefault(l => l.LoginProvider == provider && l.ProviderKey == key); + var entry = user.Logins.SingleOrDefault(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); if (entry != null) { user.Logins.Remove(entry); - Context.Set().Remove(entry); + Context.Set>().Remove(entry); } return Task.FromResult(0); } @@ -266,24 +259,18 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { throw new ArgumentNullException("user"); } - IList result = - user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList(); + IList result = user.Logins.Select( + l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)) + .ToList(); return Task.FromResult(result); } - public async virtual Task FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public async virtual Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); - if (login == null) - { - throw new ArgumentNullException("login"); - } - var provider = login.LoginProvider; - var key = login.ProviderKey; - // TODO: use FirstOrDefaultAsync - var userLogin = - Context.Set().FirstOrDefault(l => l.LoginProvider == provider && l.ProviderKey == key); + var userLogin = await Context.Set() + .FirstOrDefaultAsync(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); if (userLogin != null) { return await GetUserAggregate(u => u.Id.Equals(userLogin.UserId), cancellationToken); @@ -523,10 +510,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { throw new ArgumentNullException("user"); } - return - Task.FromResult(user.LockoutEnd.HasValue - ? new DateTimeOffset(DateTime.SpecifyKind(user.LockoutEnd.Value, DateTimeKind.Utc)) - : new DateTimeOffset()); + return Task.FromResult(user.LockoutEnd); } /// @@ -544,7 +528,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { throw new ArgumentNullException("user"); } - user.LockoutEnd = lockoutEnd == DateTimeOffset.MinValue ? (DateTime?)null : lockoutEnd.UtcDateTime; + user.LockoutEnd = lockoutEnd; return Task.FromResult(0); } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStoreTest.cs deleted file mode 100644 index e8557a046b..0000000000 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStoreTest.cs +++ /dev/null @@ -1,1659 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Identity.Test; -using Microsoft.AspNet.Testing; -using Microsoft.Data.Entity; -using Microsoft.Data.Entity.Metadata; -using System; -using System.Linq; -using System.Security.Claims; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; -using Xunit; - -namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test -{ - public class InMemoryUserStoreTest - { - - [Fact] - public async Task CanUseAddedManagerInstance() - { - var services = new ServiceCollection(); - services.AddEntityFramework().AddInMemoryStore(); - services.AddIdentity(); - services.AddSingleton, OptionsAccessor>(); - services.AddInstance(new InMemoryContext()); - services.AddTransient, InMemoryUserStore>(); - var provider = services.BuildServiceProvider(); - var manager = provider.GetService>(); - Assert.NotNull(manager); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new InMemoryUser("hello"))); - } - - [Fact] - public async Task CanCreateUsingAddUserManager() - { - var services = new ServiceCollection(); - services.AddEntityFramework().AddInMemoryStore(); - - // TODO: this needs to construct a new instance of InMemoryStore - var store = new InMemoryUserStore(new InMemoryContext()); - services.Add(OptionsServices.GetDefaultServices()); - services.AddIdentity().AddUserStore(() => store); - - var provider = services.BuildServiceProvider(); - var manager = provider.GetService>(); - Assert.NotNull(manager); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new InMemoryUser("hello2"))); - } - - [Fact] - public async Task EntityUserStoreMethodsThrowWhenDisposedTest() - { - var store = new InMemoryUserStore(new InMemoryContext()); - store.Dispose(); - await Assert.ThrowsAsync(async () => await store.AddClaimsAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.AddLoginAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.AddToRoleAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.GetClaimsAsync(null)); - await Assert.ThrowsAsync(async () => await store.GetLoginsAsync(null)); - await Assert.ThrowsAsync(async () => await store.GetRolesAsync(null)); - await Assert.ThrowsAsync(async () => await store.IsInRoleAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.RemoveLoginAsync(null, null)); - await Assert.ThrowsAsync( - async () => await store.RemoveFromRoleAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.FindByLoginAsync(null)); - await Assert.ThrowsAsync(async () => await store.FindByIdAsync(null)); - await Assert.ThrowsAsync(async () => await store.FindByNameAsync(null)); - await Assert.ThrowsAsync(async () => await store.CreateAsync(null)); - await Assert.ThrowsAsync(async () => await store.UpdateAsync(null)); - await Assert.ThrowsAsync(async () => await store.DeleteAsync(null)); - await Assert.ThrowsAsync( - async () => await store.SetEmailConfirmedAsync(null, true)); - await Assert.ThrowsAsync(async () => await store.GetEmailConfirmedAsync(null)); - await Assert.ThrowsAsync( - async () => await store.SetPhoneNumberConfirmedAsync(null, true)); - await Assert.ThrowsAsync( - async () => await store.GetPhoneNumberConfirmedAsync(null)); - } - - [Fact] - public async Task EntityUserStorePublicNullCheckTest() - { - Assert.Throws("context", () => new InMemoryUserStore(null)); - var store = new InMemoryUserStore(new InMemoryContext()); - await Assert.ThrowsAsync("user", async () => await store.GetUserIdAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.GetUserNameAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.SetUserNameAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.CreateAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.UpdateAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.DeleteAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.AddClaimsAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.GetClaimsAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.GetLoginsAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.GetRolesAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.AddLoginAsync(null, null)); - await - Assert.ThrowsAsync("user", async () => await store.RemoveLoginAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.AddToRoleAsync(null, null)); - await - Assert.ThrowsAsync("user", - async () => await store.RemoveFromRoleAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.IsInRoleAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.GetPasswordHashAsync(null)); - await - Assert.ThrowsAsync("user", - async () => await store.SetPasswordHashAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.GetSecurityStampAsync(null)); - await Assert.ThrowsAsync("user", - async () => await store.SetSecurityStampAsync(null, null)); - await Assert.ThrowsAsync("claims", - async () => await store.AddClaimsAsync(new InMemoryUser("fake"), null)); - await Assert.ThrowsAsync("claims", - async () => await store.RemoveClaimsAsync(new InMemoryUser("fake"), null)); - await Assert.ThrowsAsync("login", - async () => await store.AddLoginAsync(new InMemoryUser("fake"), null)); - await Assert.ThrowsAsync("login", - async () => await store.RemoveLoginAsync(new InMemoryUser("fake"), null)); - await Assert.ThrowsAsync("login", async () => await store.FindByLoginAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.GetEmailConfirmedAsync(null)); - await Assert.ThrowsAsync("user", - async () => await store.SetEmailConfirmedAsync(null, true)); - await Assert.ThrowsAsync("user", async () => await store.GetEmailAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.SetEmailAsync(null, null)); - await Assert.ThrowsAsync("user", async () => await store.GetPhoneNumberAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.SetPhoneNumberAsync(null, null)); - await Assert.ThrowsAsync("user", - async () => await store.GetPhoneNumberConfirmedAsync(null)); - await Assert.ThrowsAsync("user", - async () => await store.SetPhoneNumberConfirmedAsync(null, true)); - await Assert.ThrowsAsync("user", async () => await store.GetTwoFactorEnabledAsync(null)); - await Assert.ThrowsAsync("user", - async () => await store.SetTwoFactorEnabledAsync(null, true)); - await Assert.ThrowsAsync("user", async () => await store.GetAccessFailedCountAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.GetLockoutEnabledAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.SetLockoutEnabledAsync(null, false)); - await Assert.ThrowsAsync("user", async () => await store.GetLockoutEndDateAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.SetLockoutEndDateAsync(null, new DateTimeOffset())); - await Assert.ThrowsAsync("user", async () => await store.ResetAccessFailedCountAsync(null)); - await Assert.ThrowsAsync("user", async () => await store.IncrementAccessFailedCountAsync(null)); - // TODO: - //ExceptionAssert.ThrowsArgumentNullOrEmpty( - // async () => store.AddToRoleAsync(new InMemoryUser("fake"), null)), "roleName"); - //ExceptionAssert.ThrowsArgumentNullOrEmpty( - // async () => store.RemoveFromRoleAsync(new InMemoryUser("fake"), null)), "roleName"); - //ExceptionAssert.ThrowsArgumentNullOrEmpty( - // async () => store.IsInRoleAsync(new InMemoryUser("fake"), null)), "roleName"); - } - - [Fact] - public async Task Can_share_instance_between_contexts_with_sugar_experience2() - { - // TODO: Should be possible to do this without creating the provider externally, but - // that is currently not working. Will be investigated. - var services = new ServiceCollection(); - services.AddEntityFramework().AddInMemoryStore(); - var provider = services.BuildServiceProvider(); - - using (var db = new InMemoryContext(provider)) - { - db.Users.Add(new InMemoryUser { UserName = "John Doe" }); - await db.SaveChangesAsync(); - } - - using (var db = new InMemoryContext(provider)) - { - var data = db.Users.ToList(); - Assert.Equal(1, data.Count); - Assert.Equal("John Doe", data[0].UserName); - } - } - - [Fact] - public async Task Can_create_two_artists() - { - using (var db = new SimpleContext()) - { - db.Artists.Add(new SimpleContext.Artist { Name = "John Doe", ArtistId = Guid.NewGuid().ToString() }); - await db.SaveChangesAsync(); - db.Artists.Add(new SimpleContext.Artist { Name = "Second guy", ArtistId = Guid.NewGuid().ToString() }); - await db.SaveChangesAsync(); - } - } - - private class SimpleContext : DbContext - { - public DbSet Artists { get; set; } - - protected override void OnConfiguring(DbContextOptions builder) - { - builder.UseInMemoryStore(); - } - - protected override void OnModelCreating(ModelBuilder builder) - { - builder.Entity().Key(a => a.ArtistId); - } - - public class Artist// : ArtistBase - { - public string ArtistId { get; set; } - public string Name { get; set; } - } - - public class ArtistBase - { - public TKey ArtistId { get; set; } - public string Name { get; set; } - } - } - - [Fact] - public async Task CanDeleteUser() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("DeleteAsync"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - Assert.Null(await manager.FindByIdAsync(user.Id)); - } - - [Fact] - public async Task CanUpdateUserName() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("UpdateAsync"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.Null(await manager.FindByNameAsync("New")); - user.UserName = "New"; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.NotNull(await manager.FindByNameAsync("New")); - Assert.Null(await manager.FindByNameAsync("UpdateAsync")); - } - - [Fact] - public async Task CanSetUserName() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("UpdateAsync"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.Null(await manager.FindByNameAsync("New")); - IdentityResultAssert.IsSuccess(await manager.SetUserNameAsync(user, "New")); - Assert.NotNull(await manager.FindByNameAsync("New")); - Assert.Null(await manager.FindByNameAsync("UpdateAsync")); - } - - [Fact] - public async Task UserValidatorCanBlockCreate() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("CreateBlocked"); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task UserValidatorCanBlockUpdate() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("UpdateBlocked"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - public async Task UserValidatorBlocksShortEmailsWhenRequiresUniqueEmail(string email) - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("UpdateBlocked") { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email cannot be null or empty."); - } - -#if NET45 - [Theory] - [InlineData("@@afd")] - [InlineData("bogus")] - public async Task UserValidatorBlocksInvalidEmailsWhenRequiresUniqueEmail(string email) - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("UpdateBlocked") { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email '" + email + "' is invalid."); - } -#endif - - [Fact] - public async Task PasswordValidatorCanBlockAddPassword() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("AddPasswordBlocked"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task PasswordValidatorCanBlockChangePassword() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("ChangePasswordBlocked"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ChangePasswordAsync(user, "password", "new"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task CanCreateUserNoPassword() - { - var manager = TestIdentityFactory.CreateManager(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new InMemoryUser("CreateUserTest"))); - var user = await manager.FindByNameAsync("CreateUserTest"); - Assert.NotNull(user); - Assert.Null(user.PasswordHash); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - } - - //[Fact] Disabled--see issue #107 - public async Task CanCreateUserAddLogin() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "CreateExternalUserTest"; - const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new InMemoryUser(userName))); - var user = await manager.FindByNameAsync(userName); - Assert.NotNull(user); - var login = new UserLoginInfo(provider, providerKey); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(provider, logins.First().LoginProvider); - Assert.Equal(providerKey, logins.First().ProviderKey); - } - - //[Fact] Disabled--see issue #107 - public async Task CanCreateUserLoginAndAddPassword() - { - var manager = TestIdentityFactory.CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new InMemoryUser("CreateUserLoginAddPasswordTest"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.False(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddPasswordAsync(user, "password")); - Assert.True(await manager.HasPasswordAsync(user)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(user, await manager.FindByLoginAsync(login)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, "password")); - } - - [Fact] - public async Task AddPasswordFailsIfAlreadyHave() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("CannotAddAnotherPassword"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "Password")); - Assert.True(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - "User already has a password set."); - } - - //[Fact] Disabled--see issue #107 - public async Task CanCreateUserAddRemoveLogin() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("CreateUserAddRemoveLoginTest"); - var login = new UserLoginInfo("Provider", "key"); - var result = await manager.CreateAsync(user); - Assert.NotNull(user); - IdentityResultAssert.IsSuccess(result); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.Equal(user, await manager.FindByLoginAsync(login)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); - Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemoveLoginAsync(user, login)); - Assert.Null(await manager.FindByLoginAsync(login)); - logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanRemovePassword() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("RemovePasswordTest"); - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemovePasswordAsync(user)); - var u = await manager.FindByNameAsync(user.UserName); - Assert.NotNull(u); - Assert.Null(u.PasswordHash); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanChangePassword() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("ChangePasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - Assert.Equal(manager.Users.Count(), 1); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, password, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanAddRemoveUserClaim() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("ClaimsAddRemove"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; - foreach (var c in claims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - } - var userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(3, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(2, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(1, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(0, userClaims.Count); - } - - [Fact] - public async Task ChangePasswordFallsIfPasswordWrong() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("user"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - var result = await manager.ChangePasswordAsync(user, "bogus", "newpassword"); - IdentityResultAssert.IsFailure(result, "Incorrect password."); - } - - [Fact] - public async Task AddDupeUserNameFails() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("dupe"); - var user2 = new InMemoryUser("dupe"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Name dupe is already taken."); - } - - [Fact] - public async Task AddDupeEmailAllowedByDefault() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("dupe") { Email = "yup@yup.com" }; - var user2 = new InMemoryUser("dupeEmail") { Email = "yup@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - } - - [Fact] - public async Task AddDupeEmailFallsWhenUniqueEmailRequired() - { - var manager = TestIdentityFactory.CreateManager(); - manager.Options.User.RequireUniqueEmail = true; - var user = new InMemoryUser("dupe") { Email = "yup@yup.com" }; - var user2 = new InMemoryUser("dupeEmail") { Email = "yup@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Email 'yup@yup.com' is already taken."); - } - - [Fact] - public async Task UpdateSecurityStampActuallyChanges() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("stampMe"); - Assert.Null(user.SecurityStamp); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - //[Fact] Disabled--see issue #107 - public async Task AddDupeLoginFails() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("DupeLogin"); - var login = new UserLoginInfo("provder", "key"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var result = await manager.AddLoginAsync(user, login); - IdentityResultAssert.IsFailure(result, "A user with that external login already exists."); - } - - // Email tests - [Fact] - public async Task CanFindByEmail() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "EmailTest"; - const string email = "email@test.com"; - var user = new InMemoryUser(userName) { Email = email }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var fetch = await manager.FindByEmailAsync(email); - Assert.Equal(user, fetch); - } - - [Fact] - public async Task CanFindUsersViaUserQuerable() - { - var mgr = TestIdentityFactory.CreateManager(); - var users = new[] - { - new InMemoryUser("user1"), - new InMemoryUser("user2"), - new InMemoryUser("user3") - }; - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(u)); - } - var usersQ = mgr.Users; - Assert.Equal(3, usersQ.Count()); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user1")); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user2")); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user3")); - Assert.Null(usersQ.FirstOrDefault(u => u.UserName == "bogus")); - } - - [Fact] - public async Task ClaimsIdentityCreatesExpectedClaims() - { - var context = TestIdentityFactory.CreateContext(); - var manager = TestIdentityFactory.CreateManager(context); - var role = TestIdentityFactory.CreateRoleManager(context); - var user = new InMemoryUser("Hao"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await role.CreateAsync(new IdentityRole("Admin"))); - IdentityResultAssert.IsSuccess(await role.CreateAsync(new IdentityRole("Local"))); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Admin")); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Local")); - Claim[] userClaims = - { - new Claim("Whatever", "Value"), - new Claim("Whatever2", "Value2") - }; - foreach (var c in userClaims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - } - - var claimsFactory = new ClaimsIdentityFactory(manager, role); - var identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); - var claims = identity.Claims.ToList(); - Assert.NotNull(claims); - Assert.True( - claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName)); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id.ToString())); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin")); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local")); - foreach (var cl in userClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - } - - [Fact] - public async Task ConfirmEmailFalseByDefaultTest() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("test"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: No token provider implementations yet - private class StaticTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, - InMemoryUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose, user)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - InMemoryUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose, user)); - } - - public Task NotifyAsync(string token, UserManager manager, InMemoryUser user, CancellationToken cancellationToken) - { - return Task.FromResult(0); - } - - public Task IsValidProviderForUserAsync(UserManager manager, InMemoryUser user, CancellationToken token) - { - return Task.FromResult(true); - } - - private static string MakeToken(string purpose, InMemoryUser user) - { - return string.Join(":", user.Id, purpose, "ImmaToken"); - } - } - - [Fact] - public async Task CanResetPasswordWithStaticTokenProvider() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("ResetPasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ResetPasswordAsync(user, token, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("ResetPasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, token, newPassword), - AlwaysBadValidator.ErrorMessage); - Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordWithStaticTokenProviderFailsWithWrongToken() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("ResetPasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, "bogus", newPassword), "Invalid token."); - Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("UserTokenTest"); - var user2 = new InMemoryUser("UserTokenTest2"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - var token = await manager.GenerateUserTokenAsync("test", user); - Assert.True(await manager.VerifyUserTokenAsync(user, "test", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test2", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test", token + "a")); - Assert.False(await manager.VerifyUserTokenAsync(user2, "test", token)); - } - - [Fact] - public async Task CanConfirmEmailWithStaticToken() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("test"); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ConfirmEmailAsync(user, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user)); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - [Fact] - public async Task ConfirmEmailWithStaticTokenFailsWithWrongToken() - { - var manager = TestIdentityFactory.CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new InMemoryUser("test"); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, "bogus"), "Invalid token."); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: Can't reenable til we have a SecurityStamp linked token provider - //[Fact] - //public async Task ConfirmTokenFailsAfterPasswordChange() - //{ - // var manager = TestIdentityFactory.CreateManager(); - // var user = new InMemoryUser("test"); - // Assert.False(user.EmailConfirmed); - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - // var token = await manager.GenerateEmailConfirmationTokenAsync(user); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, "password", "newpassword")); - // IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, token), "Invalid token."); - // Assert.False(await manager.IsEmailConfirmedAsync(user)); - //} - - // Lockout tests - - [Fact] - public async Task SingleFailureLockout() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 0; - var user = new InMemoryUser("fastLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task TwoFailureLockout() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new InMemoryUser("twoFailureLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task ResetAccessCountPreventsLockout() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new InMemoryUser("resetLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.ResetAccessFailedCountAsync(user)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task CanEnableLockoutManuallyAndLockout() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new InMemoryUser("manualLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEnabledAsync(user, true)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new InMemoryUser("LockoutTest"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset())); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.Equal(new DateTimeOffset(), await mgr.GetLockoutEndDateAsync(user)); - Assert.Null(user.LockoutEnd); - } - - [Fact] - public async Task LockoutFailsIfNotEnabled() - { - var mgr = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("LockoutNotEnabledTest"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsFailure(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset()), - "Lockout is not enabled for this user."); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new InMemoryUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddSeconds(-1) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new InMemoryUser("LockoutUtcNowTest"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.AddSeconds(-1))); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new InMemoryUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddMinutes(5) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.True(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task UserLockedOutWithDateTimeLocalKindNowPlus30() - { - var mgr = TestIdentityFactory.CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new InMemoryUser("LockoutTest"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - var lockoutEnd = new DateTimeOffset(DateTime.Now.AddMinutes(30).ToLocalTime()); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, lockoutEnd)); - Assert.True(await mgr.IsLockedOutAsync(user)); - var end = await mgr.GetLockoutEndDateAsync(user); - Assert.Equal(lockoutEnd, end); - } - - // Role Tests - [Fact] - public async Task CanCreateRoleTest() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("create"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - } - - private class AlwaysBadValidator : IUserValidator, IRoleValidator, - IPasswordValidator - { - public const string ErrorMessage = "I'm Bad."; - - public Task ValidateAsync(string password, UserManager manager,CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(RoleManager manager, IdentityRole role, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(UserManager manager, InMemoryUser user, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - } - - [Fact] - public async Task BadValidatorBlocksCreateRole() - { - var manager = TestIdentityFactory.CreateRoleManager(); - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(new IdentityRole("blocked")), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task BadValidatorBlocksRoleUpdate() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("poorguy"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - var error = AlwaysBadValidator.ErrorMessage; - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(role), error); - } - - [Fact] - public async Task CanDeleteRoleTest() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("delete"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(role)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - } - - [Fact] - public async Task CanRoleFindByIdTest() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("FindByIdAsync"); - Assert.Null(await manager.FindByIdAsync(role.Id)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByIdAsync(role.Id)); - } - - [Fact] - public async Task CanRoleFindByName() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("FindByNameAsync"); - Assert.Null(await manager.FindByNameAsync(role.Name)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByNameAsync(role.Name)); - } - - [Fact] - public async Task CanUpdateRoleNameTest() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("update"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - role.Name = "Changed"; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(role)); - Assert.False(await manager.RoleExistsAsync("update")); - Assert.Equal(role, await manager.FindByNameAsync(role.Name)); - } - - [Fact] - public async Task CanQuerableRolesTest() - { - var manager = TestIdentityFactory.CreateRoleManager(); - IdentityRole[] roles = - { - new IdentityRole("r1"), new IdentityRole("r2"), new IdentityRole("r3"), - new IdentityRole("r4") - }; - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(r)); - } - Assert.Equal(roles.Length, manager.Roles.Count()); - var r1 = manager.Roles.FirstOrDefault(r => r.Name == "r1"); - Assert.Equal(roles[0], r1); - } - - //[Fact] - //public async Task DeleteRoleNonEmptySucceedsTest() - //{ - // // Need fail if not empty? - // var userMgr = TestIdentityFactory.CreateManager(); - // var roleMgr = TestIdentityFactory.CreateRoleManager(); - // var role = new IdentityRole("deleteNonEmpty"); - // Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - // var user = new InMemoryUser("t"); - // IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - // IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - // IdentityResultAssert.IsSuccess(await roleMgr.DeleteAsync(role)); - // Assert.Null(await roleMgr.FindByNameAsync(role.Name)); - // Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // // REVIEW: We should throw if deleteing a non empty role? - // var roles = await userMgr.GetRolesAsync(user); - - // // In memory this doesn't work since there's no concept of cascading deletes - // //Assert.Equal(0, roles.Count()); - //} - - ////[Fact] - ////public async Task DeleteUserRemovesFromRoleTest() - ////{ - //// // Need fail if not empty? - //// var userMgr = TestIdentityFactory.CreateManager(); - //// var roleMgr = TestIdentityFactory.CreateRoleManager(); - //// var role = new IdentityRole("deleteNonEmpty"); - //// Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - //// IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - //// var user = new InMemoryUser("t"); - //// IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - //// IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - //// IdentityResultAssert.IsSuccess(await userMgr.DeleteAsync(user)); - //// role = roleMgr.FindByIdAsync(role.Id); - ////} - - [Fact] - public async Task CreateRoleFailsIfExists() - { - var manager = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("dupeRole"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - var role2 = new IdentityRole("dupeRole"); - IdentityResultAssert.IsFailure(await manager.CreateAsync(role2)); - } - - [Fact] - public async Task CanAddUsersToRole() - { - var context = TestIdentityFactory.CreateContext(); - var manager = TestIdentityFactory.CreateManager(context); - var roleManager = TestIdentityFactory.CreateRoleManager(context); - var role = new IdentityRole("addUserTest"); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); - InMemoryUser[] users = - { - new InMemoryUser("1"), new InMemoryUser("2"), new InMemoryUser("3"), - new InMemoryUser("4") - }; - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(u, role.Name)); - Assert.True(await manager.IsInRoleAsync(u, role.Name)); - } - } - - [Fact] - public async Task CanGetRolesForUser() - { - var context = TestIdentityFactory.CreateContext(); - var userManager = TestIdentityFactory.CreateManager(context); - var roleManager = TestIdentityFactory.CreateRoleManager(context); - InMemoryUser[] users = - { - new InMemoryUser("u1"), new InMemoryUser("u2"), new InMemoryUser("u3"), - new InMemoryUser("u4") - }; - IdentityRole[] roles = - { - new IdentityRole("r1"), new IdentityRole("r2"), new IdentityRole("r3"), - new IdentityRole("r4") - }; - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - foreach (var u in users) - { - var rs = await userManager.GetRolesAsync(u); - Assert.Equal(roles.Length, rs.Count); - foreach (var r in roles) - { - Assert.True(rs.Any(role => role == r.Name)); - } - } - } - - - [Fact] - public async Task RemoveUserFromRoleWithMultipleRoles() - { - var context = TestIdentityFactory.CreateContext(); - var userManager = TestIdentityFactory.CreateManager(context); - var roleManager = TestIdentityFactory.CreateRoleManager(context); - var user = new InMemoryUser("MultiRoleUser"); - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); - IdentityRole[] roles = - { - new IdentityRole("r1"), new IdentityRole("r2"), new IdentityRole("r3"), - new IdentityRole("r4") - }; - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, r.Name)); - Assert.True(await userManager.IsInRoleAsync(user, r.Name)); - } - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(user, roles[2].Name)); - Assert.False(await userManager.IsInRoleAsync(user, roles[2].Name)); - } - - [Fact] - public async Task CanRemoveUsersFromRole() - { - var context = TestIdentityFactory.CreateContext(); - var userManager = TestIdentityFactory.CreateManager(context); - var roleManager = TestIdentityFactory.CreateRoleManager(context); - InMemoryUser[] users = - { - new InMemoryUser("1"), new InMemoryUser("2"), new InMemoryUser("3"), - new InMemoryUser("4") - }; - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - var r = new IdentityRole("r1"); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(u, r.Name)); - Assert.False(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - [Fact] - public async Task RemoveUserNotInRoleFails() - { - var context = TestIdentityFactory.CreateContext(); - var userMgr = TestIdentityFactory.CreateManager(context); - var roleMgr = TestIdentityFactory.CreateRoleManager(context); - var role = new IdentityRole("addUserDupeTest"); - var user = new InMemoryUser("user1"); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - var result = await userMgr.RemoveFromRoleAsync(user, role.Name); - IdentityResultAssert.IsFailure(result, "User is not in role."); - } - - [Fact] - public async Task AddUserToUnknownRoleFails() - { - var manager = TestIdentityFactory.CreateManager(); - var u = new InMemoryUser("u1"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - await Assert.ThrowsAsync( - async () => await manager.AddToRoleAsync(u, "bogus")); - } - - [Fact] - public async Task AddUserToRoleFailsIfAlreadyInRole() - { - var context = TestIdentityFactory.CreateContext(); - var userMgr = TestIdentityFactory.CreateManager(context); - var roleMgr = TestIdentityFactory.CreateRoleManager(context); - var role = new IdentityRole("addUserDupeTest"); - var user = new InMemoryUser("user1"); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - Assert.True(await userMgr.IsInRoleAsync(user, role.Name)); - IdentityResultAssert.IsFailure(await userMgr.AddToRoleAsync(user, role.Name), "User already in role."); - } - - [Fact] - public async Task CanFindRoleByNameWithManager() - { - var roleMgr = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("findRoleByNameTest"); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role.Id, (await roleMgr.FindByNameAsync(role.Name)).Id); - } - - [Fact] - public async Task CanFindRoleWithManager() - { - var roleMgr = TestIdentityFactory.CreateRoleManager(); - var role = new IdentityRole("findRoleTest"); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role, await roleMgr.FindByIdAsync(role.Id)); - } - - [Fact] - public async Task SetPhoneNumberTest() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "PhoneTest"; - var user = new InMemoryUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - -#if NET45 - [Fact] - public async Task CanChangePhoneNumber() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "PhoneTest"; - var user = new InMemoryUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, "111-111-1111"); - IdentityResultAssert.IsSuccess(await manager.ChangePhoneNumberAsync(user, "111-111-1111", token1)); - Assert.True(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePhoneNumberFailsWithWrongToken() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "PhoneTest"; - var user = new InMemoryUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - IdentityResultAssert.IsFailure(await manager.ChangePhoneNumberAsync(user, "111-111-1111", "bogus"), - "Invalid token."); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanVerifyPhoneNumber() - { - var manager = TestIdentityFactory.CreateManager(); - const string userName = "VerifyPhoneTest"; - var user = new InMemoryUser(userName); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string num1 = "111-123-4567"; - const string num2 = "111-111-1111"; - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, num1); - var token2 = await manager.GenerateChangePhoneNumberTokenAsync(user, num2); - Assert.NotEqual(token1, token2); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num1)); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num2)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num1)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num2)); - } -#endif - - private class EmailTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, InMemoryUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - InMemoryUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose)); - } - - public Task NotifyAsync(string token, UserManager manager, InMemoryUser user, CancellationToken cancellationToken) - { - return manager.SendEmailAsync(user, token, token); - } - - public async Task IsValidProviderForUserAsync(UserManager manager, InMemoryUser user, CancellationToken token) - { - return !string.IsNullOrEmpty(await manager.GetEmailAsync(user)); - } - - private static string MakeToken(string purpose) - { - return "email:" + purpose; - } - } - - private class SmsTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, InMemoryUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - InMemoryUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose)); - } - - public Task NotifyAsync(string token, UserManager manager, InMemoryUser user, CancellationToken cancellationToken) - { - return manager.SendSmsAsync(user, token); - } - - public async Task IsValidProviderForUserAsync(UserManager manager, InMemoryUser user, CancellationToken token) - { - return !string.IsNullOrEmpty(await manager.GetPhoneNumberAsync(user)); - } - - private static string MakeToken(string purpose) - { - return "sms:" + purpose; - } - } - - [Fact] - public async Task CanEmailTwoFactorToken() - { - var manager = TestIdentityFactory.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new InMemoryUser("EmailCodeTest") { Email = "foo@foo.com" }; - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Subject); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task NotifyWithUnknownProviderFails() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("NotifyFail"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await - ExceptionAssert.ThrowsAsync( - async () => await manager.NotifyTwoFactorTokenAsync(user, "Bogus", "token"), - "No IUserTwoFactorProvider for 'Bogus' is registered."); - } - - - //[Fact] - //public async Task EmailTokenFactorWithFormatTest() - //{ - // var manager = TestIdentityFactory.CreateManager(); - // var messageService = new TestMessageService(); - // manager.EmailService = messageService; - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - // { - // Subject = "Security Code", - // BodyFormat = "Your code is: {0}" - // }); - // var user = new InMemoryUser("EmailCodeTest") { Email = "foo@foo.com" }; - // const string password = "password"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Security Code", messageService.Message.Subject); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - //[Fact] - //public async Task EmailFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = TestIdentityFactory.CreateManager(); - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - // var user = new InMemoryUser("EmailCodeTest") { Email = "foo@foo.com" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task EnableTwoFactorChangesSecurityStamp() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("TwoFactorEnabledTest"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.SetTwoFactorEnabledAsync(user, true)); - Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user)); - Assert.True(await manager.GetTwoFactorEnabledAsync(user)); - } - - [Fact] - public async Task CanSendSms() - { - var manager = TestIdentityFactory.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - var user = new InMemoryUser("SmsTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendSmsAsync(user, "Hi"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Body); - } - - [Fact] - public async Task CanSendEmail() - { - var manager = TestIdentityFactory.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var user = new InMemoryUser("EmailTest") { Email = "foo@foo.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendEmailAsync(user, "Hi", "Body"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Subject); - Assert.Equal("Body", messageService.Message.Body); - } - - [Fact] - public async Task CanSmsTwoFactorToken() - { - var manager = TestIdentityFactory.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new InMemoryUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - //[Fact] - //public async Task PhoneTokenFactorFormatTest() - //{ - // var manager = TestIdentityFactory.CreateManager(); - // var messageService = new TestMessageService(); - // manager.SmsService = messageService; - // const string factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider - // { - // MessageFormat = "Your code is: {0}" - // }); - // var user = new InMemoryUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("PhoneCodeTest"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; - await - ExceptionAssert.ThrowsAsync( - () => manager.GenerateTwoFactorTokenAsync(user, "bogus"), error); - await ExceptionAssert.ThrowsAsync( - () => manager.VerifyTwoFactorTokenAsync(user, "bogus", "bogus"), error); - } - - [Fact] - public async Task GetValidTwoFactorTestEmptyWithNoProviders() - { - var manager = TestIdentityFactory.CreateManager(); - var user = new InMemoryUser("test"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - } - - [Fact] - public async Task GetValidTwoFactorTest() - { - var manager = TestIdentityFactory.CreateManager(); - manager.RegisterTwoFactorProvider("phone", new SmsTokenProvider()); - manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); - var user = new InMemoryUser("test"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, "test@test.com")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 2); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - } - - //[Fact] - //public async Task PhoneFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = TestIdentityFactory.CreateManager(); - // var factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - // var user = new InMemoryUser("PhoneCodeTest"); - // user.PhoneNumber = "4251234567"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task VerifyTokenFromWrongTokenProviderFails() - { - var manager = TestIdentityFactory.CreateManager(); - manager.RegisterTwoFactorProvider("PhoneCode", new SmsTokenProvider()); - manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); - var user = new InMemoryUser("WrongTokenProviderTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateTwoFactorTokenAsync(user, "PhoneCode"); - Assert.NotNull(token); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, "EmailCode", token)); - } - - [Fact] - public async Task VerifyWithWrongSmsTokenFails() - { - var manager = TestIdentityFactory.CreateManager(); - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new InMemoryUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, "bogus")); - } - - public class TestMessageService : IIdentityMessageService - { - public IdentityMessage Message { get; set; } - - public Task SendAsync(IdentityMessage message, CancellationToken token) - { - Message = message; - return Task.FromResult(0); - } - } - } -} diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/RoleStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/RoleStoreTest.cs index f1e98bb85d..e6adbc9247 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/RoleStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/RoleStoreTest.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test var services = new ServiceCollection(); services.AddEntityFramework().AddInMemoryStore(); var store = new RoleStore(new InMemoryContext()); - services.AddIdentity().AddRoleStore(() => store); + services.AddIdentity().AddRoleStore(() => store); var provider = services.BuildServiceProvider(); var manager = provider.GetService>(); Assert.NotNull(manager); diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs index 3591b3e724..3c24bbdc3c 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs @@ -21,12 +21,12 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return db; } - public static UserManager CreateManager(InMemoryContext context) + public static UserManager CreateManager(InMemoryContext context) { - return MockHelpers.CreateManager(() => new InMemoryUserStore(context)); + return MockHelpers.CreateManager(() => new InMemoryUserStore(context)); } - public static UserManager CreateManager() + public static UserManager CreateManager() { return CreateManager(CreateContext()); } @@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test public static RoleManager CreateRoleManager(InMemoryContext context) { var services = new ServiceCollection(); - services.AddIdentity().AddRoleStore(() => new RoleStore(context)); + services.AddIdentity().AddRoleStore(() => new RoleStore(context)); return services.BuildServiceProvider().GetService>(); } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs new file mode 100644 index 0000000000..8f08ba9feb --- /dev/null +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs @@ -0,0 +1,182 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Identity.Test; +using Microsoft.Data.Entity; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.AspNet.Identity.EntityFramework.Test +{ + + public abstract class SqlStoreTestBase : UserManagerTestBase + where TUser : IdentityUser, new() + where TRole : IdentityRole, new() + where TKey : IEquatable + { + public abstract string ConnectionString { get; } + + public class ApplicationDbContext : IdentityDbContext + { + public ApplicationDbContext(IServiceProvider services, IOptionsAccessor options) : base(services, options.Options) { } + } + + [TestPriority(-1)] + [Fact] + public void RecreateDatabase() + { + CreateContext(true); + } + + public ApplicationDbContext CreateContext(bool delete = false) + { + var services = new ServiceCollection(); + services.AddEntityFramework().AddSqlServer(); + services.Add(OptionsServices.GetDefaultServices()); + services.SetupOptions(options => + options.UseSqlServer(ConnectionString)); + var serviceProvider = services.BuildServiceProvider(); + var db = new ApplicationDbContext(serviceProvider, + serviceProvider.GetService>()); + if (delete) + { + db.Database.EnsureDeleted(); + } + db.Database.EnsureCreated(); + return db; + } + + protected override object CreateTestContext() + { + return CreateContext(); + } + + protected override UserManager CreateManager(object context = null) + { + if (context == null) + { + context = CreateTestContext(); + } + return MockHelpers.CreateManager(() => new UserStore((ApplicationDbContext)context)); + } + + protected override RoleManager CreateRoleManager(object context = null) + { + if (context == null) + { + context = CreateTestContext(); + } + var services = new ServiceCollection(); + services.AddIdentity().AddRoleStore(() => new RoleStore((ApplicationDbContext)context)); + return services.BuildServiceProvider().GetService>(); + } + + public void EnsureDatabase() + { + CreateContext(); + } + + [Fact] + public async Task EnsureStartupUsageWorks() + { + EnsureDatabase(); + IBuilder builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider()); + + builder.UseServices(services => + { + services.AddEntityFramework().AddSqlServer(); + services.AddIdentitySqlServer(); + services.SetupOptions(options => + options.UseSqlServer(ConnectionString)); + }); + + var userStore = builder.ApplicationServices.GetService>(); + var userManager = builder.ApplicationServices.GetService>(); + + Assert.NotNull(userStore); + Assert.NotNull(userManager); + + const string password = "1qaz@WSX"; + var user = CreateTestUser(); + user.UserName = "admin1111"; + IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); + IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user)); + } + + [Fact] + public async Task EnsureStartupOptionsChangeWorks() + { + EnsureDatabase(); + IBuilder builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider()); + + builder.UseServices(services => + { + services.AddEntityFramework().AddSqlServer(); + services.AddIdentitySqlServer().SetupOptions(options => + { + options.Password.RequiredLength = 1; + options.Password.RequireLowercase = false; + options.Password.RequireNonLetterOrDigit = false; + options.Password.RequireUppercase = false; + options.Password.RequireDigit = false; + options.User.AllowOnlyAlphanumericNames = false; + }); + services.SetupOptions(options => + options.UseSqlServer(ConnectionString)); + }); + + var userStore = builder.ApplicationServices.GetService>(); + var userManager = builder.ApplicationServices.GetService>(); + + Assert.NotNull(userStore); + Assert.NotNull(userManager); + + const string userName = "admin"; + const string password = "a"; + var user = CreateTestUser(userName); + IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); + IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user)); + } + + [Fact] + public void CanCreateUserUsingEF() + { + using (var db = CreateContext()) + { + var user = CreateTestUser(); + db.Users.Add(user); + db.SaveChanges(); + Assert.True(db.Users.Any(u => u.UserName == user.UserName)); + Assert.NotNull(db.Users.FirstOrDefault(u => u.UserName == user.UserName)); + } + } + + [Fact] + public async Task CanCreateUsingManager() + { + var manager = CreateManager(); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); + } + + [Fact] + public async Task EnsureRoleClaimNavigationProperty() + { + var context = CreateContext(); + var roleManager = CreateRoleManager(context); + var r = CreateRole(); + IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); + var c = new Claim("a", "b"); + IdentityResultAssert.IsSuccess(await roleManager.AddClaimAsync(r, c)); + Assert.NotNull(r.Claims.Single(cl => cl.ClaimValue == c.Value && cl.ClaimType == c.Type)); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs index 51b3874c96..832bfa981d 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } [TestCaseOrderer("Microsoft.AspNet.Identity.Test.PriorityOrderer", "Microsoft.AspNet.Identity.EntityFramework.Test")] - public class UserStoreGuidTest : UserStoreTestBase + public class UserStoreGuidTest : SqlStoreTestBase { public override string ConnectionString { @@ -58,15 +58,23 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } } - public override UserManager CreateManager(ApplicationDbContext context) + protected override UserManager CreateManager(object context) { - return MockHelpers.CreateManager(() => new ApplicationUserStore(context)); + if (context == null) + { + context = CreateTestContext(); + } + return MockHelpers.CreateManager(() => new ApplicationUserStore((ApplicationDbContext)context)); } - public override RoleManager CreateRoleManager(ApplicationDbContext context) + protected override RoleManager CreateRoleManager(object context) { + if (context == null) + { + context = CreateTestContext(); + } var services = new ServiceCollection(); - services.AddIdentity().AddRoleStore(() => new ApplicationRoleStore(context)); + services.AddIdentity().AddRoleStore(() => new ApplicationRoleStore((ApplicationDbContext)context)); return services.BuildServiceProvider().GetService>(); } } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreIntKeyTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreIntKeyTest.cs index 09b9c82885..e1e357bb08 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreIntKeyTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreIntKeyTest.cs @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Identity.Test; +using Microsoft.Data.Entity; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; using System; using Xunit; @@ -26,7 +28,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } [TestCaseOrderer("Microsoft.AspNet.Identity.Test.PriorityOrderer", "Microsoft.AspNet.Identity.EntityFramework.Test")] - public class UserStoreIntTest : UserStoreTestBase + public class UserStoreIntTest : SqlStoreTestBase { public override string ConnectionString { @@ -35,17 +37,5 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return @"Server=(localdb)\v11.0;Database=SqlUserStoreIntTest;Trusted_Connection=True;"; } } - - public override UserManager CreateManager(ApplicationDbContext context) - { - return MockHelpers.CreateManager(() => new UserStore(context)); - } - - public override RoleManager CreateRoleManager(ApplicationDbContext context) - { - var services = new ServiceCollection(); - services.AddIdentity().AddRoleStore(() => new RoleStore(context)); - return services.BuildServiceProvider().GetService>(); - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreStringKeyTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreStringKeyTest.cs index 41522b455f..b329f0b71d 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreStringKeyTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreStringKeyTest.cs @@ -1,9 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Identity.Test; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; using System; using Xunit; @@ -29,7 +26,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } [TestCaseOrderer("Microsoft.AspNet.Identity.Test.PriorityOrderer", "Microsoft.AspNet.Identity.EntityFramework.Test")] - public class UserStoreStringKeyTest : UserStoreTestBase + public class UserStoreStringKeyTest : SqlStoreTestBase { public override string ConnectionString { @@ -38,17 +35,5 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return @"Server=(localdb)\v11.0;Database=SqlUserStoreStringTest;Trusted_Connection=True;"; } } - - public override UserManager CreateManager(ApplicationDbContext context) - { - return MockHelpers.CreateManager(() => new UserStore(context)); - } - - public override RoleManager CreateRoleManager(ApplicationDbContext context) - { - var services = new ServiceCollection(); - services.AddIdentity().AddRoleStore(() => new RoleStore(context)); - return services.BuildServiceProvider().GetService>(); - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs index e6418cd42d..4f23f31ba4 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs @@ -19,9 +19,9 @@ using Xunit; namespace Microsoft.AspNet.Identity.EntityFramework.Test { [TestCaseOrderer("Microsoft.AspNet.Identity.Test.PriorityOrderer", "Microsoft.AspNet.Identity.EntityFramework.Test")] - public class UserStoreTest + public class UserStoreTest : UserManagerTestBase { - private const string ConnectionString = @"Server=(localdb)\v11.0;Database=SqlUserStoreTest;Trusted_Connection=True;"; + private const string ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=UserStoreTest;Trusted_Connection=True;"; public class ApplicationUser : IdentityUser { } @@ -126,6 +126,11 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return db; } + protected override object CreateTestContext() + { + return CreateContext(); + } + public static void EnsureDatabase() { CreateContext(); @@ -149,9 +154,13 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return MockHelpers.CreateManager(() => new UserStore(context)); } - public static UserManager CreateManager() + protected override UserManager CreateManager(object context = null) { - return CreateManager(CreateContext()); + if (context == null) + { + context = CreateTestContext(); + } + return CreateManager((DbContext)context); } public static RoleManager CreateRoleManager(IdentityDbContext context) @@ -161,9 +170,13 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return services.BuildServiceProvider().GetService>(); } - public static RoleManager CreateRoleManager() + protected override RoleManager CreateRoleManager(object context) { - return CreateRoleManager(CreateContext()); + if (context == null) + { + context = CreateTestContext(); + } + return CreateRoleManager((IdentityDbContext)context); } [Fact] @@ -179,11 +192,11 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test await Assert.ThrowsAsync(async () => await store.GetRolesAsync(null)); await Assert.ThrowsAsync(async () => await store.IsInRoleAsync(null, null)); await Assert.ThrowsAsync(async () => await store.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.RemoveLoginAsync(null, null)); + await Assert.ThrowsAsync(async () => await store.RemoveLoginAsync(null, null, null)); await Assert.ThrowsAsync( async () => await store.RemoveFromRoleAsync(null, null)); await Assert.ThrowsAsync(async () => await store.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync(async () => await store.FindByLoginAsync(null)); + await Assert.ThrowsAsync(async () => await store.FindByLoginAsync(null, null)); await Assert.ThrowsAsync(async () => await store.FindByIdAsync(null)); await Assert.ThrowsAsync(async () => await store.FindByNameAsync(null)); await Assert.ThrowsAsync(async () => await store.CreateAsync(null)); @@ -216,7 +229,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test await Assert.ThrowsAsync("user", async () => await store.GetRolesAsync(null)); await Assert.ThrowsAsync("user", async () => await store.AddLoginAsync(null, null)); await - Assert.ThrowsAsync("user", async () => await store.RemoveLoginAsync(null, null)); + Assert.ThrowsAsync("user", async () => await store.RemoveLoginAsync(null, null, null)); await Assert.ThrowsAsync("user", async () => await store.AddToRoleAsync(null, null)); await Assert.ThrowsAsync("user", @@ -229,15 +242,11 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test await Assert.ThrowsAsync("user", async () => await store.GetSecurityStampAsync(null)); await Assert.ThrowsAsync("user", async () => await store.SetSecurityStampAsync(null, null)); + await Assert.ThrowsAsync("login", async () => await store.AddLoginAsync(new IdentityUser("fake"), null)); await Assert.ThrowsAsync("claims", async () => await store.AddClaimsAsync(new IdentityUser("fake"), null)); await Assert.ThrowsAsync("claims", async () => await store.RemoveClaimsAsync(new IdentityUser("fake"), null)); - await Assert.ThrowsAsync("login", - async () => await store.AddLoginAsync(new IdentityUser("fake"), null)); - await Assert.ThrowsAsync("login", - async () => await store.RemoveLoginAsync(new IdentityUser("fake"), null)); - await Assert.ThrowsAsync("login", async () => await store.FindByLoginAsync(null)); await Assert.ThrowsAsync("user", async () => await store.GetEmailConfirmedAsync(null)); await Assert.ThrowsAsync("user", async () => await store.SetEmailConfirmedAsync(null, true)); @@ -277,367 +286,6 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); } - [Fact] - public async Task CanDeleteUser() - { - var manager = CreateManager(); - var user = new IdentityUser("CanDeleteUser"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - Assert.Null(await manager.FindByIdAsync(user.Id)); - } - - [Fact] - public async Task CanUpdateUserName() - { - var manager = CreateManager(); - var oldName = Guid.NewGuid().ToString(); - var user = new IdentityUser(oldName); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var newName = Guid.NewGuid().ToString(); - user.UserName = newName; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.NotNull(await manager.FindByNameAsync(newName)); - Assert.Null(await manager.FindByNameAsync(oldName)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task CanUpdatePasswordUsingHasher() - { - var manager = CreateManager(); - var user = new IdentityUser("CanUpdatePasswordUsingHasher"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - Assert.True(await manager.CheckPasswordAsync(user, "password")); - user.PasswordHash = manager.PasswordHasher.HashPassword(user, "New"); - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.False(await manager.CheckPasswordAsync(user, "password")); - Assert.True(await manager.CheckPasswordAsync(user, "New")); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task CanSetUserName() - { - var manager = CreateManager(); - var oldName = Guid.NewGuid().ToString(); - var user = new IdentityUser(oldName); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var newName = Guid.NewGuid().ToString(); - IdentityResultAssert.IsSuccess(await manager.SetUserNameAsync(user, newName)); - Assert.NotNull(await manager.FindByNameAsync(newName)); - Assert.Null(await manager.FindByNameAsync(oldName)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task RemoveClaimOnlyForUser() - { - var manager = CreateManager(); - var user = new IdentityUser("RemoveClaimForMe"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task UserValidatorCanBlockCreate() - { - var manager = CreateManager(); - var user = new IdentityUser("UserValidatorCanBlockCreate"); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task UserValidatorCanBlockUpdate() - { - var manager = CreateManager(); - var user = new IdentityUser("UserValidatorCanBlockUpdate"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - public async Task UserValidatorBlocksShortEmailsWhenRequiresUniqueEmail(string email) - { - var manager = CreateManager(); - var user = new IdentityUser("UserValidatorBlocksShortEmailsWhenRequiresUniqueEmail") { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email cannot be null or empty."); - } - -#if NET45 - [Theory] - [InlineData("@@afd")] - [InlineData("bogus")] - public async Task UserValidatorBlocksInvalidEmailsWhenRequiresUniqueEmail(string email) - { - var manager = CreateManager(); - var user = new IdentityUser("UserValidatorBlocksInvalidEmailsWhenRequiresUniqueEmail") { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email '" + email + "' is invalid."); - } -#endif - - [Fact] - public async Task PasswordValidatorCanBlockAddPassword() - { - var manager = CreateManager(); - var user = new IdentityUser("AddPasswordBlocked"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task PasswordValidatorCanBlockChangePassword() - { - var manager = CreateManager(); - var user = new IdentityUser("ChangePasswordBlocked"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ChangePasswordAsync(user, "password", "new"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task CanCreateUserNoPassword() - { - var manager = CreateManager(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new IdentityUser("CanCreateUserNoPassword"))); - var user = await manager.FindByNameAsync("CanCreateUserNoPassword"); - Assert.NotNull(user); - Assert.Null(user.PasswordHash); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - } - - [Fact] - public async Task CanCreateUserAddLogin() - { - var manager = CreateManager(); - const string userName = "CanCreateUserAddLogin"; - const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new IdentityUser(userName))); - var user = await manager.FindByNameAsync(userName); - Assert.NotNull(user); - var login = new UserLoginInfo(provider, providerKey); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(provider, logins.First().LoginProvider); - Assert.Equal(providerKey, logins.First().ProviderKey); - } - - [Fact] - public async Task CanCreateUserLoginAndAddPassword() - { - var manager = CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new IdentityUser("CreateUserLoginAddPasswordTest"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.False(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddPasswordAsync(user, "password")); - Assert.True(await manager.HasPasswordAsync(user)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(user, await manager.FindByLoginAsync(login)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, "password")); - } - - [Fact] - public async Task AddPasswordFailsIfAlreadyHave() - { - var manager = CreateManager(); - var user = new IdentityUser("CannotAddAnotherPassword"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "Password")); - Assert.True(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - "User already has a password set."); - } - - [Fact] - public async Task CanCreateUserAddRemoveLogin() - { - var manager = CreateManager(); - var user = new IdentityUser("CreateUserAddRemoveLoginTest"); - var login = new UserLoginInfo("Provider", "key"); - var result = await manager.CreateAsync(user); - Assert.NotNull(user); - IdentityResultAssert.IsSuccess(result); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.Equal(user, await manager.FindByLoginAsync(login)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); - Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemoveLoginAsync(user, login)); - Assert.Null(await manager.FindByLoginAsync(login)); - logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanRemovePassword() - { - var manager = CreateManager(); - var user = new IdentityUser("RemovePasswordTest"); - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemovePasswordAsync(user)); - var u = await manager.FindByNameAsync(user.UserName); - Assert.NotNull(u); - Assert.Null(u.PasswordHash); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanChangePassword() - { - var manager = CreateManager(); - var user = new IdentityUser("ChangePasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, password, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanAddRemoveUserClaim() - { - var manager = CreateManager(); - var user = new IdentityUser("ClaimsAddRemove"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; - foreach (var c in claims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - Assert.NotNull(user.Claims.Single(cl => cl.ClaimType == c.Type && cl.ClaimValue == c.Value)); - } - var userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(3, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(2, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(1, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(0, userClaims.Count); - } - - [Fact] - public async Task ChangePasswordFallsIfPasswordWrong() - { - var manager = CreateManager(); - var user = new IdentityUser("user"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - var result = await manager.ChangePasswordAsync(user, "bogus", "newpassword"); - IdentityResultAssert.IsFailure(result, "Incorrect password."); - } - - [Fact] - public async Task AddDupeUserNameFails() - { - var manager = CreateManager(); - var user = new IdentityUser("AddDupeUserNameFails"); - var user2 = new IdentityUser("AddDupeUserNameFails"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Name AddDupeUserNameFails is already taken."); - } - - [Fact] - public async Task AddDupeEmailAllowedByDefault() - { - var manager = CreateManager(); - var user = new IdentityUser("AddDupeEmailAllowedByDefault") { Email = "yup@yup.com" }; - var user2 = new IdentityUser("AddDupeEmailAllowedByDefault2") { Email = "yup@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - } - - [Fact] - public async Task AddDupeEmailFallsWhenUniqueEmailRequired() - { - var manager = CreateManager(); - manager.Options.User.RequireUniqueEmail = true; - var user = new IdentityUser("AddDupeEmailFallsWhenUniqueEmailRequired") { Email = "dupeEmailTrue@yup.com" }; - var user2 = new IdentityUser("AddDupeEmailFallsWhenUniqueEmailRequiredDupe") { Email = "dupeEmailTrue@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Email 'dupeEmailTrue@yup.com' is already taken."); - } - - [Fact] - public async Task UpdateSecurityStampActuallyChanges() - { - var manager = CreateManager(); - var user = new IdentityUser("UpdateSecurityStampActuallyChanges"); - Assert.Null(user.SecurityStamp); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task AddDupeLoginFails() - { - var manager = CreateManager(); - var user = new IdentityUser("DupeLogin"); - var login = new UserLoginInfo("provder", "key"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var result = await manager.AddLoginAsync(user, login); - IdentityResultAssert.IsFailure(result, "A user with that external login already exists."); - } - - // Email tests - [Fact] - public async Task CanFindByEmail() - { - var manager = CreateManager(); - const string userName = "EmailTest"; - const string email = "email@test.com"; - var user = new IdentityUser(userName) { Email = email }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var fetch = await manager.FindByEmailAsync(email); - Assert.Equal(user, fetch); - } - - [Fact] - public async Task CanFindUsersViaUserQuerable() - { - var mgr = CreateManager(); - var users = GenerateUsers("CanFindUsersViaUserQuerable", 3); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(u)); - } - var usersQ = mgr.Users.Where(u => u.UserName.StartsWith("CanFindUsersViaUserQuerable")); - Assert.Null(mgr.Users.FirstOrDefault(u => u.UserName == "bogus")); - } - [Fact] public async Task EnsureRoleClaimNavigationProperty() { @@ -651,524 +299,23 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } [Fact] - public async Task ClaimsIdentityCreatesExpectedClaims() - { - var context = CreateContext(); - var manager = CreateManager(context); - var role = CreateRoleManager(context); - var user = new IdentityUser("ClaimsIdentityCreatesExpectedClaims"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var admin = new IdentityRole("Admin"); - var local = new IdentityRole("Local"); - IdentityResultAssert.IsSuccess(await role.CreateAsync(admin)); - IdentityResultAssert.IsSuccess(await role.CreateAsync(local)); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Admin")); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Local")); - Claim[] userClaims = - { - new Claim("Whatever", "Value"), - new Claim("Whatever2", "Value2") - }; - foreach (var c in userClaims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - } - Claim[] adminClaims = - { - new Claim("Admin", "Value"), - }; - foreach (var c in adminClaims) - { - IdentityResultAssert.IsSuccess(await role.AddClaimAsync(admin, c)); - } - Claim[] localClaims = - { - new Claim("Local", "Value"), - new Claim("Local2", "Value2") - }; - foreach (var c in localClaims) - { - IdentityResultAssert.IsSuccess(await role.AddClaimAsync(local, c)); - } - - var claimsFactory = new ClaimsIdentityFactory(manager, role); - var identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); - var claims = identity.Claims.ToList(); - Assert.NotNull(claims); - Assert.True( - claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName)); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id.ToString())); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin")); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local")); - foreach (var cl in userClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - foreach (var cl in adminClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - foreach (var cl in localClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - - // Remove a role claim and make sure its not there - IdentityResultAssert.IsSuccess(await role.RemoveClaimAsync(local, localClaims[0])); - identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); - claims = identity.Claims.ToList(); - Assert.False(claims.Any(c => c.Type == localClaims[0].Type && c.Value == localClaims[0].Value)); - Assert.True(claims.Any(c => c.Type == localClaims[1].Type && c.Value == localClaims[1].Value)); - } - - [Fact] - public async Task ConfirmEmailFalseByDefaultTest() + public async Task AddUserToUnknownRoleFails() { var manager = CreateManager(); - var user = new IdentityUser("ConfirmEmailFalseByDefaultTest"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: No token provider implementations yet - private class StaticTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, - IdentityUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose, user)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - IdentityUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose, user)); - } - - public Task NotifyAsync(string token, UserManager manager, IdentityUser user, CancellationToken cancellationToken) - { - return Task.FromResult(0); - } - - public Task IsValidProviderForUserAsync(UserManager manager, IdentityUser user, CancellationToken token) - { - return Task.FromResult(true); - } - - private static string MakeToken(string purpose, IdentityUser user) - { - return string.Join(":", user.Id, purpose, "ImmaToken"); - } - } - - [Fact] - public async Task CanResetPasswordWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("CanResetPasswordWithStaticTokenProvider"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ResetPasswordAsync(user, token, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, token, newPassword), - AlwaysBadValidator.ErrorMessage); - Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordWithStaticTokenProviderFailsWithWrongToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("ResetPasswordWithStaticTokenProviderFailsWithWrongToken"); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, "bogus", newPassword), "Invalid token."); - Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("CanGenerateAndVerifyUserTokenWithStaticTokenProvider"); - var user2 = new IdentityUser("CanGenerateAndVerifyUserTokenWithStaticTokenProvider2"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - var token = await manager.GenerateUserTokenAsync("test", user); - Assert.True(await manager.VerifyUserTokenAsync(user, "test", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test2", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test", token + "a")); - Assert.False(await manager.VerifyUserTokenAsync(user2, "test", token)); - } - - [Fact] - public async Task CanConfirmEmailWithStaticToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("CanConfirmEmailWithStaticToken"); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ConfirmEmailAsync(user, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user)); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - [Fact] - public async Task ConfirmEmailWithStaticTokenFailsWithWrongToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new IdentityUser("ConfirmEmailWithStaticTokenFailsWithWrongToken"); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, "bogus"), "Invalid token."); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: Can't reenable til we have a SecurityStamp linked token provider - //[Fact] - //public async Task ConfirmTokenFailsAfterPasswordChange() - //{ - // var manager = CreateManager(); - // var user = new IdentityUser("test"); - // Assert.False(user.EmailConfirmed); - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - // var token = await manager.GenerateEmailConfirmationTokenAsync(user); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, "password", "newpassword")); - // IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, token), "Invalid token."); - // Assert.False(await manager.IsEmailConfirmedAsync(user)); - //} - - // Lockout tests - - [Fact] - public async Task SingleFailureLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 0; - var user = new IdentityUser("SingleFailureLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task TwoFailureLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new IdentityUser("twoFailureLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task ResetAccessCountPreventsLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new IdentityUser("ResetAccessCountPreventsLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.ResetAccessFailedCountAsync(user)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task CanEnableLockoutManuallyAndLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new IdentityUser("manualLockout"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEnabledAsync(user, true)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new IdentityUser("UserNotLockedOutWithNullDateTimeAndIsSetToNullDate"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset())); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.Equal(new DateTimeOffset(), await mgr.GetLockoutEndDateAsync(user)); - } - - [Fact] - public async Task LockoutFailsIfNotEnabled() - { - var mgr = CreateManager(); - var user = new IdentityUser("LockoutFailsIfNotEnabled"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsFailure(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset()), - "Lockout is not enabled for this user."); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new IdentityUser("LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut") { LockoutEnd = DateTime.UtcNow.AddSeconds(-1) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new IdentityUser("LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.AddSeconds(-1))); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new IdentityUser("LockoutEndToUtcNowPlus5ShouldBeLockedOut") { LockoutEnd = DateTime.UtcNow.AddMinutes(5) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.True(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task UserLockedOutWithDateTimeLocalKindNowPlus30() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new IdentityUser("UserLockedOutWithDateTimeLocalKindNowPlus30"); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - var lockoutEnd = new DateTimeOffset(DateTime.Now.AddMinutes(30).ToLocalTime()); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, lockoutEnd)); - Assert.True(await mgr.IsLockedOutAsync(user)); - var end = await mgr.GetLockoutEndDateAsync(user); - Assert.Equal(lockoutEnd, end); - } - - // Role Tests - [Fact] - public async Task CanCreateRoleTest() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CanCreateRoleTest"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - } - - private class AlwaysBadValidator : IUserValidator, IRoleValidator, - IPasswordValidator - { - public const string ErrorMessage = "I'm Bad."; - - public Task ValidateAsync(string password, UserManager manager, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(RoleManager manager, IdentityRole role, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(UserManager manager, IdentityUser user, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - } - - [Fact] - public async Task BadValidatorBlocksCreateRole() - { - var manager = CreateRoleManager(); - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(new IdentityRole("blocked")), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task BadValidatorBlocksRoleUpdate() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("BadValidatorBlocksRoleUpdate"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - var error = AlwaysBadValidator.ErrorMessage; - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(role), error); - } - - [Fact] - public async Task CanDeleteRole() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CanDeleteRole"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(role)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - } - - [Fact] - public async Task CanRoleFindById() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CanRoleFindById"); - Assert.Null(await manager.FindByIdAsync(role.Id)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByIdAsync(role.Id)); - } - - [Fact] - public async Task CanRoleFindByName() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CanRoleFindByName"); - Assert.Null(await manager.FindByNameAsync(role.Name)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByNameAsync(role.Name)); - } - - [Fact] - public async Task CanUpdateRoleName() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CanUpdateRoleName"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - role.Name = "CanUpdateRoleNameChanged"; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(role)); - Assert.False(await manager.RoleExistsAsync("CanUpdateRoleName")); - Assert.Equal(role, await manager.FindByNameAsync(role.Name)); - } - - [Fact] - public async Task CanQuerableRolesTest() - { - var manager = CreateRoleManager(); - var roles = GenerateRoles("CanQuerableRolesTest", 4); - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(r)); - } - Assert.Equal(roles.Count, manager.Roles.Count(r => r.Name.StartsWith("CanQuerableRolesTest"))); - var r1 = manager.Roles.FirstOrDefault(r => r.Name == "CanQuerableRolesTest1"); - Assert.Equal(roles[1], r1); + var u = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); + await Assert.ThrowsAsync( + async () => await manager.AddToRoleAsync(u, "bogus")); } + // TODO: can we move these to UserManagerTestBase? [Fact] public async Task DeleteRoleNonEmptySucceedsTest() { // Need fail if not empty? - var userMgr = CreateManager(); - var roleMgr = CreateRoleManager(); + var context = CreateTestContext(); + var userMgr = CreateManager(context); + var roleMgr = CreateRoleManager(context); var role = new IdentityRole("deleteNonEmpty"); Assert.False(await roleMgr.RoleExistsAsync(role.Name)); IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); @@ -1204,580 +351,5 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test // role = await roleMgr.FindByIdAsync(role.Id); // Assert.Equal(0, role.Users.Count); //} - - [Fact] - public async Task CreateRoleFailsIfExists() - { - var manager = CreateRoleManager(); - var role = new IdentityRole("CreateRoleFailsIfExists"); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - var role2 = new IdentityRole("CreateRoleFailsIfExists"); - IdentityResultAssert.IsFailure(await manager.CreateAsync(role2)); - } - - [Fact] - public async Task CanAddUsersToRole() - { - var context = CreateContext(); - var manager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var role = new IdentityRole("CanAddUsersToRole"); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); - var users = GenerateUsers("CanAddUsersToRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(u, role.Name)); - Assert.True(await manager.IsInRoleAsync(u, role.Name)); - } - } - - private List GenerateUsers(string userNamePrefix, int count) - { - var users = new List(count); - for (var i=0; i GenerateRoles(string namePrefix, int count) - { - var roles = new List(count); - for (var i = 0; i < count; i++) - { - roles.Add(new IdentityRole(namePrefix + i)); - } - return roles; - } - - [Fact] - public async Task CanGetRolesForUser() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var users = GenerateUsers("CanGetRolesForUser", 4); - var roles = GenerateRoles("CanGetRolesForUserRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - foreach (var u in users) - { - var rs = await userManager.GetRolesAsync(u); - Assert.Equal(roles.Count, rs.Count); - foreach (var r in roles) - { - Assert.True(rs.Any(role => role == r.Name)); - } - } - } - - [Fact] - public async Task RemoveUserFromRoleWithMultipleRoles() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var user = new IdentityUser("RemoveUserFromRoleWithMultipleRoles"); - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); - var roles = GenerateRoles("RemoveUserFromRoleWithMultipleRoles", 4); - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, r.Name)); - Assert.True(await userManager.IsInRoleAsync(user, r.Name)); - } - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(user, roles[2].Name)); - Assert.False(await userManager.IsInRoleAsync(user, roles[2].Name)); - } - - [Fact] - public async Task CanRemoveUsersFromRole() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var users = GenerateUsers("CanRemoveUsersFromRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - var r = new IdentityRole("CanRemoveUsersFromRole"); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(u, r.Name)); - Assert.False(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - [Fact] - public async Task RemoveUserNotInRoleFails() - { - var context = CreateContext(); - var userMgr = CreateManager(context); - var roleMgr = CreateRoleManager(context); - var role = new IdentityRole("RemoveUserNotInRoleFails"); - var user = new IdentityUser("RemoveUserNotInRoleFails"); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - var result = await userMgr.RemoveFromRoleAsync(user, role.Name); - IdentityResultAssert.IsFailure(result, "User is not in role."); - } - - [Fact] - public async Task AddUserToUnknownRoleFails() - { - var manager = CreateManager(); - var u = new IdentityUser("AddUserToUnknownRoleFails"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - await Assert.ThrowsAsync( - async () => await manager.AddToRoleAsync(u, "bogus")); - } - - [Fact] - public async Task AddUserToRoleFailsIfAlreadyInRole() - { - var context = CreateContext(); - var userMgr = CreateManager(context); - var roleMgr = CreateRoleManager(context); - var role = new IdentityRole("AddUserToRoleFailsIfAlreadyInRole"); - var user = new IdentityUser("AddUserToRoleFailsIfAlreadyInRoleUser"); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - Assert.True(await userMgr.IsInRoleAsync(user, role.Name)); - IdentityResultAssert.IsFailure(await userMgr.AddToRoleAsync(user, role.Name), "User already in role."); - } - - [Fact] - public async Task CanFindRoleByNameWithManager() - { - var roleMgr = CreateRoleManager(); - var role = new IdentityRole("CanFindRoleByNameWithManager"); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role.Id, (await roleMgr.FindByNameAsync(role.Name)).Id); - } - - [Fact] - public async Task CanFindRoleWithManager() - { - var roleMgr = CreateRoleManager(); - var role = new IdentityRole("CanFindRoleWithManager"); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role, await roleMgr.FindByIdAsync(role.Id)); - } - - [Fact] - public async Task SetPhoneNumberTest() - { - var manager = CreateManager(); - const string userName = "SetPhoneNumberTest"; - var user = new IdentityUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - -#if NET45 - [Fact] - public async Task CanChangePhoneNumber() - { - var manager = CreateManager(); - const string userName = "CanChangePhoneNumber"; - var user = new IdentityUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, "111-111-1111"); - IdentityResultAssert.IsSuccess(await manager.ChangePhoneNumberAsync(user, "111-111-1111", token1)); - Assert.True(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePhoneNumberFailsWithWrongToken() - { - var manager = CreateManager(); - const string userName = "ChangePhoneNumberFailsWithWrongToken"; - var user = new IdentityUser(userName) { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - IdentityResultAssert.IsFailure(await manager.ChangePhoneNumberAsync(user, "111-111-1111", "bogus"), - "Invalid token."); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanVerifyPhoneNumber() - { - var manager = CreateManager(); - const string userName = "CanVerifyPhoneNumber"; - var user = new IdentityUser(userName); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string num1 = "111-123-4567"; - const string num2 = "111-111-1111"; - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, num1); - var token2 = await manager.GenerateChangePhoneNumberTokenAsync(user, num2); - Assert.NotEqual(token1, token2); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num1)); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num2)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num1)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num2)); - } -#endif - - private class EmailTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, IdentityUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - IdentityUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose)); - } - - public Task NotifyAsync(string token, UserManager manager, IdentityUser user, CancellationToken cancellationToken) - { - return manager.SendEmailAsync(user, token, token); - } - - public async Task IsValidProviderForUserAsync(UserManager manager, IdentityUser user, CancellationToken token) - { - return !string.IsNullOrEmpty(await manager.GetEmailAsync(user)); - } - - private static string MakeToken(string purpose) - { - return "email:" + purpose; - } - } - - private class SmsTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, IdentityUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - IdentityUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose)); - } - - public Task NotifyAsync(string token, UserManager manager, IdentityUser user, CancellationToken cancellationToken) - { - return manager.SendSmsAsync(user, token); - } - - public async Task IsValidProviderForUserAsync(UserManager manager, IdentityUser user, CancellationToken token) - { - return !string.IsNullOrEmpty(await manager.GetPhoneNumberAsync(user)); - } - - private static string MakeToken(string purpose) - { - return "sms:" + purpose; - } - } - - [Fact] - public async Task CanEmailTwoFactorToken() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new IdentityUser("CanEmailTwoFactorToken") { Email = "foo@foo.com" }; - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Subject); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task NotifyWithUnknownProviderFails() - { - var manager = CreateManager(); - var user = new IdentityUser("NotifyFail"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await - ExceptionAssert.ThrowsAsync( - async () => await manager.NotifyTwoFactorTokenAsync(user, "Bogus", "token"), - "No IUserTwoFactorProvider for 'Bogus' is registered."); - } - - - //[Fact] - //public async Task EmailTokenFactorWithFormatTest() - //{ - // var manager = CreateManager(); - // var messageService = new TestMessageService(); - // manager.EmailService = messageService; - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - // { - // Subject = "Security Code", - // BodyFormat = "Your code is: {0}" - // }); - // var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - // const string password = "password"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Security Code", messageService.Message.Subject); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - //[Fact] - //public async Task EmailFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = CreateManager(); - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - // var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task EnableTwoFactorChangesSecurityStamp() - { - var manager = CreateManager(); - var user = new IdentityUser("EnableTwoFactorChangesSecurityStamp"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.SetTwoFactorEnabledAsync(user, true)); - Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user)); - Assert.True(await manager.GetTwoFactorEnabledAsync(user)); - } - - [Fact] - public async Task CanSendSms() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - var user = new IdentityUser("SmsTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendSmsAsync(user, "Hi"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Body); - } - - [Fact] - public async Task CanSendEmail() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var user = new IdentityUser("CanSendEmail") { Email = "foo@foo.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendEmailAsync(user, "Hi", "Body"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Subject); - Assert.Equal("Body", messageService.Message.Body); - } - - [Fact] - public async Task CanSmsTwoFactorToken() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new IdentityUser("CanSmsTwoFactorToken") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - //[Fact] - //public async Task PhoneTokenFactorFormatTest() - //{ - // var manager = CreateManager(); - // var messageService = new TestMessageService(); - // manager.SmsService = messageService; - // const string factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider - // { - // MessageFormat = "Your code is: {0}" - // }); - // var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow() - { - var manager = CreateManager(); - var user = new IdentityUser("GenerateTwoFactorWithUnknownFactorProviderWillThrow"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; - await - ExceptionAssert.ThrowsAsync( - () => manager.GenerateTwoFactorTokenAsync(user, "bogus"), error); - await ExceptionAssert.ThrowsAsync( - () => manager.VerifyTwoFactorTokenAsync(user, "bogus", "bogus"), error); - } - - [Fact] - public async Task GetValidTwoFactorTestEmptyWithNoProviders() - { - var manager = CreateManager(); - var user = new IdentityUser("GetValidTwoFactorTestEmptyWithNoProviders"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - } - - [Fact] - public async Task CanGetValidTwoFactor() - { - var manager = CreateManager(); - manager.RegisterTwoFactorProvider("phone", new SmsTokenProvider()); - manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); - var user = new IdentityUser("CanGetValidTwoFactor"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, "test@test.com")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 2); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - } - - //[Fact] - //public async Task PhoneFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = CreateManager(); - // var factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - // var user = new IdentityUser("PhoneCodeTest"); - // user.PhoneNumber = "4251234567"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} - - [Fact] - public async Task VerifyTokenFromWrongTokenProviderFails() - { - var manager = CreateManager(); - manager.RegisterTwoFactorProvider("PhoneCode", new SmsTokenProvider()); - manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); - var user = new IdentityUser("WrongTokenProviderTest") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateTwoFactorTokenAsync(user, "PhoneCode"); - Assert.NotNull(token); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, "EmailCode", token)); - } - - [Fact] - public async Task VerifyWithWrongSmsTokenFails() - { - var manager = CreateManager(); - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new IdentityUser("VerifyWithWrongSmsTokenFails") { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, "bogus")); - } - - public class TestMessageService : IIdentityMessageService - { - public IdentityMessage Message { get; set; } - - public Task SendAsync(IdentityMessage message, CancellationToken token) - { - Message = message; - return Task.FromResult(0); - } - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTestBase.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTestBase.cs deleted file mode 100644 index 2836b10290..0000000000 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTestBase.cs +++ /dev/null @@ -1,1641 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Identity.Test; -using Microsoft.AspNet.Testing; -using Microsoft.Data.Entity; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNet.Identity.EntityFramework.Test -{ - public abstract class UserStoreTestBase - where ApplicationUser : IdentityUser, new() - where ApplicationRole : IdentityRole, new() - where TKey : IEquatable - { - public abstract string ConnectionString { get; } - - public class ApplicationDbContext : IdentityDbContext - { - public ApplicationDbContext(IServiceProvider services, IOptionsAccessor options) : base(services, options.Options) { } - } - - public ApplicationDbContext CreateContext(bool delete = false) - { - var services = new ServiceCollection(); - services.AddEntityFramework().AddSqlServer(); - services.Add(OptionsServices.GetDefaultServices()); - services.SetupOptions(options => - options.UseSqlServer(ConnectionString)); - var serviceProvider = services.BuildServiceProvider(); - var db = new ApplicationDbContext(serviceProvider, - serviceProvider.GetService>()); - if (delete) - { - db.Database.EnsureDeleted(); - } - db.Database.EnsureCreated(); - return db; - } - - public void EnsureDatabase() - { - CreateContext(); - } - - public abstract UserManager CreateManager(ApplicationDbContext context); - - public UserManager CreateManager() - { - return CreateManager(CreateContext()); - } - - public abstract RoleManager CreateRoleManager(ApplicationDbContext context); - - public RoleManager CreateRoleManager() - { - return CreateRoleManager(CreateContext()); - } - - [TestPriority(-1)] - [Fact] - public void RecreateDatabase() - { - CreateContext(true); - } - - [Fact] - public async Task EnsureStartupUsageWorks() - { - EnsureDatabase(); - IBuilder builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider()); - - builder.UseServices(services => - { - services.AddEntityFramework().AddSqlServer(); - services.AddIdentitySqlServer(); - services.SetupOptions(options => - options.UseSqlServer(ConnectionString)); - }); - - var userStore = builder.ApplicationServices.GetService>(); - var userManager = builder.ApplicationServices.GetService>(); - - Assert.NotNull(userStore); - Assert.NotNull(userManager); - - const string userName = "admin"; - const string password = "1qaz@WSX"; - var user = new ApplicationUser { UserName = userName }; - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); - IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user)); - } - - [Fact] - public async Task EnsureStartupOptionsChangeWorks() - { - EnsureDatabase(); - IBuilder builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider()); - - builder.UseServices(services => - { - services.AddEntityFramework().AddSqlServer(); - services.AddIdentitySqlServer().SetupOptions(options => - { - options.Password.RequiredLength = 1; - options.Password.RequireLowercase = false; - options.Password.RequireNonLetterOrDigit = false; - options.Password.RequireUppercase = false; - options.Password.RequireDigit = false; - }); - services.SetupOptions(options => - options.UseSqlServer(ConnectionString)); - }); - - var userStore = builder.ApplicationServices.GetService>(); - var userManager = builder.ApplicationServices.GetService>(); - - Assert.NotNull(userStore); - Assert.NotNull(userManager); - - const string userName = "admin"; - const string password = "a"; - var user = new ApplicationUser { UserName = userName }; - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); - IdentityResultAssert.IsSuccess(await userManager.DeleteAsync(user)); - } - - [Fact] - public void CanCreateUserUsingEF() - { - using (var db = CreateContext()) - { - var guid = Guid.NewGuid().ToString(); - db.Users.Add(new ApplicationUser { UserName = guid }); - db.SaveChanges(); - Assert.True(db.Users.Any(u => u.UserName == guid)); - Assert.NotNull(db.Users.FirstOrDefault(u => u.UserName == guid)); - } - } - - [Fact] - public async Task CanCreateUsingManager() - { - var manager = CreateManager(); - var guid = Guid.NewGuid().ToString(); - var user = new ApplicationUser { UserName = "New" + guid }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task CanDeleteUser() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - Assert.Null(await manager.FindByIdAsync(user.Id.ToString())); - } - - [Fact] - public async Task CanUpdateUserName() - { - var manager = CreateManager(); - var oldName = Guid.NewGuid().ToString(); - var user = new ApplicationUser { UserName = oldName }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var newName = Guid.NewGuid().ToString(); - user.UserName = newName; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.Equal(user, await manager.FindByNameAsync(newName)); - Assert.Null(await manager.FindByNameAsync(oldName)); - //IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task CanUpdatePasswordUsingHasher() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - Assert.True(await manager.CheckPasswordAsync(user, "password")); - user.PasswordHash = manager.PasswordHasher.HashPassword(user, "New"); - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.False(await manager.CheckPasswordAsync(user, "password")); - Assert.True(await manager.CheckPasswordAsync(user, "New")); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - [Fact] - public async Task CanSetUserName() - { - var manager = CreateManager(); - var oldName = "CanSet" + Guid.NewGuid().ToString(); - var user = new ApplicationUser { UserName = oldName }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var newName = "PostSet" + Guid.NewGuid().ToString(); - IdentityResultAssert.IsSuccess(await manager.SetUserNameAsync(user, newName)); - Assert.NotNull(await manager.FindByNameAsync(newName)); - Assert.Null(await manager.FindByNameAsync(oldName)); - //IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - } - - //[Fact] - //public async Task RemoveClaimOnlyForUser() - //{ - // var manager = CreateManager(); - // var user = new ApplicationUser(); - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - //} - - [Fact] - public async Task UserValidatorCanBlockCreate() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task UserValidatorCanBlockUpdate() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.UserValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(user), AlwaysBadValidator.ErrorMessage); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - public async Task UserValidatorBlocksShortEmailsWhenRequiresUniqueEmail(string email) - { - var manager = CreateManager(); - var user = new ApplicationUser { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email cannot be null or empty."); - } - -#if NET45 - [Theory] - [InlineData("@@afd")] - [InlineData("bogus")] - public async Task UserValidatorBlocksInvalidEmailsWhenRequiresUniqueEmail(string email) - { - var manager = CreateManager(); - var user = new ApplicationUser { Email = email }; - manager.Options.User.RequireUniqueEmail = true; - IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email '" + email + "' is invalid."); - } -#endif - - [Fact] - public async Task PasswordValidatorCanBlockAddPassword() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task PasswordValidatorCanBlockChangePassword() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ChangePasswordAsync(user, "password", "new"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task CanCreateUserNoPassword() - { - var manager = CreateManager(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new ApplicationUser { UserName = "CanCreateUserNoPassword" })); - var user = await manager.FindByNameAsync("CanCreateUserNoPassword"); - Assert.NotNull(user); - Assert.Null(user.PasswordHash); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - } - - [Fact] - public async Task CanCreateUserAddLogin() - { - var manager = CreateManager(); - const string userName = "CanCreateUserAddLogin"; - const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new ApplicationUser { UserName = userName })); - var user = await manager.FindByNameAsync(userName); - Assert.NotNull(user); - var login = new UserLoginInfo(provider, providerKey); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(provider, logins.First().LoginProvider); - Assert.Equal(providerKey, logins.First().ProviderKey); - } - - [Fact] - public async Task CanCreateUserLoginAndAddPassword() - { - var manager = CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.False(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddPasswordAsync(user, "password")); - Assert.True(await manager.HasPasswordAsync(user)); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - // REVIEW: need to remove this - manager = CreateManager(); - var fetch = await manager.FindByLoginAsync(login); - Assert.Equal(user.Id, fetch.Id); - fetch = await manager.FindByUserNamePasswordAsync(user.UserName, "password"); - Assert.Equal(user.Id, fetch.Id); - } - - [Fact] - public async Task AddPasswordFailsIfAlreadyHave() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "Password")); - Assert.True(await manager.HasPasswordAsync(user)); - IdentityResultAssert.IsFailure(await manager.AddPasswordAsync(user, "password"), - "User already has a password set."); - } - - [Fact] - public async Task CanCreateUserAddRemoveLogin() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - var login = new UserLoginInfo("Provider", "key"); - var result = await manager.CreateAsync(user); - Assert.NotNull(user); - IdentityResultAssert.IsSuccess(result); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var fetch = await manager.FindByLoginAsync(login); - Assert.Equal(user.Id, fetch.Id); - var logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); - Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemoveLoginAsync(user, login)); - Assert.Null(await manager.FindByLoginAsync(login)); - logins = await manager.GetLoginsAsync(user); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanRemovePassword() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemovePasswordAsync(user)); - manager = CreateManager(); - var u = await manager.FindByNameAsync(user.UserName); - Assert.NotNull(u); - Assert.Null(u.PasswordHash); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanChangePassword() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, password, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - var fetch = await manager.FindByUserNamePasswordAsync(user.UserName, newPassword); - Assert.NotNull(fetch); - Assert.Equal(user.Id, fetch.Id); - Assert.Equal(user.UserName, fetch.UserName); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanAddRemoveUserClaim() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; - foreach (var c in claims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - Assert.NotNull(user.Claims.Single(cl => cl.ClaimType == c.Type && cl.ClaimValue == c.Value)); - } - var userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(3, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[0])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(2, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[1])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(1, userClaims.Count); - IdentityResultAssert.IsSuccess(await manager.RemoveClaimAsync(user, claims[2])); - userClaims = await manager.GetClaimsAsync(user); - Assert.Equal(0, userClaims.Count); - } - - [Fact] - public async Task ChangePasswordFallsIfPasswordWrong() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - var result = await manager.ChangePasswordAsync(user, "bogus", "newpassword"); - IdentityResultAssert.IsFailure(result, "Incorrect password."); - } - - [Fact] - public async Task AddDupeUserNameFails() - { - var manager = CreateManager(); - var user = new ApplicationUser { UserName = "AddDupeUserNameFails" }; - var user2 = new ApplicationUser { UserName = "AddDupeUserNameFails" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Name AddDupeUserNameFails is already taken."); - } - - [Fact] - public async Task AddDupeEmailAllowedByDefault() - { - var manager = CreateManager(); - var user = new ApplicationUser { Email = "yup@yup.com" }; - var user2 = new ApplicationUser { Email = "yup@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - } - - [Fact] - public async Task AddDupeEmailFallsWhenUniqueEmailRequired() - { - var manager = CreateManager(); - manager.Options.User.RequireUniqueEmail = true; - var user = new ApplicationUser { Email = "dupeEmailTrue@yup.com" }; - var user2 = new ApplicationUser { Email = "dupeEmailTrue@yup.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Email 'dupeEmailTrue@yup.com' is already taken."); - } - - [Fact] - public async Task UpdateSecurityStampActuallyChanges() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - Assert.Null(user.SecurityStamp); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task AddDupeLoginFails() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - var login = new UserLoginInfo("provder", "key"); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - var result = await manager.AddLoginAsync(user, login); - IdentityResultAssert.IsFailure(result, "A user with that external login already exists."); - } - - [Fact] - public async Task UserNameAsEmailTest() - { - var manager = CreateManager(); - manager.Options.User.UseUserNameAsEmail = true; - manager.Options.User.AllowOnlyAlphanumericNames = false; - const string email = "email@test.com"; - var user = new ApplicationUser { UserName = email }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.Equal(user, await manager.FindByEmailAsync(email)); - Assert.Equal(email, await manager.GetEmailAsync(user)); - const string newEmail = "modified@woot.com"; - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, newEmail)); - Assert.Equal(newEmail, user.UserName); - Assert.Equal(newEmail, user.Email); - Assert.False(user.EmailConfirmed); - } - - // Email tests - [Fact] - public async Task CanFindByEmail() - { - var manager = CreateManager(); - const string email = "email@test.com"; - var user = new ApplicationUser { Email = email }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var fetch = await manager.FindByEmailAsync(email); - Assert.Equal(user, fetch); - } - - [Fact] - public async Task CanFindUsersViaUserQuerable() - { - var mgr = CreateManager(); - var users = GenerateUsers("CanFindUsersViaUserQuerable", 3); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(u)); - } - var usersQ = mgr.Users.Where(u => u.UserName.StartsWith("CanFindUsersViaUserQuerable")); - Assert.Null(mgr.Users.FirstOrDefault(u => u.UserName == "bogus")); - } - - [Fact] - public async Task EnsureRoleClaimNavigationProperty() - { - var context = CreateContext(); - var roleManager = CreateRoleManager(context); - var r = new ApplicationRole { Name = "EnsureRoleClaimNavigationProperty" }; - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - var c = new Claim("a", "b"); - IdentityResultAssert.IsSuccess(await roleManager.AddClaimAsync(r, c)); - Assert.NotNull(r.Claims.Single(cl => cl.ClaimValue == c.Value && cl.ClaimType == c.Type)); - } - - [Fact] - public async Task ClaimsIdentityCreatesExpectedClaims() - { - var context = CreateContext(); - var manager = CreateManager(context); - var role = CreateRoleManager(context); - var user = new ApplicationUser { UserName = "ClaimsIdentityCreatesExpectedClaims" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var admin = new ApplicationRole { Name = "Admin" }; - var local = new ApplicationRole { Name = "Local" }; - IdentityResultAssert.IsSuccess(await role.CreateAsync(admin)); - IdentityResultAssert.IsSuccess(await role.CreateAsync(local)); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Admin")); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Local")); - Claim[] userClaims = - { - new Claim("Whatever", "Value"), - new Claim("Whatever2", "Value2") - }; - foreach (var c in userClaims) - { - IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); - } - Claim[] adminClaims = - { - new Claim("Admin", "Value"), - }; - foreach (var c in adminClaims) - { - IdentityResultAssert.IsSuccess(await role.AddClaimAsync(admin, c)); - } - Claim[] localClaims = - { - new Claim("Local", "Value"), - new Claim("Local2", "Value2") - }; - foreach (var c in localClaims) - { - IdentityResultAssert.IsSuccess(await role.AddClaimAsync(local, c)); - } - - var claimsFactory = new ClaimsIdentityFactory(manager, role); - var identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); - var claims = identity.Claims.ToList(); - Assert.NotNull(claims); - Assert.True( - claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName)); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id.ToString())); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin")); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local")); - foreach (var cl in userClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - foreach (var cl in adminClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - foreach (var cl in localClaims) - { - Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); - } - - // Remove a role claim and make sure its not there - IdentityResultAssert.IsSuccess(await role.RemoveClaimAsync(local, localClaims[0])); - identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); - claims = identity.Claims.ToList(); - Assert.False(claims.Any(c => c.Type == localClaims[0].Type && c.Value == localClaims[0].Value)); - Assert.True(claims.Any(c => c.Type == localClaims[1].Type && c.Value == localClaims[1].Value)); - } - - [Fact] - public async Task ConfirmEmailFalseByDefaultTest() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: No token provider implementations yet - private class StaticTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, - ApplicationUser user, CancellationToken token) - { - return Task.FromResult(MakeToken(purpose, user)); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(token == MakeToken(purpose, user)); - } - - public Task NotifyAsync(string token, UserManager manager, ApplicationUser user, CancellationToken cancellationToken) - { - return Task.FromResult(0); - } - - public Task IsValidProviderForUserAsync(UserManager manager, ApplicationUser user, CancellationToken token) - { - return Task.FromResult(true); - } - - private static string MakeToken(string purpose, ApplicationUser user) - { - return string.Join(":", user.Id, purpose, "ImmaToken"); - } - } - - [Fact] - public async Task CanResetPasswordWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ResetPasswordAsync(user, token, newPassword)); - Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task PasswordValidatorCanBlockResetPasswordWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user); - Assert.NotNull(token); - manager.PasswordValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, token, newPassword), - AlwaysBadValidator.ErrorMessage); - var fetch = await manager.FindByUserNamePasswordAsync(user.UserName, password); - Assert.Equal(user, fetch); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordWithStaticTokenProviderFailsWithWrongToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - const string password = "password"; - const string newPassword = "newpassword"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, "bogus", newPassword), "Invalid token."); - var fetch = await manager.FindByUserNamePasswordAsync(user.UserName, password); - Assert.Equal(user, fetch); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanGenerateAndVerifyUserTokenWithStaticTokenProvider() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - var user2 = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); - var token = await manager.GenerateUserTokenAsync("test", user); - Assert.True(await manager.VerifyUserTokenAsync(user, "test", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test2", token)); - Assert.False(await manager.VerifyUserTokenAsync(user, "test", token + "a")); - Assert.False(await manager.VerifyUserTokenAsync(user2, "test", token)); - } - - [Fact] - public async Task CanConfirmEmailWithStaticToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.ConfirmEmailAsync(user, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user)); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - [Fact] - public async Task ConfirmEmailWithStaticTokenFailsWithWrongToken() - { - var manager = CreateManager(); - manager.UserTokenProvider = new StaticTokenProvider(); - var user = new ApplicationUser(); - Assert.False(user.EmailConfirmed); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, "bogus"), "Invalid token."); - Assert.False(await manager.IsEmailConfirmedAsync(user)); - } - - // TODO: Can't reenable til we have a SecurityStamp linked token provider - //[Fact] - //public async Task ConfirmTokenFailsAfterPasswordChange() - //{ - // var manager = CreateManager(); - // var user = new ApplicationUser("test"); - // Assert.False(user.EmailConfirmed); - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); - // var token = await manager.GenerateEmailConfirmationTokenAsync(user); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.ChangePasswordAsync(user, "password", "newpassword")); - // IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, token), "Invalid token."); - // Assert.False(await manager.IsEmailConfirmedAsync(user)); - //} - - // Lockout tests - - [Fact] - public async Task SingleFailureLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 0; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task TwoFailureLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task ResetAccessCountPreventsLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.EnabledByDefault = true; - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.ResetAccessFailedCountAsync(user)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task CanEnableLockoutManuallyAndLockout() - { - var mgr = CreateManager(); - mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); - mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEnabledAsync(user, true)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.False(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(1, await mgr.GetAccessFailedCountAsync(user)); - IdentityResultAssert.IsSuccess(await mgr.AccessFailedAsync(user)); - Assert.True(await mgr.IsLockedOutAsync(user)); - Assert.True(await mgr.GetLockoutEndDateAsync(user) > DateTimeOffset.UtcNow.AddMinutes(55)); - Assert.Equal(0, await mgr.GetAccessFailedCountAsync(user)); - } - - [Fact] - public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset())); - Assert.False(await mgr.IsLockedOutAsync(user)); - Assert.Equal(new DateTimeOffset(), await mgr.GetLockoutEndDateAsync(user)); - } - - [Fact] - public async Task LockoutFailsIfNotEnabled() - { - var mgr = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.False(await mgr.GetLockoutEnabledAsync(user)); - Assert.False(user.LockoutEnabled); - IdentityResultAssert.IsFailure(await mgr.SetLockoutEndDateAsync(user, new DateTimeOffset()), - "Lockout is not enabled for this user."); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new ApplicationUser { LockoutEnd = DateTime.UtcNow.AddSeconds(-1) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.AddSeconds(-1))); - Assert.False(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new ApplicationUser { LockoutEnd = DateTime.UtcNow.AddMinutes(5) }; - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - Assert.True(await mgr.IsLockedOutAsync(user)); - } - - [Fact] - public async Task UserLockedOutWithDateTimeLocalKindNowPlus30() - { - var mgr = CreateManager(); - mgr.Options.Lockout.EnabledByDefault = true; - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); - Assert.True(await mgr.GetLockoutEnabledAsync(user)); - Assert.True(user.LockoutEnabled); - var lockoutEnd = new DateTimeOffset(DateTime.Now.AddMinutes(30).ToLocalTime()); - IdentityResultAssert.IsSuccess(await mgr.SetLockoutEndDateAsync(user, lockoutEnd)); - Assert.True(await mgr.IsLockedOutAsync(user)); - var end = await mgr.GetLockoutEndDateAsync(user); - Assert.Equal(lockoutEnd, end); - } - - // Role Tests - [Fact] - public async Task CanCreateRoleTest() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole { Name = "CanCreateRoleTest" }; - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - } - - private class AlwaysBadValidator : IUserValidator, IRoleValidator, - IPasswordValidator - { - public const string ErrorMessage = "I'm Bad."; - - public Task ValidateAsync(string password, UserManager manager, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(RoleManager manager, ApplicationRole role, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - - public Task ValidateAsync(UserManager manager, ApplicationUser user, CancellationToken token) - { - return Task.FromResult(IdentityResult.Failed(ErrorMessage)); - } - } - - [Fact] - public async Task BadValidatorBlocksCreateRole() - { - var manager = CreateRoleManager(); - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.CreateAsync(new ApplicationRole()), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task BadValidatorBlocksRoleUpdate() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - var error = AlwaysBadValidator.ErrorMessage; - manager.RoleValidator = new AlwaysBadValidator(); - IdentityResultAssert.IsFailure(await manager.UpdateAsync(role), error); - } - - [Fact] - public async Task CanDeleteRole() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole(); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await manager.DeleteAsync(role)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - } - - [Fact] - public async Task CanRoleFindById() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole(); - Assert.Null(await manager.FindByIdAsync(role.Id.ToString())); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByIdAsync(role.Id.ToString())); - } - - [Fact] - public async Task CanRoleFindByName() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole(); - Assert.Null(await manager.FindByNameAsync(role.Name)); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByNameAsync(role.Name)); - } - - [Fact] - public async Task CanUpdateRoleName() - { - var manager = CreateRoleManager(); - var oldName = "OldRoleName" + Guid.NewGuid().ToString(); - var role = new ApplicationRole(); - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - role.Name = "UpdatedRoleName" + Guid.NewGuid().ToString(); - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(role)); - Assert.False(await manager.RoleExistsAsync(oldName)); - var fetch = await manager.FindByNameAsync(role.Name); - Assert.Equal(role, fetch); - } - - [Fact] - public async Task CanQuerableRolesTest() - { - var manager = CreateRoleManager(); - var roles = GenerateRoles("CanQuerableRolesTest", 4); - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(r)); - } - Assert.Equal(roles.Count, manager.Roles.Count(r => r.Name.StartsWith("CanQuerableRolesTest"))); - var r1 = manager.Roles.FirstOrDefault(r => r.Name == "CanQuerableRolesTest1"); - Assert.Equal(roles[1], r1); - } - - [Fact] - public async Task DeleteRoleNonEmptySucceedsTest() - { - // Need fail if not empty? - var userMgr = CreateManager(); - var roleMgr = CreateRoleManager(); - var role = new ApplicationRole(); - Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - var roles = await userMgr.GetRolesAsync(user); - Assert.Equal(1, roles.Count()); - IdentityResultAssert.IsSuccess(await roleMgr.DeleteAsync(role)); - Assert.Null(await roleMgr.FindByNameAsync(role.Name)); - Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // REVIEW: We should throw if deleteing a non empty role? - roles = await userMgr.GetRolesAsync(user); - - Assert.Equal(0, roles.Count()); - } - - // TODO: cascading deletes? navigation properties not working - //[Fact] - //public async Task DeleteUserRemovesFromRoleTest() - //{ - // // Need fail if not empty? - // var userMgr = CreateManager(); - // var roleMgr = CreateRoleManager(); - // var role = new ApplicationRole("deleteNonEmpty"); - // Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - // var user = new ApplicationUser("t"); - // IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - // IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - // Assert.Equal(1, role.Users.Count); - // IdentityResultAssert.IsSuccess(await userMgr.DeleteAsync(user)); - // role = await roleMgr.FindByIdAsync(role.Id); - // Assert.Equal(0, role.Users.Count); - //} - - [Fact] - public async Task CreateRoleFailsIfExists() - { - var manager = CreateRoleManager(); - var role = new ApplicationRole { Name = "CreateRoleFailsIfExists" }; - Assert.False(await manager.RoleExistsAsync(role.Name)); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.True(await manager.RoleExistsAsync(role.Name)); - var role2 = new ApplicationRole { Name = "CreateRoleFailsIfExists" }; - IdentityResultAssert.IsFailure(await manager.CreateAsync(role2)); - } - - [Fact] - public async Task CanAddUsersToRole() - { - var context = CreateContext(); - var manager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var role = new ApplicationRole(); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); - var users = GenerateUsers("CanAddUsersToRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(u, role.Name)); - Assert.True(await manager.IsInRoleAsync(u, role.Name)); - } - } - - private List GenerateUsers(string userNamePrefix, int count) - { - var users = new List(count); - for (var i = 0; i < count; i++) - { - users.Add(new ApplicationUser { UserName = userNamePrefix + i }); - } - return users; - } - - private List GenerateRoles(string namePrefix, int count) - { - var roles = new List(count); - for (var i = 0; i < count; i++) - { - roles.Add(new ApplicationRole { Name = namePrefix + i }); - } - return roles; - } - - [Fact] - public async Task CanGetRolesForUser() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var users = GenerateUsers("CanGetRolesForUser", 4); - var roles = GenerateRoles("CanGetRolesForUserRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - foreach (var u in users) - { - var rs = await userManager.GetRolesAsync(u); - Assert.Equal(roles.Count, rs.Count); - foreach (var r in roles) - { - Assert.True(rs.Any(role => role == r.Name)); - } - } - } - - [Fact] - public async Task RemoveUserFromRoleWithMultipleRoles() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); - var roles = GenerateRoles("RemoveUserFromRoleWithMultipleRoles", 4); - foreach (var r in roles) - { - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, r.Name)); - Assert.True(await userManager.IsInRoleAsync(user, r.Name)); - } - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(user, roles[2].Name)); - Assert.False(await userManager.IsInRoleAsync(user, roles[2].Name)); - } - - [Fact] - public async Task CanRemoveUsersFromRole() - { - var context = CreateContext(); - var userManager = CreateManager(context); - var roleManager = CreateRoleManager(context); - var users = GenerateUsers("CanRemoveUsersFromRole", 4); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); - } - var r = new ApplicationRole(); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(u, r.Name)); - Assert.True(await userManager.IsInRoleAsync(u, r.Name)); - } - foreach (var u in users) - { - IdentityResultAssert.IsSuccess(await userManager.RemoveFromRoleAsync(u, r.Name)); - Assert.False(await userManager.IsInRoleAsync(u, r.Name)); - } - } - - [Fact] - public async Task RemoveUserNotInRoleFails() - { - var context = CreateContext(); - var userMgr = CreateManager(context); - var roleMgr = CreateRoleManager(context); - var role = new ApplicationRole(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - var result = await userMgr.RemoveFromRoleAsync(user, role.Name); - IdentityResultAssert.IsFailure(result, "User is not in role."); - } - - [Fact] - public async Task AddUserToUnknownRoleFails() - { - var manager = CreateManager(); - var u = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); - await Assert.ThrowsAsync( - async () => await manager.AddToRoleAsync(u, "bogus")); - } - - [Fact] - public async Task AddUserToRoleFailsIfAlreadyInRole() - { - var context = CreateContext(); - var userMgr = CreateManager(context); - var roleMgr = CreateRoleManager(context); - var role = new ApplicationRole(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - Assert.True(await userMgr.IsInRoleAsync(user, role.Name)); - IdentityResultAssert.IsFailure(await userMgr.AddToRoleAsync(user, role.Name), "User already in role."); - } - - [Fact] - public async Task CanFindRoleByNameWithManager() - { - var roleMgr = CreateRoleManager(); - var role = new ApplicationRole(); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role.Id, (await roleMgr.FindByNameAsync(role.Name)).Id); - } - - [Fact] - public async Task CanFindRoleWithManager() - { - var roleMgr = CreateRoleManager(); - var role = new ApplicationRole(); - IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role, await roleMgr.FindByIdAsync(role.Id.ToString())); - } - - [Fact] - public async Task SetPhoneNumberTest() - { - var manager = CreateManager(); - var user = new ApplicationUser { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanChangePhoneNumber() - { - var manager = CreateManager(); - var user = new ApplicationUser { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, "111-111-1111"); - IdentityResultAssert.IsSuccess(await manager.ChangePhoneNumberAsync(user, "111-111-1111", token1)); - Assert.True(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePhoneNumberFailsWithWrongToken() - { - var manager = CreateManager(); - var user = new ApplicationUser { PhoneNumber = "123-456-7890" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user); - IdentityResultAssert.IsFailure(await manager.ChangePhoneNumberAsync(user, "111-111-1111", "bogus"), - "Invalid token."); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user)); - Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890"); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CanVerifyPhoneNumber() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string num1 = "111-123-4567"; - const string num2 = "111-111-1111"; - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, num1); - var token2 = await manager.GenerateChangePhoneNumberTokenAsync(user, num2); - Assert.NotEqual(token1, token2); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num1)); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num2)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num1)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num2)); - } - - [Fact] - public async Task CanEmailTwoFactorToken() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - var subject = "Subject"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider { Subject = subject }); - var user = new ApplicationUser { Email = "foo@foo.com" }; - user.EmailConfirmed = true; - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - Assert.True(await manager.IsEmailConfirmedAsync(user)); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(subject, messageService.Message.Subject); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task NotifyWithUnknownProviderFails() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await - ExceptionAssert.ThrowsAsync( - async () => await manager.NotifyTwoFactorTokenAsync(user, "Bogus", "token"), - "No IUserTwoFactorProvider for 'Bogus' is registered."); - } - - [Fact] - public async Task EmailTokenFactorWithFormatTest() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - { - Subject = "Security Code", - BodyFormat = "Your code is: {0}" - }); - var user = new ApplicationUser { Email = "foo@foo.com" }; - const string password = "password"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal("Security Code", messageService.Message.Subject); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task EmailFactorFailsAfterSecurityStampChangeTest() - { - var manager = CreateManager(); - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new ApplicationUser { Email = "foo@foo.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task EnableTwoFactorChangesSecurityStamp() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - IdentityResultAssert.IsSuccess(await manager.SetTwoFactorEnabledAsync(user, true)); - Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user)); - Assert.True(await manager.GetTwoFactorEnabledAsync(user)); - } - - [Fact] - public async Task CanSendSms() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - var user = new ApplicationUser { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendSmsAsync(user, "Hi"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Body); - } - - [Fact] - public async Task CanSendEmail() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var user = new ApplicationUser { Email = "foo@foo.com" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - await manager.SendEmailAsync(user, "Hi", "Body"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Subject); - Assert.Equal("Body", messageService.Message.Body); - } - - [Fact] - public async Task CanSmsTwoFactorToken() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new ApplicationUser { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task PhoneTokenFactorFormatTest() - { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider - { - MessageFormat = "Your code is: {0}" - }); - var user = new ApplicationUser { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; - await - ExceptionAssert.ThrowsAsync( - () => manager.GenerateTwoFactorTokenAsync(user, "bogus"), error); - await ExceptionAssert.ThrowsAsync( - () => manager.VerifyTwoFactorTokenAsync(user, "bogus", "bogus"), error); - } - - [Fact] - public async Task GetValidTwoFactorTestEmptyWithNoProviders() - { - var manager = CreateManager(); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - } - - [Fact] - public async Task CanGetValidTwoFactor() - { - var manager = CreateManager(); - manager.RegisterTwoFactorProvider("phone", new PhoneNumberTokenProvider()); - manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); - var user = new ApplicationUser(); - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - IdentityResultAssert.IsSuccess(await manager.SetPhoneNumberAsync(user, "111-111-1111")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 0); - user.PhoneNumberConfirmed = true; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, "test@test.com")); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - user.EmailConfirmed = true; - IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 2); - IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, null)); - factors = await manager.GetValidTwoFactorProvidersAsync(user); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - } - - [Fact] - public async Task PhoneFactorFailsAfterSecurityStampChangeTest() - { - var manager = CreateManager(); - var factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new ApplicationUser(); - user.PhoneNumber = "4251234567"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - Assert.NotNull(token); - IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - } - - [Fact] - public async Task VerifyTokenFromWrongTokenProviderFails() - { - var manager = CreateManager(); - manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider()); - manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); - var user = new ApplicationUser { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateTwoFactorTokenAsync(user, "PhoneCode"); - Assert.NotNull(token); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, "EmailCode", token)); - } - - [Fact] - public async Task VerifyWithWrongSmsTokenFails() - { - var manager = CreateManager(); - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new ApplicationUser { PhoneNumber = "4251234567" }; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, "bogus")); - } - - public class TestMessageService : IIdentityMessageService - { - public IdentityMessage Message { get; set; } - - public Task SendAsync(IdentityMessage message, CancellationToken token) - { - Message = message; - return Task.FromResult(0); - } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryRoleStore.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryRoleStore.cs index 5acd53943e..0404ef3939 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryRoleStore.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryRoleStore.cs @@ -31,17 +31,17 @@ namespace Microsoft.AspNet.Identity.InMemory return Task.FromResult(0); } - public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(role.Id); } - public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(role.Name); } - public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { role.Name = roleName; return Task.FromResult(0); diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs index a5fa6a4d03..3eb8ea1aa5 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Identity.Test; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; @@ -10,7 +11,12 @@ namespace Microsoft.AspNet.Identity.InMemory.Test { public class InMemoryStoreTest : UserManagerTestBase { - protected override UserManager CreateManager() + protected override object CreateTestContext() + { + return null; + } + + protected override UserManager CreateManager(object context) { var services = new ServiceCollection(); services.Add(OptionsServices.GetDefaultServices()); @@ -26,7 +32,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test return services.BuildServiceProvider().GetService>(); } - protected override RoleManager CreateRoleManager() + protected override RoleManager CreateRoleManager(object context) { var services = new ServiceCollection(); services.AddIdentity().AddInMemory(); diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs index c9923bcf9d..2d62ea0053 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs @@ -23,8 +23,7 @@ namespace Microsoft.AspNet.Identity.InMemory IUserTwoFactorStore where TUser : IdentityUser { - private readonly Dictionary _logins = - new Dictionary(new LoginComparer()); + private readonly Dictionary _logins = new Dictionary(); private readonly Dictionary _users = new Dictionary(); @@ -131,59 +130,69 @@ namespace Microsoft.AspNet.Identity.InMemory return Task.FromResult(0); } - public Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + private string GetLoginKey(string loginProvider, string providerKey) + { + return loginProvider + "|" + providerKey; + } + + public virtual Task AddLoginAsync(TUser user, UserLoginInfo login, + CancellationToken cancellationToken = default(CancellationToken)) { user.Logins.Add(new IdentityUserLogin { - UserId = user.Id, - LoginProvider = login.LoginProvider, - ProviderKey = login.ProviderKey + UserId = user.Id, + ProviderKey = login.ProviderKey, + LoginProvider = login.LoginProvider, + ProviderDisplayName = login.ProviderDisplayName }); - _logins[login] = user; + _logins[GetLoginKey(login.LoginProvider, login.ProviderKey)] = user; return Task.FromResult(0); } - public Task RemoveLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, + CancellationToken cancellationToken = default(CancellationToken)) { var loginEntity = user.Logins.SingleOrDefault( l => - l.ProviderKey == login.ProviderKey && l.LoginProvider == login.LoginProvider && + l.ProviderKey == providerKey && l.LoginProvider == loginProvider && l.UserId == user.Id); if (loginEntity != null) { user.Logins.Remove(loginEntity); } - _logins[login] = null; + _logins[GetLoginKey(loginProvider, providerKey)] = null; return Task.FromResult(0); } public Task> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { - var logins = user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList(); - return Task.FromResult>(logins); + IList result = user.Logins + .Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToList(); + return Task.FromResult(result); } - public Task FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { - if (_logins.ContainsKey(login)) + string key = GetLoginKey(loginProvider, providerKey); + if (_logins.ContainsKey(key)) { - return Task.FromResult(_logins[login]); + return Task.FromResult(_logins[key]); } return Task.FromResult(null); } - public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.Id); } - public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.UserName); } - public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { user.UserName = userName; return Task.FromResult(0); @@ -329,18 +338,5 @@ namespace Microsoft.AspNet.Identity.InMemory user.NormalizedUserName = userName; return Task.FromResult(0); } - - private class LoginComparer : IEqualityComparer - { - public bool Equals(UserLoginInfo x, UserLoginInfo y) - { - return x.LoginProvider == y.LoginProvider && x.ProviderKey == y.ProviderKey; - } - - public int GetHashCode(UserLoginInfo obj) - { - return (obj.ProviderKey + "--" + obj.LoginProvider).GetHashCode(); - } - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.Test/NoopRoleStore.cs b/test/Microsoft.AspNet.Identity.Test/NoopRoleStore.cs index 94e6758321..004d960841 100644 --- a/test/Microsoft.AspNet.Identity.Test/NoopRoleStore.cs +++ b/test/Microsoft.AspNet.Identity.Test/NoopRoleStore.cs @@ -18,12 +18,12 @@ namespace Microsoft.AspNet.Identity.Test return Task.FromResult(0); } - public Task GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(null); } - public Task SetRoleNameAsync(TestRole role, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetRoleNameAsync(TestRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(0); } @@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Identity.Test return Task.FromResult(0); } - public Task GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(null); } diff --git a/test/Microsoft.AspNet.Identity.Test/NoopUserStore.cs b/test/Microsoft.AspNet.Identity.Test/NoopUserStore.cs index 62943a8692..026784e489 100644 --- a/test/Microsoft.AspNet.Identity.Test/NoopUserStore.cs +++ b/test/Microsoft.AspNet.Identity.Test/NoopUserStore.cs @@ -9,17 +9,17 @@ namespace Microsoft.AspNet.Identity.Test { public class NoopUserStore : IUserStore { - public Task GetUserIdAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserIdAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.Id); } - public Task GetUserNameAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserNameAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.UserName); } - public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(0); } diff --git a/test/Microsoft.AspNet.Identity.Test/RoleManagerTest.cs b/test/Microsoft.AspNet.Identity.Test/RoleManagerTest.cs index 44de5a5727..01bad66ab9 100644 --- a/test/Microsoft.AspNet.Identity.Test/RoleManagerTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/RoleManagerTest.cs @@ -80,17 +80,17 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken()) + public Task GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task SetRoleNameAsync(TestRole role, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetRoleNameAsync(TestRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs index 1f389c7cb7..31db0ad6af 100644 --- a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs @@ -502,9 +502,9 @@ namespace Microsoft.AspNet.Identity.Test var manager = MockHelpers.TestUserManager(new NoopUserStore()); Assert.False(manager.SupportsUserLogin); await Assert.ThrowsAsync(async () => await manager.AddLoginAsync(null, null)); - await Assert.ThrowsAsync(async () => await manager.RemoveLoginAsync(null, null)); + await Assert.ThrowsAsync(async () => await manager.RemoveLoginAsync(null, null, null)); await Assert.ThrowsAsync(async () => await manager.GetLoginsAsync(null)); - await Assert.ThrowsAsync(async () => await manager.FindByLoginAsync(null)); + await Assert.ThrowsAsync(async () => await manager.FindByLoginAsync(null, null)); } [Fact] @@ -603,8 +603,10 @@ namespace Microsoft.AspNet.Identity.Test await Assert.ThrowsAsync("userName", async () => await manager.FindByNameAsync(null)); await Assert.ThrowsAsync("userName", async () => await manager.FindByUserNamePasswordAsync(null, null)); await Assert.ThrowsAsync("login", async () => await manager.AddLoginAsync(null, null)); - await - Assert.ThrowsAsync("login", async () => await manager.RemoveLoginAsync(null, null)); + await Assert.ThrowsAsync("loginProvider", + async () => await manager.RemoveLoginAsync(null, null, null)); + await Assert.ThrowsAsync("providerKey", + async () => await manager.RemoveLoginAsync(null, "", null)); await Assert.ThrowsAsync("email", async () => await manager.FindByEmailAsync(null)); Assert.Throws("twoFactorProvider", () => manager.RegisterTwoFactorProvider(null, null)); @@ -625,7 +627,7 @@ namespace Microsoft.AspNet.Identity.Test await Assert.ThrowsAsync("user", async () => await manager.AddClaimAsync(null, new Claim("a", "b"))); await Assert.ThrowsAsync("user", - async () => await manager.AddLoginAsync(null, new UserLoginInfo("", ""))); + async () => await manager.AddLoginAsync(null, new UserLoginInfo("","",""))); await Assert.ThrowsAsync("user", async () => await manager.AddPasswordAsync(null, null)); await Assert.ThrowsAsync("user", @@ -645,7 +647,7 @@ namespace Microsoft.AspNet.Identity.Test await Assert.ThrowsAsync("user", async () => await manager.RemoveClaimAsync(null, new Claim("a", "b"))); await Assert.ThrowsAsync("user", - async () => await manager.RemoveLoginAsync(null, new UserLoginInfo("", ""))); + async () => await manager.RemoveLoginAsync(null, "", "")); await Assert.ThrowsAsync("user", async () => await manager.RemovePasswordAsync(null)); await Assert.ThrowsAsync("user", @@ -736,12 +738,12 @@ namespace Microsoft.AspNet.Identity.Test await Assert.ThrowsAsync(() => manager.IsInRoleAsync(null, null)); await Assert.ThrowsAsync(() => manager.RemoveClaimAsync(null, null)); await Assert.ThrowsAsync(() => manager.RemoveClaimsAsync(null, null)); - await Assert.ThrowsAsync(() => manager.RemoveLoginAsync(null, null)); + await Assert.ThrowsAsync(() => manager.RemoveLoginAsync(null, null, null)); await Assert.ThrowsAsync(() => manager.RemovePasswordAsync(null)); await Assert.ThrowsAsync(() => manager.RemoveFromRoleAsync(null, null)); await Assert.ThrowsAsync(() => manager.RemoveFromRolesAsync(null, null)); await Assert.ThrowsAsync(() => manager.FindByUserNamePasswordAsync(null, null)); - await Assert.ThrowsAsync(() => manager.FindByLoginAsync(null)); + await Assert.ThrowsAsync(() => manager.FindByLoginAsync(null, null)); await Assert.ThrowsAsync(() => manager.FindByIdAsync(null)); await Assert.ThrowsAsync(() => manager.FindByNameAsync(null)); await Assert.ThrowsAsync(() => manager.CreateAsync(null)); @@ -858,7 +860,7 @@ namespace Microsoft.AspNet.Identity.Test return Task.FromResult(0); } - public Task RemoveLoginAsync(TestUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task RemoveLoginAsync(TestUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(0); } @@ -868,7 +870,7 @@ namespace Microsoft.AspNet.Identity.Test return Task.FromResult>(new List()); } - public Task FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(null); } @@ -877,7 +879,7 @@ namespace Microsoft.AspNet.Identity.Test { } - public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(0); } @@ -1117,7 +1119,7 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task RemoveLoginAsync(TestUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task RemoveLoginAsync(TestUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } @@ -1127,7 +1129,7 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) + public Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } @@ -1137,17 +1139,17 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task GetUserIdAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserIdAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task GetUserNameAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task GetUserNameAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = new CancellationToken()) + public Task SetUserNameAsync(TestUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } @@ -1222,22 +1224,22 @@ namespace Microsoft.AspNet.Identity.Test throw new NotImplementedException(); } - public Task AddToRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task AddToRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task RemoveFromRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task RemoveFromRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task> GetRolesAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken()) + public Task> GetRolesAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } - public Task IsInRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = new CancellationToken()) + public Task IsInRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/test/Shared/UserManagerTestBase.cs b/test/Shared/UserManagerTestBase.cs index 2c26304b6a..e0f2fc6530 100644 --- a/test/Shared/UserManagerTestBase.cs +++ b/test/Shared/UserManagerTestBase.cs @@ -2,6 +2,7 @@ // 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; using System.Security.Claims; using System.Threading; @@ -11,20 +12,30 @@ using Xunit; namespace Microsoft.AspNet.Identity.Test { - public abstract class UserManagerTestBase where TUser: IdentityUser, new() where TRole: IdentityRole, new() + + // Common functionality tests that all verifies user manager functionality regardless of store implementation + public abstract class UserManagerTestBase : UserManagerTestBase + where TUser : IdentityUser, new() + where TRole : IdentityRole, new() + { } + + public abstract class UserManagerTestBase + where TUser: IdentityUser, new() + where TRole: IdentityRole, new() + where TKey : IEquatable { - protected abstract UserManager CreateManager(); - protected abstract RoleManager CreateRoleManager(); + protected abstract UserManager CreateManager(object context = null); + protected abstract RoleManager CreateRoleManager(object context = null); + protected abstract object CreateTestContext(); - protected TUser CreateTestUser() { - return new TUser() { UserName = Guid.NewGuid().ToString() }; + protected TUser CreateTestUser(string namePrefix = "") { + return new TUser() { UserName = namePrefix + Guid.NewGuid().ToString() }; } - protected TRole CreateRole(string name) { - return new TRole() { Name = name }; + protected TRole CreateRole(string namePrefix = "") { + return new TRole() { Name = namePrefix + Guid.NewGuid().ToString() }; } - [Fact] public async Task CanDeleteUser() { @@ -32,20 +43,22 @@ namespace Microsoft.AspNet.Identity.Test var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user)); - Assert.Null(await manager.FindByIdAsync(user.Id)); + Assert.Null(await manager.FindByIdAsync(user.Id.ToString())); } [Fact] public async Task CanUpdateUserName() { var manager = CreateManager(); - var user = new TUser() { UserName = "UpdateAsync" }; + var name = Guid.NewGuid().ToString(); + var user = new TUser() { UserName = name }; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.Null(await manager.FindByNameAsync("New")); - user.UserName = "New"; + var newName = Guid.NewGuid().ToString(); + Assert.Null(await manager.FindByNameAsync(newName)); + user.UserName = newName; IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user)); - Assert.NotNull(await manager.FindByNameAsync("New")); - Assert.Null(await manager.FindByNameAsync("UpdateAsync")); + Assert.NotNull(await manager.FindByNameAsync(newName)); + Assert.Null(await manager.FindByNameAsync(name)); } [Fact] @@ -79,7 +92,7 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - Assert.NotNull(await manager.FindByIdAsync(user.Id)); + Assert.NotNull(await manager.FindByIdAsync(user.Id.ToString())); } [Fact] @@ -164,26 +177,27 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanCreateUserAddLogin() { var manager = CreateManager(); - const string userName = "CreateExternalUserTest"; const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - IdentityResultAssert.IsSuccess(await manager.CreateAsync(new TUser() { UserName = userName })); - var user = await manager.FindByNameAsync(userName); - var login = new UserLoginInfo(provider, providerKey); - IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); + const string display = "display"; + var user = CreateTestUser(); + var providerKey = user.Id.ToString(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + user = await manager.FindByNameAsync(user.UserName); + IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, new UserLoginInfo(provider, providerKey, display))); var logins = await manager.GetLoginsAsync(user); Assert.NotNull(logins); Assert.Equal(1, logins.Count()); Assert.Equal(provider, logins.First().LoginProvider); Assert.Equal(providerKey, logins.First().ProviderKey); + Assert.Equal(display, logins.First().ProviderDisplayName); } [Fact] public async Task CanCreateUserLoginAndAddPassword() { var manager = CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new TUser() { UserName = "CreateUserLoginAddPasswordTest" }; + var user = CreateTestUser(); + var login = new UserLoginInfo("Provider", user.Id.ToString(), "display"); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); Assert.False(await manager.HasPasswordAsync(user)); @@ -192,7 +206,7 @@ namespace Microsoft.AspNet.Identity.Test var logins = await manager.GetLoginsAsync(user); Assert.NotNull(logins); Assert.Equal(1, logins.Count()); - Assert.Equal(user, await manager.FindByLoginAsync(login)); + Assert.Equal(user, await manager.FindByLoginAsync(login.LoginProvider, login.ProviderKey)); Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, "password")); } @@ -212,20 +226,21 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); var user = CreateTestUser(); - var login = new UserLoginInfo("Provider", "key"); + var login = new UserLoginInfo("Provider", user.Id.ToString(), "display"); var result = await manager.CreateAsync(user); Assert.NotNull(user); IdentityResultAssert.IsSuccess(result); IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); - Assert.Equal(user, await manager.FindByLoginAsync(login)); + Assert.Equal(user, await manager.FindByLoginAsync(login.LoginProvider, login.ProviderKey)); var logins = await manager.GetLoginsAsync(user); Assert.NotNull(logins); Assert.Equal(1, logins.Count()); Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); + Assert.Equal(login.ProviderDisplayName, logins.Last().ProviderDisplayName); var stamp = user.SecurityStamp; - IdentityResultAssert.IsSuccess(await manager.RemoveLoginAsync(user, login)); - Assert.Null(await manager.FindByLoginAsync(login)); + IdentityResultAssert.IsSuccess(await manager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey)); + Assert.Null(await manager.FindByLoginAsync(login.LoginProvider, login.ProviderKey)); logins = await manager.GetLoginsAsync(user); Assert.NotNull(logins); Assert.Equal(0, logins.Count()); @@ -236,7 +251,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanRemovePassword() { var manager = CreateManager(); - var user = new TUser() { UserName = "RemovePasswordTest" }; + var user = CreateTestUser(); const string password = "password"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); var stamp = user.SecurityStamp; @@ -251,7 +266,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanChangePassword() { var manager = CreateManager(); - var user = new TUser() { UserName = "ChangePasswordTest" }; + var user = CreateTestUser(); const string password = "password"; const string newPassword = "newpassword"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); @@ -267,7 +282,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanAddRemoveUserClaim() { var manager = CreateManager(); - var user = new TUser() { UserName = "ClaimsAddRemove" }; + var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; foreach (Claim c in claims) @@ -291,7 +306,7 @@ namespace Microsoft.AspNet.Identity.Test public async Task ChangePasswordFallsIfPasswordWrong() { var manager = CreateManager(); - var user = new TUser() { UserName = "user" }; + var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); var result = await manager.ChangePasswordAsync(user, "bogus", "newpassword"); IdentityResultAssert.IsFailure(result, "Incorrect password."); @@ -301,18 +316,20 @@ namespace Microsoft.AspNet.Identity.Test public async Task AddDupeUserNameFails() { var manager = CreateManager(); - var user = new TUser() { UserName = "dupe" }; - var user2 = new TUser() { UserName = "dupe" }; + var user = CreateTestUser(); + var user2 = new TUser() { UserName = user.UserName }; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Name dupe is already taken."); + IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Name "+user.UserName+" is already taken."); } [Fact] public async Task AddDupeEmailAllowedByDefault() { var manager = CreateManager(); - var user = new TUser() { UserName = "dupe", Email = "yup@yup.com" }; - var user2 = new TUser() { UserName = "dupeEmail", Email = "yup@yup.com" }; + var user = CreateTestUser(); + var user2 = CreateTestUser(); + user.Email = "yup@yup.com"; + user2.Email = "yup@yup.com"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); } @@ -322,17 +339,20 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.Options.User.RequireUniqueEmail = true; - var user = new TUser() { UserName = "dupe", Email = "yup@yup.com" }; - var user2 = new TUser() { UserName = "dupeEmail", Email = "yup@yup.com" }; + var user = CreateTestUser(); + var user2 = CreateTestUser(); + string email = user.UserName + "@yup.com"; + user.Email = email; + user2.Email = email; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Email 'yup@yup.com' is already taken."); + IdentityResultAssert.IsFailure(await manager.CreateAsync(user2), "Email '"+email+"' is already taken."); } [Fact] public async Task UpdateSecurityStampActuallyChanges() { var manager = CreateManager(); - var user = new TUser() { UserName = "stampMe" }; + var user = CreateTestUser(); Assert.Null(user.SecurityStamp); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var stamp = user.SecurityStamp; @@ -345,8 +365,8 @@ namespace Microsoft.AspNet.Identity.Test public async Task AddDupeLoginFails() { var manager = CreateManager(); - var user = new TUser() { UserName = "DupeLogin" }; - var login = new UserLoginInfo("provder", "key"); + var user = CreateTestUser(); + var login = new UserLoginInfo("Provider", "key", "display"); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await manager.AddLoginAsync(user, login)); var result = await manager.AddLoginAsync(user, login); @@ -358,47 +378,60 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanFindByEmail() { var manager = CreateManager(); - const string userName = "EmailTest"; - const string email = "email@test.com"; - var user = new TUser() { UserName = userName, Email = email }; + var user = CreateTestUser(); + var email = user.UserName + "@test.com"; + user.Email = email; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var fetch = await manager.FindByEmailAsync(email); Assert.Equal(user, fetch); } + [Fact] + public async Task UserNameAsEmailTest() + { + var manager = CreateManager(); + manager.Options.User.UseUserNameAsEmail = true; + manager.Options.User.AllowOnlyAlphanumericNames = false; + var user = CreateTestUser(); + var email = user.UserName + "@test.com"; + user.UserName = email; + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + Assert.Equal(user, await manager.FindByEmailAsync(email)); + Assert.Equal(email, await manager.GetEmailAsync(user)); + const string newEmail = "modified@woot.com"; + IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, newEmail)); + Assert.Equal(newEmail, user.UserName); + Assert.Equal(newEmail, user.Email); + Assert.False(user.EmailConfirmed); + } + [Fact] public async Task CanFindUsersViaUserQuerable() { var mgr = CreateManager(); - var users = new[] - { - new TUser() { UserName = "user1" }, - new TUser() { UserName = "user2" }, - new TUser() { UserName = "user3" } - }; - foreach (TUser u in users) + var users = GenerateUsers("CanFindUsersViaUserQuerable", 3); + foreach (var u in users) { IdentityResultAssert.IsSuccess(await mgr.CreateAsync(u)); } - var usersQ = mgr.Users; - Assert.Equal(3, usersQ.Count()); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user1")); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user2")); - Assert.NotNull(usersQ.FirstOrDefault(u => u.UserName == "user3")); - Assert.Null(usersQ.FirstOrDefault(u => u.UserName == "bogus")); + var usersQ = mgr.Users.Where(u => u.UserName.StartsWith("CanFindUsersViaUserQuerable")); + Assert.Null(mgr.Users.FirstOrDefault(u => u.UserName == "bogus")); } [Fact] public async Task ClaimsIdentityCreatesExpectedClaims() { - var manager = CreateManager(); - var role = CreateRoleManager(); - var user = new TUser() { UserName = "Hao" }; + var context = CreateTestContext(); + var manager = CreateManager(context); + var role = CreateRoleManager(context); + var user = CreateTestUser(); + var admin = CreateRole("Admin"); + var local = CreateRole("local"); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - IdentityResultAssert.IsSuccess(await role.CreateAsync(CreateRole("Admin"))); - IdentityResultAssert.IsSuccess(await role.CreateAsync(CreateRole("Local"))); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Admin")); - IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, "Local")); + IdentityResultAssert.IsSuccess(await role.CreateAsync(admin)); + IdentityResultAssert.IsSuccess(await role.CreateAsync(local)); + IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, admin.Name)); + IdentityResultAssert.IsSuccess(await manager.AddToRoleAsync(user, local.Name)); Claim[] userClaims = { new Claim("Whatever", "Value"), @@ -408,33 +441,65 @@ namespace Microsoft.AspNet.Identity.Test { IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, c)); } + Claim[] adminClaims = + { + new Claim("Admin", "Value"), + }; + foreach (var c in adminClaims) + { + IdentityResultAssert.IsSuccess(await role.AddClaimAsync(admin, c)); + } + Claim[] localClaims = + { + new Claim("Local", "Value"), + new Claim("Local2", "Value2") + }; + foreach (var c in localClaims) + { + IdentityResultAssert.IsSuccess(await role.AddClaimAsync(local, c)); + } var claimsFactory = new ClaimsIdentityFactory(manager, role); var identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); + Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); var claims = identity.Claims.ToList(); Assert.NotNull(claims); - Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); Assert.True( claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserNameClaimType && c.Value == user.UserName)); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id)); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Admin")); - Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == "Local")); + Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.UserIdClaimType && c.Value == user.Id.ToString())); + Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == admin.Name)); + Assert.True(claims.Any(c => c.Type == manager.Options.ClaimsIdentity.RoleClaimType && c.Value == local.Name)); foreach (var cl in userClaims) { Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); } + foreach (var cl in adminClaims) + { + Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); + } + foreach (var cl in localClaims) + { + Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value)); + } + + // Remove a role claim and make sure its not there + IdentityResultAssert.IsSuccess(await role.RemoveClaimAsync(local, localClaims[0])); + identity = await claimsFactory.CreateAsync(user, new ClaimsIdentityOptions()); + Assert.Equal(ClaimsIdentityOptions.DefaultAuthenticationType, identity.AuthenticationType); + claims = identity.Claims.ToList(); + Assert.False(claims.Any(c => c.Type == localClaims[0].Type && c.Value == localClaims[0].Value)); + Assert.True(claims.Any(c => c.Type == localClaims[1].Type && c.Value == localClaims[1].Value)); } [Fact] public async Task ConfirmEmailFalseByDefaultTest() { var manager = CreateManager(); - var user = new TUser() { UserName = "test" }; + var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); Assert.False(await manager.IsEmailConfirmedAsync(user)); } - // TODO: No token provider implementations yet private class StaticTokenProvider : IUserTokenProvider { public Task GenerateAsync(string purpose, UserManager manager, @@ -470,7 +535,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "ResetPasswordTest" }; + var user = CreateTestUser(); const string password = "password"; const string newPassword = "newpassword"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); @@ -489,7 +554,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "ResetPasswordTest" }; + var user = CreateTestUser(); const string password = "password"; const string newPassword = "newpassword"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); @@ -510,7 +575,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "ResetPasswordTest" }; + var user = CreateTestUser(); const string password = "password"; const string newPassword = "newpassword"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); @@ -527,8 +592,8 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "UserTokenTest" }; - var user2 = new TUser() { UserName = "UserTokenTest2" }; + var user = CreateTestUser(); + var user2 = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user2)); var token = await manager.GenerateUserTokenAsync("test", user); @@ -543,7 +608,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "test" }; + var user = CreateTestUser(); Assert.False(user.EmailConfirmed); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var token = await manager.GenerateEmailConfirmationTokenAsync(user); @@ -559,7 +624,7 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); manager.UserTokenProvider = new StaticTokenProvider(); - var user = new TUser() { UserName = "test" }; + var user = CreateTestUser(); Assert.False(user.EmailConfirmed); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); IdentityResultAssert.IsFailure(await manager.ConfirmEmailAsync(user, "bogus"), "Invalid token."); @@ -590,7 +655,7 @@ namespace Microsoft.AspNet.Identity.Test mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); mgr.Options.Lockout.EnabledByDefault = true; mgr.Options.Lockout.MaxFailedAccessAttempts = 0; - var user = new TUser() { UserName = "fastLockout" }; + var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); Assert.True(await mgr.GetLockoutEnabledAsync(user)); Assert.True(user.LockoutEnabled); @@ -608,7 +673,7 @@ namespace Microsoft.AspNet.Identity.Test mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1); mgr.Options.Lockout.EnabledByDefault = true; mgr.Options.Lockout.MaxFailedAccessAttempts = 2; - var user = new TUser() { UserName = "twoFailureLockout" }; + var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); Assert.True(await mgr.GetLockoutEnabledAsync(user)); Assert.True(user.LockoutEnabled); @@ -706,7 +771,8 @@ namespace Microsoft.AspNet.Identity.Test { var mgr = CreateManager(); mgr.Options.Lockout.EnabledByDefault = true; - var user = new TUser() { UserName = "LockoutUtcNowTest", LockoutEnd = DateTimeOffset.UtcNow.AddSeconds(-1) }; + var user = CreateTestUser(); + user.LockoutEnd = DateTimeOffset.UtcNow.AddSeconds(-1); IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); Assert.True(await mgr.GetLockoutEnabledAsync(user)); Assert.True(user.LockoutEnabled); @@ -731,7 +797,8 @@ namespace Microsoft.AspNet.Identity.Test { var mgr = CreateManager(); mgr.Options.Lockout.EnabledByDefault = true; - var user = new TUser() { UserName = "LockoutUtcNowTest", LockoutEnd = DateTimeOffset.UtcNow.AddMinutes(5) }; + var user = CreateTestUser(); + user.LockoutEnd = DateTimeOffset.UtcNow.AddMinutes(5); IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user)); Assert.True(await mgr.GetLockoutEnabledAsync(user)); Assert.True(user.LockoutEnabled); @@ -807,7 +874,7 @@ namespace Microsoft.AspNet.Identity.Test } [Fact] - public async Task CanDeleteRoleTest() + public async Task CanDeleteRole() { var manager = CreateRoleManager(); var role = CreateRole("delete"); @@ -842,13 +909,13 @@ namespace Microsoft.AspNet.Identity.Test } [Fact] - public async Task CanRoleFindByIdTest() + public async Task CanRoleFindById() { var manager = CreateRoleManager(); var role = CreateRole("FindByIdAsync"); - Assert.Null(await manager.FindByIdAsync(role.Id)); + Assert.Null(await manager.FindByIdAsync(role.Id.ToString())); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); - Assert.Equal(role, await manager.FindByIdAsync(role.Id)); + Assert.Equal(role, await manager.FindByIdAsync(role.Id.ToString())); } [Fact] @@ -863,7 +930,7 @@ namespace Microsoft.AspNet.Identity.Test } [Fact] - public async Task CanUpdateRoleNameTest() + public async Task CanUpdateRoleName() { var manager = CreateRoleManager(); var role = CreateRole("update"); @@ -877,45 +944,45 @@ namespace Microsoft.AspNet.Identity.Test } [Fact] - public async Task CanQuerableRolesTest() + public async Task CanQueryableRoles() { var manager = CreateRoleManager(); - TRole[] roles = - { - CreateRole("r1"), CreateRole("r2"), CreateRole("r3"), - CreateRole("r4") - }; + var roles = GenerateRoles("CanQuerableRolesTest", 4); foreach (var r in roles) { IdentityResultAssert.IsSuccess(await manager.CreateAsync(r)); } - Assert.Equal(roles.Length, manager.Roles.Count()); - var r1 = manager.Roles.FirstOrDefault(r => r.Name == "r1"); - Assert.Equal(roles[0], r1); + Assert.Equal(roles.Count, manager.Roles.Count(r => r.Name.StartsWith("CanQuerableRolesTest"))); + var r1 = manager.Roles.FirstOrDefault(r => r.Name.StartsWith("CanQuerableRolesTest1")); + Assert.Equal(roles[1], r1); } - //[Fact] - //public async Task DeleteRoleNonEmptySucceedsTest() - //{ - // // Need fail if not empty? - // var userMgr = CreateManager(); - // var roleMgr = CreateRoleManager(); - // var role = CreateRole("deleteNonEmpty"); - // Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - // var user = new TUser() { UserName = "t"); - // IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); - // IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); - // IdentityResultAssert.IsSuccess(await roleMgr.DeleteAsync(role)); - // Assert.Null(await roleMgr.FindByNameAsync(role.Name)); - // Assert.False(await roleMgr.RoleExistsAsync(role.Name)); - // // REVIEW: We should throw if deleteing a non empty role? - // var roles = await userMgr.GetRolesAsync(user); + [Fact] + public async Task DeleteRoleNonEmptySucceedsTest() + { + // Need fail if not empty? + var context = CreateTestContext(); + var userMgr = CreateManager(context); + var roleMgr = CreateRoleManager(context); + var role = CreateRole(); + Assert.False(await roleMgr.RoleExistsAsync(role.Name)); + IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); + IdentityResultAssert.IsSuccess(await userMgr.AddToRoleAsync(user, role.Name)); + var roles = await userMgr.GetRolesAsync(user); + Assert.Equal(1, roles.Count()); + IdentityResultAssert.IsSuccess(await roleMgr.DeleteAsync(role)); + Assert.Null(await roleMgr.FindByNameAsync(role.Name)); + Assert.False(await roleMgr.RoleExistsAsync(role.Name)); + // REVIEW: We should throw if deleteing a non empty role? + roles = await userMgr.GetRolesAsync(user); - // // In memory this doesn't work since there's no concept of cascading deletes - // //Assert.Equal(0, roles.Count()); - //} + // REVIEW: This depends on cascading deletes + //Assert.Equal(0, roles.Count()); + } + // TODO: cascading deletes? navigation properties not working ////[Fact] ////public async Task DeleteUserRemovesFromRoleTest() ////{ @@ -940,15 +1007,17 @@ namespace Microsoft.AspNet.Identity.Test Assert.False(await manager.RoleExistsAsync(role.Name)); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); Assert.True(await manager.RoleExistsAsync(role.Name)); - var role2 = CreateRole("dupeRole"); + var role2 = CreateRole(); + role2.Name = role.Name; IdentityResultAssert.IsFailure(await manager.CreateAsync(role2)); } [Fact] public async Task CanAddUsersToRole() { - var manager = CreateManager(); - var roleManager = CreateRoleManager(); + var context = CreateTestContext(); + var manager = CreateManager(context); + var roleManager = CreateRoleManager(context); var role = CreateRole("addUserTest"); IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); TUser[] users = @@ -967,18 +1036,11 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task CanGetRolesForUser() { - var userManager = CreateManager(); - var roleManager = CreateRoleManager(); - TUser[] users = - { - new TUser() { UserName = "1"}, new TUser() { UserName = "2"}, new TUser() { UserName = "3"}, - new TUser() { UserName = "4"} - }; - TRole[] roles = - { - CreateRole("r1"), CreateRole("r2"), CreateRole("r3"), - CreateRole("r4") - }; + var context = CreateTestContext(); + var userManager = CreateManager(context); + var roleManager = CreateRoleManager(context); + var users = GenerateUsers("CanGetRolesForUser", 4); + var roles = GenerateRoles("CanGetRolesForUserRole", 4); foreach (var u in users) { IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); @@ -996,7 +1058,7 @@ namespace Microsoft.AspNet.Identity.Test foreach (var u in users) { var rs = await userManager.GetRolesAsync(u); - Assert.Equal(roles.Length, rs.Count); + Assert.Equal(roles.Count, rs.Count); foreach (var r in roles) { Assert.True(rs.Any(role => role == r.Name)); @@ -1007,15 +1069,12 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task RemoveUserFromRoleWithMultipleRoles() { - var userManager = CreateManager(); - var roleManager = CreateRoleManager(); + var context = CreateTestContext(); + var userManager = CreateManager(context); + var roleManager = CreateRoleManager(context); var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); - TRole[] roles = - { - CreateRole("r1"), CreateRole("r2"), CreateRole("r3"), - CreateRole("r4") - }; + var roles = GenerateRoles("RemoveUserFromRoleWithMultipleRoles", 4); foreach (var r in roles) { IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(r)); @@ -1029,13 +1088,10 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task CanRemoveUsersFromRole() { - var userManager = CreateManager(); - var roleManager = CreateRoleManager(); - TUser[] users = - { - new TUser() { UserName = "1"}, new TUser() { UserName = "2"}, new TUser() { UserName = "3"}, - new TUser() { UserName = "4"} - }; + var context = CreateTestContext(); + var userManager = CreateManager(context); + var roleManager = CreateRoleManager(context); + var users = GenerateUsers("CanRemoveUsersFromRole", 4); foreach (var u in users) { IdentityResultAssert.IsSuccess(await userManager.CreateAsync(u)); @@ -1057,8 +1113,9 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task RemoveUserNotInRoleFails() { - var userMgr = CreateManager(); - var roleMgr = CreateRoleManager(); + var context = CreateTestContext(); + var userMgr = CreateManager(context); + var roleMgr = CreateRoleManager(context); var role = CreateRole("addUserDupeTest"); var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); @@ -1070,8 +1127,9 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task AddUserToRoleFailsIfAlreadyInRole() { - var userMgr = CreateManager(); - var roleMgr = CreateRoleManager(); + var context = CreateTestContext(); + var userMgr = CreateManager(context); + var roleMgr = CreateRoleManager(context); var role = CreateRole("addUserDupeTest"); var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await userMgr.CreateAsync(user)); @@ -1096,7 +1154,7 @@ namespace Microsoft.AspNet.Identity.Test var roleMgr = CreateRoleManager(); var role = CreateRole("findRoleTest"); IdentityResultAssert.IsSuccess(await roleMgr.CreateAsync(role)); - Assert.Equal(role.Name, (await roleMgr.FindByIdAsync(role.Id)).Name); + Assert.Equal(role.Name, (await roleMgr.FindByIdAsync(role.Id.ToString())).Name); } [Fact] @@ -1113,7 +1171,6 @@ namespace Microsoft.AspNet.Identity.Test Assert.NotEqual(stamp, user.SecurityStamp); } -#if NET45 [Fact] public async Task CanChangePhoneNumber() { @@ -1162,7 +1219,6 @@ namespace Microsoft.AspNet.Identity.Test Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num1)); Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num2)); } -#endif private class EmailTokenProvider : IUserTokenProvider { @@ -1257,49 +1313,51 @@ namespace Microsoft.AspNet.Identity.Test "No IUserTwoFactorProvider for 'Bogus' is registered."); } + [Fact] + public async Task EmailTokenFactorWithFormatTest() + { + var manager = CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider + { + Subject = "Security Code", + BodyFormat = "Your code is: {0}" + }); + var user = CreateTestUser(); + user.Email = user.UserName + "@foo.com"; + const string password = "password"; + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal("Security Code", messageService.Message.Subject); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); + } - //[Fact] - //public async Task EmailTokenFactorWithFormatTest() - //{ - // var manager = CreateManager(); - // var messageService = new TestMessageService(); - // manager.EmailService = messageService; - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - // { - // Subject = "Security Code", - // BodyFormat = "Your code is: {0}" - // }); - // var user = new TUser() { UserName = "EmailCodeTest") { Email = "foo@foo.com" }; - // const string password = "password"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Security Code", messageService.Message.Subject); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} + [Fact] + public async Task EmailFactorFailsAfterSecurityStampChangeTest() + { + var manager = CreateManager(); + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); + var user = CreateTestUser(); + user.Email = user.UserName + "@foo.com"; + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); + Assert.NotNull(token); + IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); + } - //[Fact] - //public async Task EmailFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = CreateManager(); - // const string factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - // var user = new TUser() { UserName = "EmailCodeTest") { Email = "foo@foo.com" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} [Fact] public async Task EnableTwoFactorChangesSecurityStamp() @@ -1320,7 +1378,8 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); var messageService = new TestMessageService(); manager.SmsService = messageService; - var user = new TUser() { UserName = "SmsTest", PhoneNumber = "4251234567" }; + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); await manager.SendSmsAsync(user, "Hi"); Assert.NotNull(messageService.Message); @@ -1333,7 +1392,8 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); var messageService = new TestMessageService(); manager.EmailService = messageService; - var user = new TUser() { UserName = "EmailTest", Email = "foo@foo.com" }; + var user = CreateTestUser(); + user.Email = user.UserName + "@foo.com"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); await manager.SendEmailAsync(user, "Hi", "Body"); Assert.NotNull(messageService.Message); @@ -1349,7 +1409,8 @@ namespace Microsoft.AspNet.Identity.Test manager.SmsService = messageService; const string factorId = "PhoneCode"; manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new TUser() { UserName = "PhoneCodeTest", PhoneNumber = "4251234567" }; + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var stamp = user.SecurityStamp; Assert.NotNull(stamp); @@ -1362,29 +1423,30 @@ namespace Microsoft.AspNet.Identity.Test Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); } - //[Fact] - //public async Task PhoneTokenFactorFormatTest() - //{ - // var manager = CreateManager(); - // var messageService = new TestMessageService(); - // manager.SmsService = messageService; - // const string factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider - // { - // MessageFormat = "Your code is: {0}" - // }); - // var user = new TUser() { UserName = "PhoneCodeTest", PhoneNumber = "4251234567" }; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} + [Fact] + public async Task PhoneTokenFactorFormatTest() + { + var manager = CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + const string factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider + { + MessageFormat = "Your code is: {0}" + }); + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + IdentityResultAssert.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); + } [Fact] public async Task GenerateTwoFactorWithUnknownFactorProviderWillThrow() @@ -1412,7 +1474,7 @@ namespace Microsoft.AspNet.Identity.Test } [Fact] - public async Task GetValidTwoFactorTest() + public async Task CanGetValidTwoFactor() { var manager = CreateManager(); manager.RegisterTwoFactorProvider("phone", new SmsTokenProvider()); @@ -1438,22 +1500,22 @@ namespace Microsoft.AspNet.Identity.Test Assert.Equal("phone", factors[0]); } - //[Fact] - //public async Task PhoneFactorFailsAfterSecurityStampChangeTest() - //{ - // var manager = CreateManager(); - // var factorId = "PhoneCode"; - // manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - // var user = new TUser() { UserName = "PhoneCodeTest"); - // user.PhoneNumber = "4251234567"; - // IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); - // Assert.NotNull(token); - // IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); - // Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); - //} + [Fact] + public async Task PhoneFactorFailsAfterSecurityStampChangeTest() + { + var manager = CreateManager(); + var factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user, factorId); + Assert.NotNull(token); + IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user)); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); + } [Fact] public async Task VerifyTokenFromWrongTokenProviderFails() @@ -1461,7 +1523,8 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); manager.RegisterTwoFactorProvider("PhoneCode", new SmsTokenProvider()); manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); - var user = new TUser() { UserName = "WrongTokenProviderTest", PhoneNumber = "4251234567" }; + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var token = await manager.GenerateTwoFactorTokenAsync(user, "PhoneCode"); Assert.NotNull(token); @@ -1474,9 +1537,31 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); const string factorId = "PhoneCode"; manager.RegisterTwoFactorProvider(factorId, new SmsTokenProvider()); - var user = new TUser() { UserName = "PhoneCodeTest", PhoneNumber = "4251234567" }; + var user = CreateTestUser(); + user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, "bogus")); } + + public List GenerateUsers(string userNamePrefix, int count) + { + var users = new List(count); + for (var i = 0; i < count; i++) + { + users.Add(CreateTestUser(userNamePrefix + i)); + } + return users; + } + + public List GenerateRoles(string namePrefix, int count) + { + var roles = new List(count); + for (var i = 0; i < count; i++) + { + roles.Add(CreateRole(namePrefix + i)); + } + return roles; + } + } } \ No newline at end of file