зеркало из https://github.com/aspnet/Identity.git
Added new apis to query users and fixed EF.Inmemory
This commit is contained in:
Родитель
5d29d11ccb
Коммит
625b270924
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
@ -12,6 +12,7 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<DevelopmentServerPort>5131</DevelopmentServerPort>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -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<TKey> { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value });
|
||||
return RoleClaims.AddAsync(new IdentityRoleClaim<TKey> { 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);
|
||||
|
|
|
@ -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<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
||||
|
@ -417,7 +417,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework
|
|||
}
|
||||
foreach (var claim in claims)
|
||||
{
|
||||
await UserClaims.AddAsync(new IdentityUserClaim<TKey> { UserId = user.Id, ClaimType = claim.Type, ClaimValue = claim.Value });
|
||||
await UserClaims.AddAsync(new IdentityUserClaim<TKey> { 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<TUser> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all users with given claim
|
||||
/// </summary>
|
||||
/// <param name="claim"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IList<TUser>> 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<TUser>)await query.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all users in given role
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IList<TUser>> 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<TUser>) await query.ToListAsync(cancellationToken);
|
||||
}
|
||||
return new List<TUser>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,5 +51,13 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <returns></returns>
|
||||
Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims,
|
||||
CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Get users having a specific claim
|
||||
/// </summary>
|
||||
/// <param name="claim">Claim to look up</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IList<TUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken));
|
||||
}
|
||||
}
|
|
@ -51,5 +51,13 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <returns></returns>
|
||||
Task<bool> IsInRoleAsync(TUser user, string roleName,
|
||||
CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
||||
/// <summary>
|
||||
/// Returns all users in given role
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken));
|
||||
}
|
||||
}
|
|
@ -1962,6 +1962,37 @@ namespace Microsoft.AspNet.Identity
|
|||
return await store.GetAccessFailedCountAsync(user, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual Task<IList<TUser>> GetUsersForClaimAsync(Claim claim,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
var store = GetClaimStore();
|
||||
if (claim == null)
|
||||
{
|
||||
throw new ArgumentNullException("claim");
|
||||
}
|
||||
return store.GetUsersForClaimAsync(claim, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all the users in a role
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<IList<TUser>> 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)
|
||||
|
|
|
@ -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<IdentityUser, IdentityRole, InMemoryContext>(context);
|
||||
}
|
||||
|
||||
public static IdentityBuilder AddIdentityInMemory<TUser, TRole, TDbContext>(this ServiceCollection services, TDbContext context)
|
||||
where TUser : IdentityUser
|
||||
where TRole : IdentityRole
|
||||
where TDbContext : DbContext
|
||||
{
|
||||
var builder = services.AddIdentity<TUser, TRole>();
|
||||
builder.AddDefaultTokenProviders();
|
||||
services.AddInstance<IUserStore<TUser>>(new InMemoryUserStore<TUser, TDbContext>(context));
|
||||
var store = new RoleStore<TRole, TDbContext>(context);
|
||||
services.AddInstance<IRoleStore<TRole>>(store);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<IdentityUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
|
||||
InMemoryContext<IdentityUser, IdentityRole, string>
|
||||
{
|
||||
public InMemoryContext() { }
|
||||
public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
}
|
||||
|
||||
public class InMemoryContext<TUser> :
|
||||
InMemoryContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
|
||||
InMemoryContext<TUser, IdentityRole, string>
|
||||
where TUser : IdentityUser
|
||||
{
|
||||
public InMemoryContext() { }
|
||||
public InMemoryContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
}
|
||||
|
||||
public class InMemoryContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
|
||||
public class InMemoryContext<TUser, TRole, TKey> : IdentityDbContext<TUser,TRole,TKey>
|
||||
where TUser : IdentityUser<TKey>
|
||||
where TRole : IdentityRole<TKey>
|
||||
where TUserLogin : IdentityUserLogin<TKey>
|
||||
where TUserRole : IdentityUserRole<TKey>
|
||||
where TUserClaim : IdentityUserClaim<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
|
||||
public DbSet<TUser> Users { get; set; }
|
||||
public DbSet<TRole> Roles { get; set; }
|
||||
public DbSet<IdentityRoleClaim> 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<TUser>(b =>
|
||||
{
|
||||
b.Key(u => u.Id);
|
||||
b.Property(u => u.UserName);
|
||||
b.ForRelational().Table("AspNetUsers");
|
||||
});
|
||||
|
||||
builder.Entity<TRole>(b =>
|
||||
{
|
||||
b.Key(r => r.Id);
|
||||
b.ForRelational().Table("AspNetRoles");
|
||||
});
|
||||
|
||||
builder.Entity<TUserRole>(b =>
|
||||
{
|
||||
b.Key(r => new { r.UserId, r.RoleId });
|
||||
b.ForeignKey<TUser>(f => f.UserId);
|
||||
b.ForeignKey<TRole>(f => f.RoleId);
|
||||
b.ForRelational().Table("AspNetUserRoles");
|
||||
});
|
||||
|
||||
builder.Entity<TUserLogin>(b =>
|
||||
{
|
||||
b.Key(l => new { l.LoginProvider, l.ProviderKey, l.UserId });
|
||||
b.ForeignKey<TUser>(f => f.UserId);
|
||||
b.ForRelational().Table("AspNetUserLogins");
|
||||
});
|
||||
|
||||
builder.Entity<TUserClaim>(b =>
|
||||
{
|
||||
b.Key(c => c.Id);
|
||||
b.ForeignKey<TUser>(f => f.UserId);
|
||||
b.ForRelational().Table("AspNetUserClaims");
|
||||
});
|
||||
|
||||
builder.Entity<IdentityRoleClaim<TKey>>(b =>
|
||||
{
|
||||
b.Key(c => c.Id);
|
||||
b.ForeignKey<TRole>(f => f.RoleId);
|
||||
b.ForRelational().Table("AspNetRoleClaims");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
|
|||
|
||||
protected override void AddUserStore(IServiceCollection services, object context = null)
|
||||
{
|
||||
services.AddInstance<IUserStore<IdentityUser>>(new InMemoryUserStore<IdentityUser, InMemoryContext>((InMemoryContext)context));
|
||||
services.AddInstance<IUserStore<IdentityUser>>(new UserStore<IdentityUser>((InMemoryContext)context));
|
||||
}
|
||||
|
||||
protected override void AddRoleStore(IServiceCollection services, object context = 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<IdentityUser, InMemoryContext>
|
||||
{
|
||||
public InMemoryUserStore(InMemoryContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser> : InMemoryUserStore<TUser, InMemoryContext>
|
||||
where TUser : IdentityUser
|
||||
{
|
||||
public InMemoryUserStore(InMemoryContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser, TContext> : InMemoryUserStore<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim, TContext>
|
||||
where TUser:IdentityUser
|
||||
where TContext : DbContext
|
||||
{
|
||||
public InMemoryUserStore(TContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim, TContext> :
|
||||
IUserLoginStore<TUser>,
|
||||
IUserClaimStore<TUser>,
|
||||
IUserRoleStore<TUser>,
|
||||
IUserPasswordStore<TUser>,
|
||||
IUserSecurityStampStore<TUser>,
|
||||
IQueryableUserStore<TUser>,
|
||||
IUserEmailStore<TUser>,
|
||||
IUserPhoneNumberStore<TUser>,
|
||||
IUserTwoFactorStore<TUser>,
|
||||
IUserLockoutStore<TUser>
|
||||
where TKey : IEquatable<TKey>
|
||||
where TUser : IdentityUser<TKey>
|
||||
where TRole : IdentityRole<TKey>
|
||||
where TUserLogin : IdentityUserLogin<TKey>, new()
|
||||
where TUserRole : IdentityUserRole<TKey>, new()
|
||||
where TUserClaim : IdentityUserClaim<TKey>, 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; }
|
||||
|
||||
/// <summary>
|
||||
/// If true will call SaveChanges after CreateAsync/UpdateAsync/DeleteAsync
|
||||
/// </summary>
|
||||
public bool AutoSaveChanges { get; set; }
|
||||
|
||||
private Task SaveChanges(CancellationToken cancellationToken)
|
||||
{
|
||||
return AutoSaveChanges ? Context.SaveChangesAsync(cancellationToken) : Task.FromResult(0);
|
||||
}
|
||||
|
||||
protected virtual Task<TUser> GetUserAggregate(Expression<Func<TUser, bool>> 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<string> 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<string> 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<string> 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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a user by id
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
var id = ConvertUserId(userId);
|
||||
return GetUserAggregate(u => u.Id.Equals(id), cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a user by name
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<TUser> FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
return GetUserAggregate(u => u.UserName.ToUpper() == userName.ToUpper(), cancellationToken);
|
||||
}
|
||||
|
||||
public IQueryable<TUser> Users
|
||||
{
|
||||
get { return Context.Set<TUser>(); }
|
||||
}
|
||||
|
||||
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<TUserLogin>().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<IdentityUserLogin<TKey>>().Remove(entry);
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public virtual Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
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(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
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);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the password hash for a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="passwordHash"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the password hash for a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<string> GetPasswordHashAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.PasswordHash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the user has a password set
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> HasPasswordAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return Task.FromResult(user.PasswordHash != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the claims for a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<IList<Claim>> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
IList<Claim> result = user.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList();
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add claims to a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="claims"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task AddClaimsAsync(TUser user, IEnumerable<Claim> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the give claim with the new one.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="claim"></param>
|
||||
/// <param name="newClaim"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove claims from a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="claims"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the user email is confirmed
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> GetEmailConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.EmailConfirmed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set IsConfirmed on the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="confirmed"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the user email
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the user's email
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<string> GetEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.Email);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FindByLoginAsync a user by email
|
||||
/// </summary>
|
||||
/// <param name="email"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<TUser> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the DateTimeOffset that represents the end of a user's lockout, any time in the past should be considered
|
||||
/// not locked out.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<DateTimeOffset?> GetLockoutEndDateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.LockoutEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks a user out until the specified end date (set to a past date, to unlock a user)
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="lockoutEnd"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to record when an attempt to access the user has failed
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<int> IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
user.AccessFailedCount++;
|
||||
return Task.FromResult(user.AccessFailedCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to reset the account access count, typically after the account is successfully accessed
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<int> GetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.AccessFailedCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the user can be locked out.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> GetLockoutEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.LockoutEnabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether the user can be locked out.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="enabled"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the user's phone number
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="phoneNumber"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a user's phone number
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<string> GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.PhoneNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the user phoneNumber is confirmed
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.PhoneNumberConfirmed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set PhoneNumberConfirmed on the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="confirmed"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a user to a role
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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<TRole>().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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a user from a role
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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<TRole>().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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the names of the roles a user is a member of
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<IList<string>> 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<TRole>()
|
||||
on userRoles.RoleId equals roles.Id
|
||||
select roles.Name;
|
||||
return Task.FromResult<IList<string>>(query.ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the user is in the named role
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> 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<TRole>().Where(r => r.Name.ToUpper() == roleName.ToUpper())
|
||||
.Where(r => r.Users.Any(ur => ur.UserId.Equals(user.Id)))
|
||||
.Count() > 0;
|
||||
return Task.FromResult(any);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the security stamp for the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="stamp"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the security stamp for a user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<string> GetSecurityStampAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
return Task.FromResult(user.SecurityStamp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set whether two factor authentication is enabled for the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="enabled"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether two factor authentication is enabled for the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<bool> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the store
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (String.IsNullOrEmpty(roleName))
|
||||
{
|
||||
throw new ArgumentNullException("role");
|
||||
}
|
||||
|
||||
return Task.FromResult<IList<TUser>>(Users.Where(u => (u.Roles.Where(x => x.RoleId == roleName).Count() > 0)).Select(x => x).ToList());
|
||||
}
|
||||
|
||||
public Task<IList<TUser>> 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<IList<TUser>>(query.ToList());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -961,6 +961,16 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<IList<TestUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return Task.FromResult<IList<TestUser>>(new List<TestUser>());
|
||||
}
|
||||
|
||||
public Task<IList<TestUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return Task.FromResult<IList<TestUser>>(new List<TestUser>());
|
||||
}
|
||||
}
|
||||
|
||||
private class NoOpTokenProvider : IUserTokenProvider<TestUser>
|
||||
|
@ -1218,6 +1228,16 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IList<TestUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IList<TestUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1581,6 +1581,59 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
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<TUser> GenerateUsers(string userNamePrefix, int count)
|
||||
{
|
||||
var users = new List<TUser>(count);
|
||||
|
|
Загрузка…
Ссылка в новой задаче