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
This commit is contained in:
Hao Kung 2014-08-18 11:42:26 -07:00
parent 6db51e74fb
commit c80ec3f326
32 changed files with 872 additions and 5326 deletions

View File

@ -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);

View File

@ -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"
}
}
}

View File

@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework
await SaveChanges(cancellationToken);
}
public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<string> GetRoleNameAsync(TRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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();

View File

@ -80,7 +80,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework
//.Include(u => u.Logins)
}
public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<string> GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<string> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<IdentityUserRole<TKey>> UserRoles { get { return Context.Set<IdentityUserRole<TKey>>(); } }
private DbSet<IdentityUserLogin<TKey>> UserLogins { get { return Context.Set<IdentityUserLogin<TKey>>(); } }
public Task<IList<Claim>> GetClaimsAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<IList<Claim>> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
ThrowIfDisposed();
if (user == null)
@ -422,7 +422,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework
return Task.FromResult((IList<Claim>)result);
}
public Task AddClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = new CancellationToken())
public Task AddClaimsAsync(TUser user, IEnumerable<Claim> 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<Claim> claims, CancellationToken cancellationToken = new CancellationToken())
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> 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<UserLoginInfo>)result);
IList<UserLoginInfo> result = user.Logins
.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToList();
return Task.FromResult(result);
}
public async virtual Task<TUser> FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task<TUser> 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);
}
/// <summary>

View File

@ -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
/// </summary>
/// <param name="user"></param>
/// <param name="login"></param>
/// <param name="loginProvider"></param>
/// <param name="providerKey"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task RemoveLoginAsync(TUser user, UserLoginInfo login,
Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey,
CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
@ -45,10 +46,11 @@ namespace Microsoft.AspNet.Identity
/// <summary>
/// Returns the user associated with this login
/// </summary>
/// <param name="login"></param>
/// <param name="loginProvider"></param>
/// <param name="providerKey"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TUser> FindByLoginAsync(UserLoginInfo login,
Task<TUser> FindByLoginAsync(string loginProvider, string providerKey,
CancellationToken cancellationToken = default(CancellationToken));
}
}

View File

@ -23,6 +23,11 @@ namespace Microsoft.AspNet.Identity
/// </summary>
public virtual string ProviderKey { get; set; }
/// <summary>
/// Display name for the login
/// </summary>
public virtual string ProviderDisplayName { get; set; }
/// <summary>
/// User Id for the user who owns this login
/// </summary>

View File

@ -82,6 +82,11 @@ namespace Microsoft.AspNet.Identity
AuthenticationManager.SignOut(Options.ClaimsIdentity.AuthenticationType);
}
private async Task<bool> IsLockedOut(TUser user, CancellationToken token)
{
return UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user, token);
}
/// <summary>
/// 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<SignInStatus> ExternalLoginSignInAsync(UserLoginInfo loginInfo, bool isPersistent,
public async Task<SignInStatus> 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;
}

View File

@ -13,10 +13,12 @@ namespace Microsoft.AspNet.Identity
/// </summary>
/// <param name="loginProvider"></param>
/// <param name="providerKey"></param>
public UserLoginInfo(string loginProvider, string providerKey)
/// <param name="displayName"></param>
public UserLoginInfo(string loginProvider, string providerKey, string displayName)
{
LoginProvider = loginProvider;
ProviderKey = providerKey;
ProviderDisplayName = displayName;
}
/// <summary>
@ -28,5 +30,10 @@ namespace Microsoft.AspNet.Identity
/// Key for the linked login at the provider
/// </summary>
public string ProviderKey { get; set; }
/// <summary>
/// Display name for the provider
/// </summary>
public string ProviderDisplayName { get; set; }
}
}

View File

@ -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
}
/// <summary>
/// Returns the user associated with this login
/// Returns the user associated with this login
/// </summary>
/// <param name="loginProvider"></param>
/// <param name="providerKey"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual Task<TUser> FindByLoginAsync(UserLoginInfo login,
public virtual Task<TUser> 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);
}
/// <summary>
@ -812,20 +824,24 @@ namespace Microsoft.AspNet.Identity
/// <param name="login"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IdentityResult> RemoveLoginAsync(TUser user, UserLoginInfo login,
public virtual async Task<IdentityResult> 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);

View File

@ -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<TestUser>();
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<TestUser>();
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<HttpContext>();
var response = new Mock<HttpResponse>();
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
response.Setup(r => r.SignIn(It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent), It.IsAny<ClaimsIdentity>())).Verifiable();
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
contextAccessor.Setup(a => a.Value).Returns(context.Object);
var roleManager = MockHelpers.MockRoleManager<TestRole>();
var identityOptions = new IdentityOptions();
var claimsFactory = new Mock<ClaimsIdentityFactory<TestUser, TestRole>>(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<IOptionsAccessor<IdentityOptions>>();
options.Setup(a => a.Options).Returns(identityOptions);
var helper = new SignInManager<TestUser>(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<TestUser>();
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();

View File

@ -10,15 +10,24 @@ namespace Microsoft.AspNet.Identity
{
public static class EntityInMemoryTestServiceCollectionExtensions
{
public static IdentityBuilder<TUser, TRole> AddIdentityInMemory<TUser, TRole, TDbContext>(this ServiceCollection services)
where TUser : InMemoryUser
public static IdentityBuilder<IdentityUser, IdentityRole> AddIdentityInMemory(this ServiceCollection services, InMemoryContext context)
{
return services.AddIdentityInMemory<IdentityUser, IdentityRole, InMemoryContext>(context);
}
public static IdentityBuilder<TUser, TRole> AddIdentityInMemory<TUser, TRole, TDbContext>(this ServiceCollection services, TDbContext context)
where TUser : IdentityUser
where TRole : IdentityRole
where TDbContext : DbContext
{
var builder = services.AddIdentity<TUser, TRole>();
services.AddScoped<TDbContext>();
services.AddScoped<IUserStore<TUser>, InMemoryUserStore<TUser, TDbContext>>();
services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TDbContext>>();
services.AddInstance<IUserStore<TUser>>(new InMemoryUserStore<TUser, TDbContext>(context));
var store = new RoleStore<TRole, TDbContext>(context);
services.AddInstance<IRoleStore<TRole>>(store);
//services.AddInstance(context);
//services.AddScoped<TDbContext>();
//services.AddScoped<IUserStore<TUser>, InMemoryUserStore<TUser, TDbContext>>();
//services.AddScoped<IRoleStore<TRole>, RoleStore<TRole, TDbContext>>();
return builder;
}
}

View File

@ -8,7 +8,7 @@ using Microsoft.Data.Entity.Metadata;
namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
{
public class InMemoryContext :
InMemoryContext<InMemoryUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
InMemoryContext<IdentityUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public InMemoryContext() { }
public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
@ -16,14 +16,14 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
public class InMemoryContext<TUser> :
InMemoryContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
where TUser : InMemoryUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
where TUser : IdentityUser
{
public InMemoryContext() { }
public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
}
public class InMemoryContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
where TUser : InMemoryUser<TKey, TUserLogin, TUserRole, TUserClaim>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TUserRole : IdentityUserRole<TKey>
@ -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)

View File

@ -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<IdentityUser, IdentityRole>
{
protected override object CreateTestContext()
{
return new InMemoryContext();
}
protected override UserManager<IdentityUser> 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<IdentityOptions>(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<UserManager<IdentityUser>>();
}
protected override RoleManager<IdentityRole> 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<RoleManager<IdentityRole>>();
}
}
}

View File

@ -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<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public InMemoryUser()
{
Id = Guid.NewGuid().ToString();
}
public InMemoryUser(string userName)
: this()
{
UserName = userName;
}
}
public class InMemoryUser<TKey, TLogin, TRole, TClaim>
where TLogin : IdentityUserLogin<TKey>
where TRole : IdentityUserRole<TKey>
where TClaim : IdentityUserClaim<TKey>
where TKey : IEquatable<TKey>
{
public InMemoryUser()
{
Claims = new List<TClaim>();
Roles = new List<TRole>();
Logins = new List<TLogin>();
}
public virtual TKey Id { get; set; }
public virtual string UserName { get; set; }
public virtual string NormalizedUserName { get; set; }
/// <summary>
/// Email
/// </summary>
public virtual string Email { get; set; }
/// <summary>
/// True if the email is confirmed, default is false
/// </summary>
public virtual bool EmailConfirmed { get; set; }
/// <summary>
/// The salted/hashed form of the user password
/// </summary>
public virtual string PasswordHash { get; set; }
/// <summary>
/// A random value that should change whenever a users credentials have changed (password changed, login removed)
/// </summary>
public virtual string SecurityStamp { get; set; }
/// <summary>
/// PhoneNumber for the user
/// </summary>
public virtual string PhoneNumber { get; set; }
/// <summary>
/// True if the phone number is confirmed, default is false
/// </summary>
public virtual bool PhoneNumberConfirmed { get; set; }
/// <summary>
/// Is two factor enabled for the user
/// </summary>
public virtual bool TwoFactorEnabled { get; set; }
/// <summary>
/// DateTime in UTC when lockout ends, any time in the past is considered not locked out.
/// </summary>
public virtual DateTime? LockoutEnd { get; set; }
/// <summary>
/// Is lockout enabled for this user
/// </summary>
public virtual bool LockoutEnabled { get; set; }
/// <summary>
/// Used to record failures for the purposes of lockout
/// </summary>
public virtual int AccessFailedCount { get; set; }
/// <summary>
/// Navigation property for user roles
/// </summary>
public virtual ICollection<TRole> Roles { get; private set; }
/// <summary>
/// Navigation property for user claims
/// </summary>
public virtual ICollection<TClaim> Claims { get; private set; }
/// <summary>
/// Navigation property for user logins
/// </summary>
public virtual ICollection<TLogin> Logins { get; private set; }
}
}

View File

@ -13,19 +13,19 @@ using Microsoft.Data.Entity;
namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
{
public class InMemoryUserStore : InMemoryUserStore<InMemoryUser, InMemoryContext>
public class InMemoryUserStore : InMemoryUserStore<IdentityUser, InMemoryContext>
{
public InMemoryUserStore(InMemoryContext context) : base(context) { }
}
public class InMemoryUserStore<TUser> : InMemoryUserStore<TUser, InMemoryContext>
where TUser : InMemoryUser
where TUser : IdentityUser
{
public InMemoryUserStore(InMemoryContext context) : base(context) { }
}
public class InMemoryUserStore<TUser, TContext> : InMemoryUserStore<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim, TContext>
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<TUser>,
IUserLockoutStore<TUser>
where TKey : IEquatable<TKey>
where TUser : InMemoryUser<TKey, TUserLogin, TUserRole, TUserClaim>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>, new()
where TUserRole : IdentityUserRole<TKey>, new()
@ -83,7 +83,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
//.Include(u => u.Logins)
}
public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<string> GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<string> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<TUser>(); }
}
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<TUserLogin>().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<TUserLogin>().Remove(entry);
Context.Set<IdentityUserLogin<TKey>>().Remove(entry);
}
return Task.FromResult(0);
}
@ -266,24 +259,18 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
{
throw new ArgumentNullException("user");
}
IList<UserLoginInfo> result =
user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList();
IList<UserLoginInfo> result = user.Logins.Select(
l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName))
.ToList();
return Task.FromResult(result);
}
public async virtual Task<TUser> FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task<TUser> 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<TUserLogin>().FirstOrDefault(l => l.LoginProvider == provider && l.ProviderKey == key);
var userLogin = await Context.Set<TUserLogin>()
.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);
}
/// <summary>
@ -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);
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
var services = new ServiceCollection();
services.AddEntityFramework().AddInMemoryStore();
var store = new RoleStore<IdentityRole>(new InMemoryContext());
services.AddIdentity<InMemoryUser, IdentityRole>().AddRoleStore(() => store);
services.AddIdentity().AddRoleStore(() => store);
var provider = services.BuildServiceProvider();
var manager = provider.GetService<RoleManager<IdentityRole>>();
Assert.NotNull(manager);

View File

@ -21,12 +21,12 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
return db;
}
public static UserManager<InMemoryUser> CreateManager(InMemoryContext context)
public static UserManager<IdentityUser> CreateManager(InMemoryContext context)
{
return MockHelpers.CreateManager<InMemoryUser>(() => new InMemoryUserStore<InMemoryUser>(context));
return MockHelpers.CreateManager<IdentityUser>(() => new InMemoryUserStore<IdentityUser>(context));
}
public static UserManager<InMemoryUser> CreateManager()
public static UserManager<IdentityUser> CreateManager()
{
return CreateManager(CreateContext());
}
@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
public static RoleManager<IdentityRole> CreateRoleManager(InMemoryContext context)
{
var services = new ServiceCollection();
services.AddIdentity<InMemoryUser, IdentityRole>().AddRoleStore(() => new RoleStore<IdentityRole>(context));
services.AddIdentity().AddRoleStore(() => new RoleStore<IdentityRole>(context));
return services.BuildServiceProvider().GetService<RoleManager<IdentityRole>>();
}

View File

@ -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<TUser, TRole, TKey> : UserManagerTestBase<TUser, TRole, TKey>
where TUser : IdentityUser<TKey>, new()
where TRole : IdentityRole<TKey>, new()
where TKey : IEquatable<TKey>
{
public abstract string ConnectionString { get; }
public class ApplicationDbContext : IdentityDbContext<TUser, TRole, TKey>
{
public ApplicationDbContext(IServiceProvider services, IOptionsAccessor<DbContextOptions> 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<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString));
var serviceProvider = services.BuildServiceProvider();
var db = new ApplicationDbContext(serviceProvider,
serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>());
if (delete)
{
db.Database.EnsureDeleted();
}
db.Database.EnsureCreated();
return db;
}
protected override object CreateTestContext()
{
return CreateContext();
}
protected override UserManager<TUser> CreateManager(object context = null)
{
if (context == null)
{
context = CreateTestContext();
}
return MockHelpers.CreateManager(() => new UserStore<TUser, TRole, ApplicationDbContext, TKey>((ApplicationDbContext)context));
}
protected override RoleManager<TRole> CreateRoleManager(object context = null)
{
if (context == null)
{
context = CreateTestContext();
}
var services = new ServiceCollection();
services.AddIdentity<TUser, TRole>().AddRoleStore(() => new RoleStore<TRole, ApplicationDbContext, TKey>((ApplicationDbContext)context));
return services.BuildServiceProvider().GetService<RoleManager<TRole>>();
}
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<ApplicationDbContext, TUser, TRole, TKey>();
services.SetupOptions<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString));
});
var userStore = builder.ApplicationServices.GetService<IUserStore<TUser>>();
var userManager = builder.ApplicationServices.GetService<UserManager<TUser>>();
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<ApplicationDbContext, TUser, TRole, TKey>().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<DbContextOptions>(options =>
options.UseSqlServer(ConnectionString));
});
var userStore = builder.ApplicationServices.GetService<IUserStore<TUser>>();
var userManager = builder.ApplicationServices.GetService<UserManager<TUser>>();
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));
}
}
}

View File

@ -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<GuidUser, GuidRole, Guid>
public class UserStoreGuidTest : SqlStoreTestBase<GuidUser, GuidRole, Guid>
{
public override string ConnectionString
{
@ -58,15 +58,23 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test
}
}
public override UserManager<GuidUser> CreateManager(ApplicationDbContext context)
protected override UserManager<GuidUser> CreateManager(object context)
{
return MockHelpers.CreateManager(() => new ApplicationUserStore(context));
if (context == null)
{
context = CreateTestContext();
}
return MockHelpers.CreateManager(() => new ApplicationUserStore((ApplicationDbContext)context));
}
public override RoleManager<GuidRole> CreateRoleManager(ApplicationDbContext context)
protected override RoleManager<GuidRole> CreateRoleManager(object context)
{
if (context == null)
{
context = CreateTestContext();
}
var services = new ServiceCollection();
services.AddIdentity<GuidUser, GuidRole>().AddRoleStore(() => new ApplicationRoleStore(context));
services.AddIdentity<GuidUser, GuidRole>().AddRoleStore(() => new ApplicationRoleStore((ApplicationDbContext)context));
return services.BuildServiceProvider().GetService<RoleManager<GuidRole>>();
}
}

View File

@ -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<IntUser, IntRole, int>
public class UserStoreIntTest : SqlStoreTestBase<IntUser, IntRole, int>
{
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<IntUser> CreateManager(ApplicationDbContext context)
{
return MockHelpers.CreateManager(() => new UserStore<IntUser, IntRole, ApplicationDbContext, int>(context));
}
public override RoleManager<IntRole> CreateRoleManager(ApplicationDbContext context)
{
var services = new ServiceCollection();
services.AddIdentity<IntUser, IntRole>().AddRoleStore(() => new RoleStore<IntRole, ApplicationDbContext, int>(context));
return services.BuildServiceProvider().GetService<RoleManager<IntRole>>();
}
}
}

View File

@ -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<StringUser, StringRole, string>
public class UserStoreStringKeyTest : SqlStoreTestBase<StringUser, StringRole, string>
{
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<StringUser> CreateManager(ApplicationDbContext context)
{
return MockHelpers.CreateManager(() => new UserStore<StringUser, StringRole, ApplicationDbContext, string>(context));
}
public override RoleManager<StringRole> CreateRoleManager(ApplicationDbContext context)
{
var services = new ServiceCollection();
services.AddIdentity<StringUser, StringRole>().AddRoleStore(() => new RoleStore<StringRole, ApplicationDbContext, string>(context));
return services.BuildServiceProvider().GetService<RoleManager<StringRole>>();
}
}
}

View File

@ -31,17 +31,17 @@ namespace Microsoft.AspNet.Identity.InMemory
return Task.FromResult(0);
}
public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.Id);
}
public Task<string> GetRoleNameAsync(TRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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);

View File

@ -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<IdentityUser, IdentityRole>
{
protected override UserManager<IdentityUser> CreateManager()
protected override object CreateTestContext()
{
return null;
}
protected override UserManager<IdentityUser> 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<UserManager<IdentityUser>>();
}
protected override RoleManager<IdentityRole> CreateRoleManager()
protected override RoleManager<IdentityRole> CreateRoleManager(object context)
{
var services = new ServiceCollection();
services.AddIdentity().AddInMemory();

View File

@ -23,8 +23,7 @@ namespace Microsoft.AspNet.Identity.InMemory
IUserTwoFactorStore<TUser>
where TUser : IdentityUser
{
private readonly Dictionary<UserLoginInfo, TUser> _logins =
new Dictionary<UserLoginInfo, TUser>(new LoginComparer());
private readonly Dictionary<string, TUser> _logins = new Dictionary<string, TUser>();
private readonly Dictionary<string, TUser> _users = new Dictionary<string, TUser>();
@ -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<string>
{
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<IList<UserLoginInfo>> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
var logins = user.Logins.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey)).ToList();
return Task.FromResult<IList<UserLoginInfo>>(logins);
IList<UserLoginInfo> result = user.Logins
.Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToList();
return Task.FromResult(result);
}
public Task<TUser> FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))
public Task<TUser> 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<TUser>(null);
}
public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Id);
}
public Task<string> GetUserNameAsync(TUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<UserLoginInfo>
{
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();
}
}
}
}

View File

@ -18,12 +18,12 @@ namespace Microsoft.AspNet.Identity.Test
return Task.FromResult(0);
}
public Task<string> GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<string>(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<string> GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<string>(null);
}

View File

@ -9,17 +9,17 @@ namespace Microsoft.AspNet.Identity.Test
{
public class NoopUserStore : IUserStore<TestUser>
{
public Task<string> GetUserIdAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetUserIdAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Id);
}
public Task<string> GetUserNameAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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);
}

View File

@ -80,17 +80,17 @@ namespace Microsoft.AspNet.Identity.Test
throw new NotImplementedException();
}
public Task<string> GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetRoleIdAsync(TestRole role, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task<string> GetRoleNameAsync(TestRole role, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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();
}

View File

@ -502,9 +502,9 @@ namespace Microsoft.AspNet.Identity.Test
var manager = MockHelpers.TestUserManager(new NoopUserStore());
Assert.False(manager.SupportsUserLogin);
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddLoginAsync(null, null));
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveLoginAsync(null, null));
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveLoginAsync(null, null, null));
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetLoginsAsync(null));
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.FindByLoginAsync(null));
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.FindByLoginAsync(null, null));
}
[Fact]
@ -603,8 +603,10 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByNameAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByUserNamePasswordAsync(null, null));
await Assert.ThrowsAsync<ArgumentNullException>("login", async () => await manager.AddLoginAsync(null, null));
await
Assert.ThrowsAsync<ArgumentNullException>("login", async () => await manager.RemoveLoginAsync(null, null));
await Assert.ThrowsAsync<ArgumentNullException>("loginProvider",
async () => await manager.RemoveLoginAsync(null, null, null));
await Assert.ThrowsAsync<ArgumentNullException>("providerKey",
async () => await manager.RemoveLoginAsync(null, "", null));
await Assert.ThrowsAsync<ArgumentNullException>("email", async () => await manager.FindByEmailAsync(null));
Assert.Throws<ArgumentNullException>("twoFactorProvider",
() => manager.RegisterTwoFactorProvider(null, null));
@ -625,7 +627,7 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.AddClaimAsync(null, new Claim("a", "b")));
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.AddLoginAsync(null, new UserLoginInfo("", "")));
async () => await manager.AddLoginAsync(null, new UserLoginInfo("","","")));
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.AddPasswordAsync(null, null));
await Assert.ThrowsAsync<ArgumentNullException>("user",
@ -645,7 +647,7 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.RemoveClaimAsync(null, new Claim("a", "b")));
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.RemoveLoginAsync(null, new UserLoginInfo("", "")));
async () => await manager.RemoveLoginAsync(null, "", ""));
await Assert.ThrowsAsync<ArgumentNullException>("user",
async () => await manager.RemovePasswordAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("user",
@ -736,12 +738,12 @@ namespace Microsoft.AspNet.Identity.Test
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.IsInRoleAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveClaimAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveClaimsAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveLoginAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveLoginAsync(null, null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemovePasswordAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveFromRoleAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveFromRolesAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByUserNamePasswordAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByLoginAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByLoginAsync(null, null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByIdAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByNameAsync(null));
await Assert.ThrowsAsync<ObjectDisposedException>(() => 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<IList<UserLoginInfo>>(new List<UserLoginInfo>());
}
public Task<TestUser> FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))
public Task<TestUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<TestUser>(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<TestUser> FindByLoginAsync(UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))
public Task<TestUser> 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<string> GetUserIdAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> GetUserIdAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task<string> GetUserNameAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<string> 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<IList<string>> GetRolesAsync(TestUser user, CancellationToken cancellationToken = new CancellationToken())
public Task<IList<string>> GetRolesAsync(TestUser user, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
public Task<bool> IsInRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = new CancellationToken())
public Task<bool> IsInRoleAsync(TestUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}

View File

@ -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<TUser, TRole> 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<TUser, TRole> : UserManagerTestBase<TUser, TRole, string>
where TUser : IdentityUser, new()
where TRole : IdentityRole, new()
{ }
public abstract class UserManagerTestBase<TUser, TRole, TKey>
where TUser: IdentityUser<TKey>, new()
where TRole: IdentityRole<TKey>, new()
where TKey : IEquatable<TKey>
{
protected abstract UserManager<TUser> CreateManager();
protected abstract RoleManager<TRole> CreateRoleManager();
protected abstract UserManager<TUser> CreateManager(object context = null);
protected abstract RoleManager<TRole> 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<TUser, TRole>(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<TUser>
{
public Task<string> GenerateAsync(string purpose, UserManager<TUser> 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<TUser>
{
@ -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<TUser>
{
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<TUser>
// {
// 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<TUser>());
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<TUser>());
// 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<TUser>
// {
// 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<TUser>
{
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<TUser>());
// 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<TUser>());
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<TUser> GenerateUsers(string userNamePrefix, int count)
{
var users = new List<TUser>(count);
for (var i = 0; i < count; i++)
{
users.Add(CreateTestUser(userNamePrefix + i));
}
return users;
}
public List<TRole> GenerateRoles(string namePrefix, int count)
{
var roles = new List<TRole>(count);
for (var i = 0; i < count; i++)
{
roles.Add(CreateRole(namePrefix + i));
}
return roles;
}
}
}