UserManager should normalize role name

This commit is contained in:
Hao Kung 2016-02-04 14:09:11 -08:00
parent ada5756c87
commit 7ba61d6c6f
11 changed files with 179 additions and 193 deletions

View File

@ -1,4 +1,3 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
@ -28,8 +27,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Identi
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore", "src\Microsoft.AspNetCore.Identity.EntityFrameworkCore\Microsoft.AspNetCore.Identity.EntityFrameworkCore.xproj", "{4490894C-3572-4E63-86F1-EE5105CE8A06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop45", "samples\Interop45\Interop45.csproj", "{9A46D74F-8347-4821-A888-8DA0844443EF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -110,18 +107,6 @@ Global
{4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x86.ActiveCfg = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|x86.ActiveCfg = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Debug|x86.Build.0 = Debug|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|Any CPU.Build.0 = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|x86.ActiveCfg = Release|Any CPU
{9A46D74F-8347-4821-A888-8DA0844443EF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -134,6 +119,5 @@ Global
{37236EA3-915D-46D5-997C-DF513C500E4B} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
{EA7EB28F-53B8-4009-9C6B-74DB090CA8DD} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
{4490894C-3572-4E63-86F1-EE5105CE8A06} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
{9A46D74F-8347-4821-A888-8DA0844443EF} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
EndGlobalSection
EndGlobal

View File

@ -394,13 +394,13 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
}
/// <summary>
/// Adds the given <paramref name="roleName"/> to the specified <paramref name="user"/>.
/// Adds the given <paramref name="normalizedRoleName"/> to the specified <paramref name="user"/>.
/// </summary>
/// <param name="user">The user to add the role to.</param>
/// <param name="roleName">The role to add.</param>
/// <param name="normalizedRoleName">The role to add.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
public async virtual Task AddToRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task AddToRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@ -408,27 +408,27 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
{
throw new ArgumentNullException(nameof(user));
}
if (string.IsNullOrWhiteSpace(roleName))
if (string.IsNullOrWhiteSpace(normalizedRoleName))
{
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(roleName));
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName));
}
var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken);
var roleEntity = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken);
if (roleEntity == null)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, roleName));
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, normalizedRoleName));
}
var ur = new IdentityUserRole<TKey> { UserId = user.Id, RoleId = roleEntity.Id };
UserRoles.Add(ur);
}
/// <summary>
/// Removes the given <paramref name="roleName"/> from the specified <paramref name="user"/>.
/// Removes the given <paramref name="normalizedRoleName"/> from the specified <paramref name="user"/>.
/// </summary>
/// <param name="user">The user to remove the role from.</param>
/// <param name="roleName">The role to remove.</param>
/// <param name="normalizedRoleName">The role to remove.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
public async virtual Task RemoveFromRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task RemoveFromRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@ -436,11 +436,11 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
{
throw new ArgumentNullException(nameof(user));
}
if (string.IsNullOrWhiteSpace(roleName))
if (string.IsNullOrWhiteSpace(normalizedRoleName))
{
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(roleName));
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName));
}
var roleEntity = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken);
var roleEntity = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken);
if (roleEntity != null)
{
var userRole = await UserRoles.FirstOrDefaultAsync(r => roleEntity.Id.Equals(r.RoleId) && r.UserId.Equals(user.Id), cancellationToken);
@ -474,14 +474,14 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
}
/// <summary>
/// Returns a flag indicating if the specified user is a member of the give <paramref name="roleName"/>.
/// Returns a flag indicating if the specified user is a member of the give <paramref name="normalizedRoleName"/>.
/// </summary>
/// <param name="user">The user whose role membership should be checked.</param>
/// <param name="roleName">The role to check membership of</param>
/// <param name="normalizedRoleName">The role to check membership of</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>A <see cref="Task{TResult}"/> containing a flag indicating if the specified user is a member of the given group. If the
/// user is a member of the group the returned value with be true, otherwise it will be false.</returns>
public virtual async Task<bool> IsInRoleAsync(TUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))
public virtual async Task<bool> IsInRoleAsync(TUser user, string normalizedRoleName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@ -489,11 +489,11 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
{
throw new ArgumentNullException(nameof(user));
}
if (string.IsNullOrWhiteSpace(roleName))
if (string.IsNullOrWhiteSpace(normalizedRoleName))
{
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(roleName));
throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName));
}
var role = await Roles.SingleOrDefaultAsync(r => r.Name.ToUpper() == roleName.ToUpper(), cancellationToken);
var role = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken);
if (role != null)
{
var userId = user.Id;
@ -1168,21 +1168,21 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
/// <summary>
/// Retrieves all users in the specified role.
/// </summary>
/// <param name="roleName">The role whose users should be retrieved.</param>
/// <param name="normalizedRoleName">The role whose users should be retrieved.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>
/// The <see cref="Task"/> contains a list of users, if any, that are in the specified role.
/// </returns>
public async virtual Task<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task<IList<TUser>> GetUsersInRoleAsync(string normalizedRoleName, CancellationToken cancellationToken = default(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
if (String.IsNullOrEmpty(roleName))
if (String.IsNullOrEmpty(normalizedRoleName))
{
throw new ArgumentNullException(nameof(roleName));
throw new ArgumentNullException(nameof(normalizedRoleName));
}
var role = await Roles.Where(x => x.Name.Equals(roleName)).FirstOrDefaultAsync(cancellationToken);
var role = await Roles.Where(x => x.NormalizedName == normalizedRoleName).FirstOrDefaultAsync(cancellationToken);
if (role != null)
{

View File

@ -4,11 +4,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -17,7 +15,7 @@ namespace Microsoft.AspNetCore.Identity
/// <summary>
/// Provides the APIs for managing roles in a persistence store.
/// </summary>
/// <typeparam name="TUser">The type encapsulating a role.</typeparam>
/// <typeparam name="TRole">The type encapsulating a role.</typeparam>
public class RoleManager<TRole> : IDisposable where TRole : class
{
private bool _disposed;

View File

@ -434,9 +434,9 @@ namespace Microsoft.AspNetCore.Identity
}
/// <summary>
/// Finds and returns a user, if any, who has the specified normalized user name.
/// Finds and returns a user, if any, who has the specified user name.
/// </summary>
/// <param name="normalizedUserName">The normalized user name to search for.</param>
/// <param name="userName">The user name to search for.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>
/// The <see cref="Task"/> that represents the asynchronous operation, containing the user matching the specified <paramref name="userID"/> if it exists.
@ -1038,7 +1038,7 @@ namespace Microsoft.AspNetCore.Identity
/// <summary>
/// Gets a list of <see cref="Claim"/>s to be belonging to the specified <paramref name="user"/> as an asynchronous operation.
/// </summary>
/// <param name="user">The role whose claims to retrieve.</param>
/// <param name="user">The user whose claims to retrieve.</param>
/// <returns>
/// A <see cref="Task{TResult}"/> that represents the result of the asynchronous query, a list of <see cref="Claim"/>s.
/// </returns>
@ -1071,11 +1071,12 @@ namespace Microsoft.AspNetCore.Identity
throw new ArgumentNullException("user");
}
if (await userRoleStore.IsInRoleAsync(user, role, CancellationToken))
var normalizedRole = NormalizeKey(role);
if (await userRoleStore.IsInRoleAsync(user, normalizedRole, CancellationToken))
{
return await UserAlreadyInRoleError(user, role);
}
await userRoleStore.AddToRoleAsync(user, role, CancellationToken);
await userRoleStore.AddToRoleAsync(user, normalizedRole, CancellationToken);
return await UpdateUserAsync(user);
}
@ -1103,11 +1104,12 @@ namespace Microsoft.AspNetCore.Identity
foreach (var role in roles.Distinct())
{
if (await userRoleStore.IsInRoleAsync(user, role, CancellationToken))
var normalizedRole = NormalizeKey(role);
if (await userRoleStore.IsInRoleAsync(user, normalizedRole, CancellationToken))
{
return await UserAlreadyInRoleError(user, role);
}
await userRoleStore.AddToRoleAsync(user, role, CancellationToken);
await userRoleStore.AddToRoleAsync(user, normalizedRole, CancellationToken);
}
return await UpdateUserAsync(user);
}
@ -1130,11 +1132,12 @@ namespace Microsoft.AspNetCore.Identity
throw new ArgumentNullException("user");
}
if (!await userRoleStore.IsInRoleAsync(user, role, CancellationToken))
var normalizedRole = NormalizeKey(role);
if (!await userRoleStore.IsInRoleAsync(user, normalizedRole, CancellationToken))
{
return await UserNotInRoleError(user, role);
}
await userRoleStore.RemoveFromRoleAsync(user, role, CancellationToken);
await userRoleStore.RemoveFromRoleAsync(user, normalizedRole, CancellationToken);
return await UpdateUserAsync(user);
}
@ -1174,11 +1177,12 @@ namespace Microsoft.AspNetCore.Identity
foreach (var role in roles)
{
if (!await userRoleStore.IsInRoleAsync(user, role, CancellationToken))
var normalizedRole = NormalizeKey(role);
if (!await userRoleStore.IsInRoleAsync(user, normalizedRole, CancellationToken))
{
return await UserNotInRoleError(user, role);
}
await userRoleStore.RemoveFromRoleAsync(user, role, CancellationToken);
await userRoleStore.RemoveFromRoleAsync(user, normalizedRole, CancellationToken);
}
return await UpdateUserAsync(user);
}
@ -1216,7 +1220,7 @@ namespace Microsoft.AspNetCore.Identity
{
throw new ArgumentNullException("user");
}
return await userRoleStore.IsInRoleAsync(user, role, CancellationToken);
return await userRoleStore.IsInRoleAsync(user, NormalizeKey(role), CancellationToken);
}
/// <summary>
@ -1950,7 +1954,7 @@ namespace Microsoft.AspNetCore.Identity
throw new ArgumentNullException("role");
}
return store.GetUsersInRoleAsync(roleName, CancellationToken);
return store.GetUsersInRoleAsync(NormalizeKey(roleName), CancellationToken);
}
/// <summary>

View File

@ -172,12 +172,12 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.SetLockoutEndDateAsync(null, new DateTimeOffset()));
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.ResetAccessFailedCountAsync(null));
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.IncrementAccessFailedCountAsync(null));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.AddToRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.RemoveFromRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.IsInRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.AddToRoleAsync(new IdentityUser("fake"), ""));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.RemoveFromRoleAsync(new IdentityUser("fake"), ""));
await Assert.ThrowsAsync<ArgumentException>("roleName", async () => await store.IsInRoleAsync(new IdentityUser("fake"), ""));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.AddToRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.RemoveFromRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.IsInRoleAsync(new IdentityUser("fake"), null));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.AddToRoleAsync(new IdentityUser("fake"), ""));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.RemoveFromRoleAsync(new IdentityUser("fake"), ""));
await Assert.ThrowsAsync<ArgumentException>("normalizedRoleName", async () => await store.IsInRoleAsync(new IdentityUser("fake"), ""));
}
[ConditionalFact]

View File

@ -257,8 +257,8 @@ namespace Microsoft.AspNetCore.Identity.InMemory
.ConfigureServices(services =>
{
services.AddIdentity<TestUser, TestRole>();
services.AddSingleton<IUserStore<TestUser>, InMemoryUserStore<TestUser>>();
services.AddSingleton<IRoleStore<TestRole>, InMemoryRoleStore<TestRole>>();
services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>();
services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>();
if (configureServices != null)
{
configureServices(services);

View File

@ -37,8 +37,8 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
services.AddLogging();
services.AddSingleton(contextAccessor.Object);
services.AddIdentity<TestUser, TestRole>();
services.AddSingleton<IUserStore<TestUser>, InMemoryUserStore<TestUser>>();
services.AddSingleton<IRoleStore<TestRole>, InMemoryRoleStore<TestRole>>();
services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>();
services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>();
var app = new ApplicationBuilder(services.BuildServiceProvider());
app.UseCookieAuthentication();

View File

@ -1,117 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.Test;
namespace Microsoft.AspNetCore.Identity.InMemory
{
public class InMemoryRoleStore<TRole> : IQueryableRoleStore<TRole>, IRoleClaimStore<TRole> where TRole : TestRole
{
private readonly Dictionary<string, TRole> _roles = new Dictionary<string, TRole>();
public Task<IdentityResult> CreateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
_roles[role.Id] = role;
return Task.FromResult(IdentityResult.Success);
}
public Task<IdentityResult> DeleteAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
if (role == null || !_roles.ContainsKey(role.Id))
{
throw new InvalidOperationException("Unknown role");
}
_roles.Remove(role.Id);
return Task.FromResult(IdentityResult.Success);
}
public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.Id);
}
public Task<string> GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.Name);
}
public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken))
{
role.Name = roleName;
return Task.FromResult(0);
}
public Task<IdentityResult> UpdateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
_roles[role.Id] = role;
return Task.FromResult(IdentityResult.Success);
}
public Task<TRole> FindByIdAsync(string roleId, CancellationToken cancellationToken = default(CancellationToken))
{
if (_roles.ContainsKey(roleId))
{
return Task.FromResult(_roles[roleId]);
}
return Task.FromResult<TRole>(null);
}
public Task<TRole> FindByNameAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))
{
return
Task.FromResult(
Roles.SingleOrDefault(r => String.Equals(r.Name, roleName, StringComparison.OrdinalIgnoreCase)));
}
public void Dispose()
{
}
public Task<IList<Claim>> GetClaimsAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
var claims = role.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList();
return Task.FromResult<IList<Claim>>(claims);
}
public Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))
{
role.Claims.Add(new TestRoleClaim<string> { ClaimType = claim.Type, ClaimValue = claim.Value, RoleId = role.Id });
return Task.FromResult(0);
}
public Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))
{
var entity =
role.Claims.FirstOrDefault(
ur => ur.RoleId == role.Id && ur.ClaimType == claim.Type && ur.ClaimValue == claim.Value);
if (entity != null)
{
role.Claims.Remove(entity);
}
return Task.FromResult(0);
}
public Task<string> GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.NormalizedName);
}
public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken))
{
role.NormalizedName = normalizedName;
return Task.FromResult(0);
}
public IQueryable<TRole> Roles
{
get { return _roles.Values.AsQueryable(); }
}
}
}

View File

@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Identity.Test;
namespace Microsoft.AspNetCore.Identity.InMemory
{
public class InMemoryUserStore<TUser> :
public class InMemoryStore<TUser, TRole> :
IUserLoginStore<TUser>,
IUserRoleStore<TUser>,
IUserClaimStore<TUser>,
@ -21,7 +21,10 @@ namespace Microsoft.AspNetCore.Identity.InMemory
IUserLockoutStore<TUser>,
IUserPhoneNumberStore<TUser>,
IQueryableUserStore<TUser>,
IUserTwoFactorStore<TUser>
IUserTwoFactorStore<TUser>,
IQueryableRoleStore<TRole>,
IRoleClaimStore<TRole>
where TRole : TestRole
where TUser : TestUser
{
private readonly Dictionary<string, TUser> _logins = new Dictionary<string, TUser>();
@ -305,14 +308,19 @@ namespace Microsoft.AspNetCore.Identity.InMemory
// RoleId == roleName for InMemory
public Task AddToRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))
{
user.Roles.Add(new TestUserRole { RoleId = role, UserId = user.Id });
var roleEntity = _roles.Values.SingleOrDefault(r => r.NormalizedName == role);
if (roleEntity != null)
{
user.Roles.Add(new TestUserRole { RoleId = roleEntity.Id, UserId = user.Id });
}
return Task.FromResult(0);
}
// RoleId == roleName for InMemory
public Task RemoveFromRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))
{
var roleEntity = user.Roles.SingleOrDefault(ur => ur.RoleId == role);
var roleObject = _roles.Values.SingleOrDefault(r => r.NormalizedName == role);
var roleEntity = user.Roles.SingleOrDefault(ur => ur.RoleId == roleObject.Id);
if (roleEntity != null)
{
user.Roles.Remove(roleEntity);
@ -322,12 +330,19 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public Task<IList<string>> GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult<IList<string>>(user.Roles.Select(ur => ur.RoleId).ToList());
IList<string> roles = new List<string>();
foreach (var r in user.Roles.Select(ur => ur.RoleId))
{
roles.Add(_roles[r].Name);
}
return Task.FromResult(roles);
}
public Task<bool> IsInRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(user.Roles.Any(ur => ur.RoleId == role));
var roleObject = _roles.Values.SingleOrDefault(r => r.NormalizedName == role);
bool result = roleObject != null && user.Roles.Any(ur => ur.RoleId == roleObject.Id);
return Task.FromResult(result);
}
public Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken = default(CancellationToken))
@ -371,7 +386,12 @@ namespace Microsoft.AspNetCore.Identity.InMemory
throw new ArgumentNullException(nameof(roleName));
}
return Task.FromResult<IList<TUser>>(Users.Where(u => (u.Roles.Where(x => x.RoleId == roleName).Count() > 0)).Select(x => x).ToList());
var role = _roles.Values.Where(x => x.NormalizedName.Equals(roleName)).SingleOrDefault();
if (role == null)
{
return Task.FromResult<IList<TUser>>(new List<TUser>());
}
return Task.FromResult<IList<TUser>>(Users.Where(u => (u.Roles.Where(x => x.RoleId == role.Id).Count() > 0)).Select(x => x).ToList());
}
public Task<IList<TUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken))
@ -387,5 +407,101 @@ namespace Microsoft.AspNetCore.Identity.InMemory
return Task.FromResult<IList<TUser>>(query.ToList());
}
private readonly Dictionary<string, TRole> _roles = new Dictionary<string, TRole>();
public Task<IdentityResult> CreateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
_roles[role.Id] = role;
return Task.FromResult(IdentityResult.Success);
}
public Task<IdentityResult> DeleteAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
if (role == null || !_roles.ContainsKey(role.Id))
{
throw new InvalidOperationException("Unknown role");
}
_roles.Remove(role.Id);
return Task.FromResult(IdentityResult.Success);
}
public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.Id);
}
public Task<string> GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.Name);
}
public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken))
{
role.Name = roleName;
return Task.FromResult(0);
}
public Task<IdentityResult> UpdateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
_roles[role.Id] = role;
return Task.FromResult(IdentityResult.Success);
}
Task<TRole> IRoleStore<TRole>.FindByIdAsync(string roleId, CancellationToken cancellationToken)
{
if (_roles.ContainsKey(roleId))
{
return Task.FromResult(_roles[roleId]);
}
return Task.FromResult<TRole>(null);
}
Task<TRole> IRoleStore<TRole>.FindByNameAsync(string roleName, CancellationToken cancellationToken)
{
return
Task.FromResult(
Roles.SingleOrDefault(r => String.Equals(r.NormalizedName, roleName, StringComparison.OrdinalIgnoreCase)));
}
public Task<IList<Claim>> GetClaimsAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
var claims = role.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList();
return Task.FromResult<IList<Claim>>(claims);
}
public Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))
{
role.Claims.Add(new TestRoleClaim<string> { ClaimType = claim.Type, ClaimValue = claim.Value, RoleId = role.Id });
return Task.FromResult(0);
}
public Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))
{
var entity =
role.Claims.FirstOrDefault(
ur => ur.RoleId == role.Id && ur.ClaimType == claim.Type && ur.ClaimValue == claim.Value);
if (entity != null)
{
role.Claims.Remove(entity);
}
return Task.FromResult(0);
}
public Task<string> GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(role.NormalizedName);
}
public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken))
{
role.NormalizedName = normalizedName;
return Task.FromResult(0);
}
public IQueryable<TRole> Roles
{
get { return _roles.Values.AsQueryable(); }
}
}
}

View File

@ -12,17 +12,17 @@ namespace Microsoft.AspNetCore.Identity.InMemory.Test
{
protected override object CreateTestContext()
{
return null;
return new InMemoryStore<TestUser, TestRole>();
}
protected override void AddUserStore(IServiceCollection services, object context = null)
{
services.AddSingleton<IUserStore<TestUser>, InMemoryUserStore<TestUser>>();
services.AddSingleton<IUserStore<TestUser>>((InMemoryStore<TestUser, TestRole>)context);
}
protected override void AddRoleStore(IServiceCollection services, object context = null)
{
services.AddSingleton<IRoleStore<TestRole>, InMemoryRoleStore<TestRole>>();
services.AddSingleton<IRoleStore<TestRole>>((InMemoryStore<TestUser, TestRole>)context);
}
protected override void SetUserPasswordHash(TestUser user, string hashedPassword)

View File

@ -1467,6 +1467,7 @@ namespace Microsoft.AspNetCore.Identity.Test
{
return;
}
var context = CreateTestContext();
var userManager = CreateManager(context);
var roleManager = CreateRoleManager(context);