From 625b270924c6ea343701ee098bbe718bb7299f69 Mon Sep 17 00:00:00 2001 From: Suhas Joshi Date: Mon, 1 Dec 2014 10:29:15 -0800 Subject: [PATCH] Added new apis to query users and fixed EF.Inmemory --- .../IdentitySample.Mvc.kproj | 5 +- .../RoleStore.cs | 10 +- .../UserStore.cs | 80 +- .../IUserClaimStore.cs | 8 + .../IUserRoleStore.cs | 8 + src/Microsoft.AspNet.Identity/UserManager.cs | 31 + ...InMemoryTestServiceCollectionExtensions.cs | 31 - .../InMemoryContext.cs | 67 +- .../InMemoryEFUserStoreTest.cs | 2 +- .../InMemoryUserStore.cs | 929 ------------------ .../TestIdentityFactory.cs | 2 +- .../InMemoryUserStore.cs | 27 +- .../UserManagerTest.cs | 20 + test/Shared/UserManagerTestBase.cs | 53 + 14 files changed, 226 insertions(+), 1047 deletions(-) delete mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs delete mode 100644 test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs diff --git a/samples/IdentitySample.Mvc/IdentitySample.Mvc.kproj b/samples/IdentitySample.Mvc/IdentitySample.Mvc.kproj index 0c84b42be0..3cdababc47 100644 --- a/samples/IdentitySample.Mvc/IdentitySample.Mvc.kproj +++ b/samples/IdentitySample.Mvc/IdentitySample.Mvc.kproj @@ -1,4 +1,4 @@ - + 14.0 @@ -12,6 +12,7 @@ 2.0 + 5131 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs index 7b14e0aa21..b3d7988dc5 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs @@ -25,8 +25,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework public RoleStore(TContext context) : base(context) { } } - public class RoleStore : - IQueryableRoleStore, + public class RoleStore : + IQueryableRoleStore, IRoleClaimStore where TRole : IdentityRole where TKey : IEquatable @@ -198,7 +198,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("role"); } - return await RoleClaims.Where(rc => rc.RoleId.Equals(role.Id)).Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToListAsync(); + return await RoleClaims.Where(rc => rc.RoleId.Equals(role.Id)).Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToListAsync(cancellationToken); } public Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) @@ -213,7 +213,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("claim"); } - return RoleClaims.AddAsync(new IdentityRoleClaim { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value }); + return RoleClaims.AddAsync(new IdentityRoleClaim { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value }, cancellationToken); } public async Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) @@ -227,7 +227,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentNullException("claim"); } - var claims = await RoleClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(); + var claims = await RoleClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(cancellationToken); foreach (var c in claims) { RoleClaims.Remove(c); diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs index 591013e8b6..f1cf95a2c4 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs @@ -282,7 +282,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); } - var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper()); + var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken); if (roleEntity == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, roleName)); @@ -310,10 +310,10 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); } - var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper()); + var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken); if (roleEntity != null) { - var userRole = await UserRoles.FirstOrDefaultAsync(r => roleEntity.Id.Equals(r.RoleId) && r.UserId.Equals(user.Id)); + var userRole = await UserRoles.FirstOrDefaultAsync(r => roleEntity.Id.Equals(r.RoleId) && r.UserId.Equals(user.Id), cancellationToken); if (userRole != null) { UserRoles.Remove(userRole); @@ -362,7 +362,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, "roleName"); } - var role = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper()); + var role = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken); if (role != null) { var userId = user.Id; @@ -401,7 +401,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("user"); } - return await UserClaims.Where(uc => uc.UserId.Equals(user.Id)).Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToListAsync(); + return await UserClaims.Where(uc => uc.UserId.Equals(user.Id)).Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToListAsync(cancellationToken); } public async Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) @@ -417,7 +417,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework } foreach (var claim in claims) { - await UserClaims.AddAsync(new IdentityUserClaim { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value }); + await UserClaims.AddAsync(new IdentityUserClaim { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value }, cancellationToken); } } @@ -437,8 +437,8 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("newClaim"); } - var matchedClaims = await UserClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(); - foreach(var matchedClaim in matchedClaims) + var matchedClaims = await UserClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(cancellationToken); + foreach (var matchedClaim in matchedClaims) { matchedClaim.ClaimValue = newClaim.Value; matchedClaim.ClaimType = newClaim.Type; @@ -456,8 +456,9 @@ namespace Microsoft.AspNet.Identity.EntityFramework { throw new ArgumentNullException("claims"); } - foreach (var claim in claims) { - var matchedClaims = await UserClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(); + foreach (var claim in claims) + { + var matchedClaims = await UserClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToListAsync(cancellationToken); foreach (var c in matchedClaims) { UserClaims.Remove(c); @@ -499,7 +500,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework throw new ArgumentNullException("user"); } var userId = user.Id; - var entry = await UserLogins.SingleOrDefaultAsync(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.ProviderKey == providerKey); + var entry = await UserLogins.SingleOrDefaultAsync(l => l.UserId.Equals(userId) && l.LoginProvider == loginProvider && l.ProviderKey == providerKey, cancellationToken); if (entry != null) { UserLogins.Remove(entry); @@ -516,7 +517,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework } var userId = user.Id; return await UserLogins.Where(l => l.UserId.Equals(userId)) - .Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToListAsync(); + .Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToListAsync(cancellationToken); } public async virtual Task FindByLoginAsync(string loginProvider, string providerKey, @@ -525,7 +526,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); var userLogin = await - UserLogins.FirstOrDefaultAsync(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); + UserLogins.FirstOrDefaultAsync(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey, cancellationToken); if (userLogin != null) { return await Users.FirstOrDefaultAsync(u => u.Id.Equals(userLogin.UserId), cancellationToken); @@ -890,5 +891,58 @@ namespace Microsoft.AspNet.Identity.EntityFramework } return Task.FromResult(user.TwoFactorEnabled); } + + /// + /// Get all users with given claim + /// + /// + /// + /// + public async Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + if (claim == null) + { + throw new ArgumentNullException("claim"); + } + + var query = from userclaims in UserClaims + join user in Users on userclaims.UserId equals user.Id + where userclaims.ClaimValue == claim.Value + && userclaims.ClaimType == claim.Type + select user; + + return (IList)await query.ToListAsync(cancellationToken); + } + + /// + /// Get all users in given role + /// + /// + /// + /// + public async Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) + { + cancellationToken.ThrowIfCancellationRequested(); + ThrowIfDisposed(); + if (String.IsNullOrEmpty(roleName)) + { + throw new ArgumentNullException("role"); + } + + var role = await Roles.Where(x => x.Name.Equals(roleName)).FirstOrDefaultAsync(cancellationToken); + + if (role != null) + { + var query = from userrole in UserRoles + join user in Users on userrole.UserId equals user.Id + where userrole.RoleId.Equals(role.Id) + select user; + + return (IList) await query.ToListAsync(cancellationToken); + } + return new List(); + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IUserClaimStore.cs b/src/Microsoft.AspNet.Identity/IUserClaimStore.cs index eb7d0d559f..825c289b0e 100644 --- a/src/Microsoft.AspNet.Identity/IUserClaimStore.cs +++ b/src/Microsoft.AspNet.Identity/IUserClaimStore.cs @@ -51,5 +51,13 @@ namespace Microsoft.AspNet.Identity /// Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Get users having a specific claim + /// + /// Claim to look up + /// + /// + Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/IUserRoleStore.cs b/src/Microsoft.AspNet.Identity/IUserRoleStore.cs index e74ca87fe6..690eeeb45a 100644 --- a/src/Microsoft.AspNet.Identity/IUserRoleStore.cs +++ b/src/Microsoft.AspNet.Identity/IUserRoleStore.cs @@ -51,5 +51,13 @@ namespace Microsoft.AspNet.Identity /// Task IsInRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Returns all users in given role + /// + /// + /// + /// + Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity/UserManager.cs b/src/Microsoft.AspNet.Identity/UserManager.cs index 3b18d534fd..787f91ebeb 100644 --- a/src/Microsoft.AspNet.Identity/UserManager.cs +++ b/src/Microsoft.AspNet.Identity/UserManager.cs @@ -1962,6 +1962,37 @@ namespace Microsoft.AspNet.Identity return await store.GetAccessFailedCountAsync(user, cancellationToken); } + public virtual Task> GetUsersForClaimAsync(Claim claim, + CancellationToken cancellationToken = default(CancellationToken)) + { + ThrowIfDisposed(); + var store = GetClaimStore(); + if (claim == null) + { + throw new ArgumentNullException("claim"); + } + return store.GetUsersForClaimAsync(claim, cancellationToken); + } + + /// + /// Get all the users in a role + /// + /// + /// + /// + public virtual Task> GetUsersInRoleAsync(string roleName, + CancellationToken cancellationToken = default(CancellationToken)) + { + ThrowIfDisposed(); + var store = GetUserRoleStore(); + if (roleName == null) + { + throw new ArgumentNullException("role"); + } + + return store.GetUsersInRoleAsync(roleName, cancellationToken); + } + private void ThrowIfDisposed() { if (_disposed) diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs deleted file mode 100644 index 98c6e6506c..0000000000 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.EntityFramework.InMemory.Test; -using Microsoft.Data.Entity; -using Microsoft.Framework.DependencyInjection; - -namespace Microsoft.AspNet.Identity -{ - public static class EntityInMemoryTestServiceCollectionExtensions - { - public static IdentityBuilder AddIdentityInMemory(this ServiceCollection services, InMemoryContext context) - { - return services.AddIdentityInMemory(context); - } - - public static IdentityBuilder AddIdentityInMemory(this ServiceCollection services, TDbContext context) - where TUser : IdentityUser - where TRole : IdentityRole - where TDbContext : DbContext - { - var builder = services.AddIdentity(); - builder.AddDefaultTokenProviders(); - services.AddInstance>(new InMemoryUserStore(context)); - var store = new RoleStore(context); - services.AddInstance>(store); - return builder; - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs index 375f24319d..16455fa25a 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryContext.cs @@ -3,41 +3,25 @@ using System; using Microsoft.Data.Entity; -using Microsoft.Data.Entity.Metadata; namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { public class InMemoryContext : - InMemoryContext + InMemoryContext { - public InMemoryContext() { } - public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { } } public class InMemoryContext : - InMemoryContext + InMemoryContext where TUser : IdentityUser { - public InMemoryContext() { } - public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { } } - public class InMemoryContext : DbContext + public class InMemoryContext : IdentityDbContext where TUser : IdentityUser where TRole : IdentityRole - where TUserLogin : IdentityUserLogin - where TUserRole : IdentityUserRole - where TUserClaim : IdentityUserClaim where TKey : IEquatable { - - public DbSet Users { get; set; } - public DbSet Roles { get; set; } - public DbSet RoleClaims { get; set; } - - public InMemoryContext(IServiceProvider serviceProvider) - : base(serviceProvider) { } - public InMemoryContext() { } protected override void OnConfiguring(DbContextOptions builder) @@ -45,50 +29,5 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test // Want fresh in memory store for tests always for now builder.UseInMemoryStore(persist: false); } - - protected override void OnModelCreating(ModelBuilder builder) - { - builder.Entity(b => - { - b.Key(u => u.Id); - b.Property(u => u.UserName); - b.ForRelational().Table("AspNetUsers"); - }); - - builder.Entity(b => - { - b.Key(r => r.Id); - b.ForRelational().Table("AspNetRoles"); - }); - - builder.Entity(b => - { - b.Key(r => new { r.UserId, r.RoleId }); - b.ForeignKey(f => f.UserId); - b.ForeignKey(f => f.RoleId); - b.ForRelational().Table("AspNetUserRoles"); - }); - - builder.Entity(b => - { - b.Key(l => new { l.LoginProvider, l.ProviderKey, l.UserId }); - b.ForeignKey(f => f.UserId); - b.ForRelational().Table("AspNetUserLogins"); - }); - - builder.Entity(b => - { - b.Key(c => c.Id); - b.ForeignKey(f => f.UserId); - b.ForRelational().Table("AspNetUserClaims"); - }); - - builder.Entity>(b => - { - b.Key(c => c.Id); - b.ForeignKey(f => f.RoleId); - b.ForRelational().Table("AspNetRoleClaims"); - }); - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs index e8bd3397b6..66c01e5998 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test protected override void AddUserStore(IServiceCollection services, object context = null) { - services.AddInstance>(new InMemoryUserStore((InMemoryContext)context)); + services.AddInstance>(new UserStore((InMemoryContext)context)); } protected override void AddRoleStore(IServiceCollection services, object context = null) diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs deleted file mode 100644 index e2e9f6e43d..0000000000 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryUserStore.cs +++ /dev/null @@ -1,929 +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; -using System.Globalization; -using System.Linq; -using System.Linq.Expressions; -using System.Security.Claims; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Data.Entity; - -namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test -{ - public class InMemoryUserStore : InMemoryUserStore - { - public InMemoryUserStore(InMemoryContext context) : base(context) { } - } - - public class InMemoryUserStore : InMemoryUserStore - where TUser : IdentityUser - { - public InMemoryUserStore(InMemoryContext context) : base(context) { } - } - - public class InMemoryUserStore : InMemoryUserStore - where TUser:IdentityUser - where TContext : DbContext - { - public InMemoryUserStore(TContext context) : base(context) { } - } - - public class InMemoryUserStore : - IUserLoginStore, - IUserClaimStore, - IUserRoleStore, - IUserPasswordStore, - IUserSecurityStampStore, - IQueryableUserStore, - IUserEmailStore, - IUserPhoneNumberStore, - IUserTwoFactorStore, - IUserLockoutStore - where TKey : IEquatable - where TUser : IdentityUser - where TRole : IdentityRole - where TUserLogin : IdentityUserLogin, new() - where TUserRole : IdentityUserRole, new() - where TUserClaim : IdentityUserClaim, new() - where TContext : DbContext - { - private bool _disposed; - - public InMemoryUserStore(TContext context) - { - if (context == null) - { - throw new ArgumentNullException("context"); - } - Context = context; - AutoSaveChanges = true; - } - - public TContext Context { get; private set; } - - /// - /// If true will call SaveChanges after CreateAsync/UpdateAsync/DeleteAsync - /// - public bool AutoSaveChanges { get; set; } - - private Task SaveChanges(CancellationToken cancellationToken) - { - return AutoSaveChanges ? Context.SaveChangesAsync(cancellationToken) : Task.FromResult(0); - } - - protected virtual Task GetUserAggregate(Expression> filter, CancellationToken cancellationToken = default(CancellationToken)) - { - return Task.FromResult(Users.SingleOrDefault(filter)); - // TODO: return Users.SingleOrDefaultAsync(filter, cancellationToken); - //Include(u => u.Roles) - //.Include(u => u.Claims) - //.Include(u => u.Logins) - } - - public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(Convert.ToString(user.Id, CultureInfo.InvariantCulture)); - } - - public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.UserName); - } - - public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.UserName = userName; - return Task.FromResult(0); - } - - public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.NormalizedUserName); - } - - public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.NormalizedUserName = userName; - return Task.FromResult(0); - } - - public async virtual Task CreateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - await Context.AddAsync(user, cancellationToken); - await SaveChanges(cancellationToken); - } - - public async virtual Task UpdateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - Context.Update(user); - await SaveChanges(cancellationToken); - } - - public async virtual Task DeleteAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - Context.Remove(user); - await SaveChanges(cancellationToken); - } - - public virtual TKey ConvertUserId(string userId) - { - return (TKey)Convert.ChangeType(userId, typeof(TKey)); - } - - /// - /// Find a user by id - /// - /// - /// - /// - public virtual Task FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - var id = ConvertUserId(userId); - return GetUserAggregate(u => u.Id.Equals(id), cancellationToken); - } - - /// - /// Find a user by name - /// - /// - /// - /// - public virtual Task FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - return GetUserAggregate(u => u.UserName.ToUpper() == userName.ToUpper(), cancellationToken); - } - - public IQueryable Users - { - get { return Context.Set(); } - } - - public async virtual Task AddLoginAsync(TUser user, UserLoginInfo login, - CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - var l = new TUserLogin - { - UserId = user.Id, - ProviderKey = login.ProviderKey, - LoginProvider = login.LoginProvider, - ProviderDisplayName = login.ProviderDisplayName - }; - await Context.Set().AddAsync(l, cancellationToken); - user.Logins.Add(l); - } - - public virtual Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, - CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - var entry = user.Logins.SingleOrDefault(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); - if (entry != null) - { - user.Logins.Remove(entry); - Context.Set>().Remove(entry); - } - return Task.FromResult(0); - } - - public virtual Task> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - IList result = user.Logins.Select( - l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)) - .ToList(); - return Task.FromResult(result); - } - - public async virtual Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - var userLogin = await Context.Set() - .FirstOrDefaultAsync(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); - if (userLogin != null) - { - return await GetUserAggregate(u => u.Id.Equals(userLogin.UserId), cancellationToken); - } - return null; - } - - /// - /// Set the password hash for a user - /// - /// - /// - /// - /// - public virtual Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.PasswordHash = passwordHash; - return Task.FromResult(0); - } - - /// - /// Get the password hash for a user - /// - /// - /// - /// - public virtual Task GetPasswordHashAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.PasswordHash); - } - - /// - /// Returns true if the user has a password set - /// - /// - /// - /// - public virtual Task HasPasswordAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - return Task.FromResult(user.PasswordHash != null); - } - - /// - /// Return the claims for a user - /// - /// - /// - /// - public virtual Task> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - IList result = user.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList(); - return Task.FromResult(result); - } - - /// - /// Add claims to a user - /// - /// - /// - /// - /// - public virtual Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - if (claims == null) - { - throw new ArgumentNullException("claims"); - } - foreach (var claim in claims) - { - user.Claims.Add(new TUserClaim { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value }); - } - return Task.FromResult(0); - } - - /// - /// Updates the give claim with the new one. - /// - /// - /// - /// - /// - /// - public Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken)) - { - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - if (claim == null) - { - throw new ArgumentNullException("claim"); - } - if (newClaim == null) - { - throw new ArgumentNullException("newClaim"); - } - - var matchedClaim = user.Claims.FirstOrDefault(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type); - if(matchedClaim != null) - { - matchedClaim.ClaimValue = newClaim.Value; - matchedClaim.ClaimType = newClaim.Type; - } - return Task.FromResult(0); - } - - /// - /// Remove claims from a user - /// - /// - /// - /// - /// - public virtual Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - if (claims == null) - { - throw new ArgumentNullException("claims"); - } - foreach (var claim in claims) - { - var matchingClaims = - user.Claims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList(); - foreach (var c in matchingClaims) - { - user.Claims.Remove(c); - } - } - // TODO:these claims might not exist in the dbset - //var query = - // _userClaims.Where( - // uc => uc.UserId.Equals(user.Id) && uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type); - //foreach (var c in query) - //{ - // _userClaims.Remove(c); - //} - return Task.FromResult(0); - } - - /// - /// Returns whether the user email is confirmed - /// - /// - /// - /// - public virtual Task GetEmailConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.EmailConfirmed); - } - - /// - /// Set IsConfirmed on the user - /// - /// - /// - /// - /// - public virtual Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.EmailConfirmed = confirmed; - return Task.FromResult(0); - } - - /// - /// Set the user email - /// - /// - /// - /// - /// - public virtual Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.Email = email; - return Task.FromResult(0); - } - - /// - /// Get the user's email - /// - /// - /// - /// - public virtual Task GetEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.Email); - } - - /// - /// FindByLoginAsync a user by email - /// - /// - /// - /// - public virtual Task FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - return Task.FromResult(Users.SingleOrDefault(u => u.Email.ToUpper() == email.ToUpper())); - //return GetUserAggregate(u => u.Email.ToUpper() == email.ToUpper(), cancellationToken); - } - - /// - /// Returns the DateTimeOffset that represents the end of a user's lockout, any time in the past should be considered - /// not locked out. - /// - /// - /// - /// - public virtual Task GetLockoutEndDateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.LockoutEnd); - } - - /// - /// Locks a user out until the specified end date (set to a past date, to unlock a user) - /// - /// - /// - /// - /// - public virtual Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.LockoutEnd = lockoutEnd; - return Task.FromResult(0); - } - - /// - /// Used to record when an attempt to access the user has failed - /// - /// - /// - /// - public virtual Task IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.AccessFailedCount++; - return Task.FromResult(user.AccessFailedCount); - } - - /// - /// Used to reset the account access count, typically after the account is successfully accessed - /// - /// - /// - /// - public virtual Task ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.AccessFailedCount = 0; - return Task.FromResult(0); - } - - /// - /// Returns the current number of failed access attempts. This number usually will be reset whenever the password is - /// verified or the account is locked out. - /// - /// - /// - /// - public virtual Task GetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.AccessFailedCount); - } - - /// - /// Returns whether the user can be locked out. - /// - /// - /// - /// - public virtual Task GetLockoutEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.LockoutEnabled); - } - - /// - /// Sets whether the user can be locked out. - /// - /// - /// - /// - /// - public virtual Task SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.LockoutEnabled = enabled; - return Task.FromResult(0); - } - - /// - /// Set the user's phone number - /// - /// - /// - /// - /// - public virtual Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.PhoneNumber = phoneNumber; - return Task.FromResult(0); - } - - /// - /// Get a user's phone number - /// - /// - /// - /// - public virtual Task GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.PhoneNumber); - } - - /// - /// Returns whether the user phoneNumber is confirmed - /// - /// - /// - /// - public virtual Task GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.PhoneNumberConfirmed); - } - - /// - /// Set PhoneNumberConfirmed on the user - /// - /// - /// - /// - /// - public virtual Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.PhoneNumberConfirmed = confirmed; - return Task.FromResult(0); - } - - /// - /// Add a user to a role - /// - /// - /// - /// - /// - public virtual Task AddToRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - // TODO: - //if (String.IsNullOrWhiteSpace(roleName)) - //{ - // throw new ArgumentException(IdentityResources.ValueCannotBeNullOrEmpty, "roleName"); - //} - var roleEntity = Context.Set().SingleOrDefault(r => r.Name.ToUpper() == roleName.ToUpper()); - if (roleEntity == null) - { - throw new InvalidOperationException("Role Not Found"); - //TODO: String.Format(CultureInfo.CurrentCulture, IdentityResources.RoleNotFound, roleName)); - } - var ur = new TUserRole { UserId = user.Id, RoleId = roleEntity.Id }; - user.Roles.Add(ur); - roleEntity.Users.Add(ur); - return Task.FromResult(0); - } - - /// - /// Remove a user from a role - /// - /// - /// - /// - /// - public virtual Task RemoveFromRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - //if (String.IsNullOrWhiteSpace(roleName)) - //{ - // throw new ArgumentException(IdentityResources.ValueCannotBeNullOrEmpty, "roleName"); - //} - var roleEntity = Context.Set().SingleOrDefault(r => r.Name.ToUpper() == roleName.ToUpper()); - if (roleEntity != null) - { - var userRole = user.Roles.FirstOrDefault(r => roleEntity.Id.Equals(r.RoleId)); - if (userRole != null) - { - user.Roles.Remove(userRole); - roleEntity.Users.Remove(userRole); - } - } - return Task.FromResult(0); - } - - /// - /// Get the names of the roles a user is a member of - /// - /// - /// - /// - public virtual Task> GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - var query = from userRoles in user.Roles - join roles in Context.Set() - on userRoles.RoleId equals roles.Id - select roles.Name; - return Task.FromResult>(query.ToList()); - } - - /// - /// Returns true if the user is in the named role - /// - /// - /// - /// - /// - public virtual Task IsInRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - //if (String.IsNullOrWhiteSpace(roleName)) - //{ - // throw new ArgumentException(IdentityResources.ValueCannotBeNullOrEmpty, "roleName"); - //} - var any = - Context.Set().Where(r => r.Name.ToUpper() == roleName.ToUpper()) - .Where(r => r.Users.Any(ur => ur.UserId.Equals(user.Id))) - .Count() > 0; - return Task.FromResult(any); - } - - /// - /// Set the security stamp for the user - /// - /// - /// - /// - /// - public virtual Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.SecurityStamp = stamp; - return Task.FromResult(0); - } - - /// - /// Get the security stamp for a user - /// - /// - /// - /// - public virtual Task GetSecurityStampAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.SecurityStamp); - } - - /// - /// Set whether two factor authentication is enabled for the user - /// - /// - /// - /// - /// - public virtual Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - user.TwoFactorEnabled = enabled; - return Task.FromResult(0); - } - - /// - /// Gets whether two factor authentication is enabled for the user - /// - /// - /// - /// - public virtual Task GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); - ThrowIfDisposed(); - if (user == null) - { - throw new ArgumentNullException("user"); - } - return Task.FromResult(user.TwoFactorEnabled); - } - - private void ThrowIfDisposed() - { - if (_disposed) - { - throw new ObjectDisposedException(GetType().Name); - } - } - - /// - /// Dispose the store - /// - public void Dispose() - { - _disposed = true; - } - } -} diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs index 3112c72c58..5e4a8ef137 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test services.AddEntityFramework().AddInMemoryStore(); var serviceProvider = services.BuildServiceProvider(); - var db = new InMemoryContext(serviceProvider); + var db = new InMemoryContext(); db.Database.EnsureCreated(); return db; diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs index e056b3f048..2590eccba7 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryUserStore.cs @@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Identity.InMemory public Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken)) { var matchedClaims = user.Claims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList(); - foreach(var matchedClaim in matchedClaims) + foreach (var matchedClaim in matchedClaims) { matchedClaim.ClaimValue = newClaim.Value; matchedClaim.ClaimType = newClaim.Type; @@ -349,5 +349,30 @@ namespace Microsoft.AspNet.Identity.InMemory user.NormalizedUserName = userName; return Task.FromResult(0); } + + // RoleId == rolename for inmemory store tests + public Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) + { + if (String.IsNullOrEmpty(roleName)) + { + throw new ArgumentNullException("role"); + } + + return Task.FromResult>(Users.Where(u => (u.Roles.Where(x => x.RoleId == roleName).Count() > 0)).Select(x => x).ToList()); + } + + public Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) + { + if (claim == null) + { + throw new ArgumentNullException("claim"); + } + + var query = from user in Users + where user.Claims.Where(x => x.ClaimType == claim.Type && x.ClaimValue == claim.Value).FirstOrDefault() != null + select user; + + return Task.FromResult>(query.ToList()); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs index f9068d6e30..de496f8ff7 100644 --- a/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs +++ b/test/Microsoft.AspNet.Identity.Test/UserManagerTest.cs @@ -961,6 +961,16 @@ namespace Microsoft.AspNet.Identity.Test { return Task.FromResult(0); } + + public Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) + { + return Task.FromResult>(new List()); + } + + public Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) + { + return Task.FromResult>(new List()); + } } private class NoOpTokenProvider : IUserTokenProvider @@ -1218,6 +1228,16 @@ namespace Microsoft.AspNet.Identity.Test { throw new NotImplementedException(); } + + public Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) + { + throw new NotImplementedException(); + } + + public Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) + { + throw new NotImplementedException(); + } } } } \ No newline at end of file diff --git a/test/Shared/UserManagerTestBase.cs b/test/Shared/UserManagerTestBase.cs index 2ba65a828a..8997be452f 100644 --- a/test/Shared/UserManagerTestBase.cs +++ b/test/Shared/UserManagerTestBase.cs @@ -1579,6 +1579,59 @@ namespace Microsoft.AspNet.Identity.Test // set to a valid value await userMgr.SetLockoutEndDateAsync(user, DateTimeOffset.Parse("01/01/2014")); Assert.Equal(DateTimeOffset.Parse("01/01/2014"), await userMgr.GetLockoutEndDateAsync(user)); + } + + [Fact] + public async Task CanGetUsersWithClaims() + { + var manager = CreateManager(); + + for (int i = 0; i < 6; i++) + { + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + if ((i % 2) == 0) + { + IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, new Claim("foo", "bar"))); + } + } + + Assert.Equal(3, (await manager.GetUsersForClaimAsync(new Claim("foo", "bar"))).Count); + + Assert.Equal(0, (await manager.GetUsersForClaimAsync(new Claim("123", "456"))).Count); + } + + [Fact] + public async Task CanGetUsersInRole() + { + var context = CreateTestContext(); + var manager = CreateManager(context); + var roleManager = CreateRoleManager(context); + var roles = GenerateRoles("UsersInRole", 4); + + foreach (var role in roles) + { + IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); + } + + for (int i = 0; i < 6; i++) + { + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + if ((i % 2) == 0) + { + IdentityResultAssert.IsSuccess(await manager.AddToRolesAsync(user, roles.Select(x=>x.Name).AsEnumerable())); + } + } + + foreach (var role in roles) + { + Assert.Equal(3, (await manager.GetUsersInRoleAsync(role.Name)).Count); + } + + Assert.Equal(0, (await manager.GetUsersInRoleAsync("123456")).Count); } public List GenerateUsers(string userNamePrefix, int count)