added replace claim functionality. fixes #232
- added ReplaceClaimAsync method to IUserClaimStore interface - implemented ReplaceClaimAsync method from IUserClaimStore inside the Microsoft.AspNet.Identity.EntityFramework.UserStore<TUser, TRole, TContext, TKey> - added ReplaceClaimAsync method to UserManager - added UserManager tests for ReplaceClaimAsync method. - added some UserStore tests for ReplaceClaimAsync implementation of IUserClaimStore
This commit is contained in:
parent
0bbd7c8b48
commit
d7f711bca1
|
|
@ -441,6 +441,32 @@ namespace Microsoft.AspNet.Identity.EntityFramework
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 matchedClaims = UserClaims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList();
|
||||||
|
foreach(var matchedClaim in matchedClaims)
|
||||||
|
{
|
||||||
|
matchedClaim.ClaimValue = newClaim.Value;
|
||||||
|
matchedClaim.ClaimType = newClaim.Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,16 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task AddClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken));
|
Task AddClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the give claim information with the given new claim information
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="claim"></param>
|
||||||
|
/// <param name="newClaim"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove a user claim
|
/// Remove a user claim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -946,6 +946,35 @@ namespace Microsoft.AspNet.Identity
|
||||||
return await UpdateAsync(user, cancellationToken);
|
return await UpdateAsync(user, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the give claim information with the given new claim information
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="claim"></param>
|
||||||
|
/// <param name="newClaim"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual async Task<IdentityResult> ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim,
|
||||||
|
CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
ThrowIfDisposed();
|
||||||
|
var claimStore = GetClaimStore();
|
||||||
|
if (claim == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("claim");
|
||||||
|
}
|
||||||
|
if (newClaim == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("newClaim");
|
||||||
|
}
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("user");
|
||||||
|
}
|
||||||
|
await claimStore.ReplaceClaimAsync(user, claim, newClaim, cancellationToken);
|
||||||
|
return await UpdateAsync(user, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove a user claim
|
/// Remove a user claim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,39 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test
|
||||||
return Task.FromResult(0);
|
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>
|
/// <summary>
|
||||||
/// Remove claims from a user
|
/// Remove claims from a user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(
|
await Assert.ThrowsAsync<ObjectDisposedException>(
|
||||||
async () => await store.RemoveFromRoleAsync(null, null));
|
async () => await store.RemoveFromRoleAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.RemoveClaimsAsync(null, null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.RemoveClaimsAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.ReplaceClaimAsync(null, null, null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByLoginAsync(null, null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByLoginAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByIdAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByIdAsync(null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByNameAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByNameAsync(null));
|
||||||
|
|
@ -199,6 +200,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.UpdateAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.UpdateAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.DeleteAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.DeleteAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.AddClaimsAsync(null, null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.AddClaimsAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.ReplaceClaimAsync(null, null, null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.RemoveClaimsAsync(null, null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.RemoveClaimsAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetClaimsAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetClaimsAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetLoginsAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetLoginsAsync(null));
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,17 @@ namespace Microsoft.AspNet.Identity.InMemory
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
matchedClaim.ClaimValue = newClaim.Value;
|
||||||
|
matchedClaim.ClaimType = newClaim.Type;
|
||||||
|
}
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
public Task RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
foreach (var claim in claims)
|
foreach (var claim in claims)
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,27 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
store.VerifyAll();
|
store.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateClaimCallsStore()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
var store = new Mock<IUserClaimStore<TestUser>>();
|
||||||
|
var user = new TestUser { UserName = "Foo" };
|
||||||
|
var claim = new Claim("1", "1");
|
||||||
|
var newClaim = new Claim("1", "2");
|
||||||
|
store.Setup(s => s.ReplaceClaimAsync(user, It.IsAny<Claim>(), It.IsAny<Claim>(), CancellationToken.None))
|
||||||
|
.Returns(Task.FromResult(0))
|
||||||
|
.Verifiable();
|
||||||
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await userManager.ReplaceClaimAsync(user, claim, newClaim);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result.Succeeded);
|
||||||
|
store.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RemoveClaimsCallsStore()
|
public async Task RemoveClaimsCallsStore()
|
||||||
{
|
{
|
||||||
|
|
@ -455,6 +476,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserClaim);
|
Assert.False(manager.SupportsUserClaim);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddClaimAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddClaimAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.ReplaceClaimAsync(null, null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveClaimAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveClaimAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetClaimsAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetClaimsAsync(null));
|
||||||
}
|
}
|
||||||
|
|
@ -541,6 +563,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.UpdateAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.UpdateAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.DeleteAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.DeleteAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.AddClaimAsync(null, null));
|
await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.AddClaimAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.ReplaceClaimAsync(null, null, null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("claims", async () => await manager.AddClaimsAsync(null, null));
|
await Assert.ThrowsAsync<ArgumentNullException>("claims", async () => await manager.AddClaimsAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByNameAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByNameAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByUserNamePasswordAsync(null, null));
|
await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByUserNamePasswordAsync(null, null));
|
||||||
|
|
@ -594,6 +617,8 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
async () => await manager.RemoveFromRoleAsync(null, null));
|
async () => await manager.RemoveFromRoleAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
async () => await manager.RemoveFromRolesAsync(null, null));
|
async () => await manager.RemoveFromRolesAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
|
async () => await manager.ReplaceClaimAsync(null, new Claim("a", "b"), new Claim("a", "c")));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
async () => await manager.UpdateSecurityStampAsync(null));
|
async () => await manager.UpdateSecurityStampAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
|
|
@ -690,6 +715,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.CreateAsync(null, null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.CreateAsync(null, null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateAsync(null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.DeleteAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.DeleteAsync(null));
|
||||||
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ReplaceClaimAsync(null, null, null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateSecurityStampAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateSecurityStampAsync(null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetSecurityStampAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetSecurityStampAsync(null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GeneratePasswordResetTokenAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GeneratePasswordResetTokenAsync(null));
|
||||||
|
|
@ -730,6 +756,11 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task ReplaceClaimAsync(TestUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveClaimsAsync(TestUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken))
|
public Task RemoveClaimsAsync(TestUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
|
|
@ -991,6 +1022,11 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task ReplaceClaimAsync(TestUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveClaimsAsync(TestUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
public Task RemoveClaimsAsync(TestUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,25 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
Assert.Equal(0, userClaims.Count);
|
Assert.Equal(0, userClaims.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanReplaceUserClaim()
|
||||||
|
{
|
||||||
|
var manager = CreateManager();
|
||||||
|
var user = CreateTestUser();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(user, new Claim("c", "a")));
|
||||||
|
var userClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, userClaims.Count);
|
||||||
|
Claim claim = new Claim("c", "b");
|
||||||
|
Claim oldClaim = userClaims.FirstOrDefault();
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.ReplaceClaimAsync(user, oldClaim, claim));
|
||||||
|
var newUserClaims = await manager.GetClaimsAsync(user);
|
||||||
|
Assert.Equal(1, newUserClaims.Count);
|
||||||
|
Claim newClaim = newUserClaims.FirstOrDefault();
|
||||||
|
Assert.Equal(claim.Type, newClaim.Type);
|
||||||
|
Assert.Equal(claim.Value, newClaim.Value);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ChangePasswordFallsIfPasswordWrong()
|
public async Task ChangePasswordFallsIfPasswordWrong()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue