1 // Copyright (c) .NET Foundation. All rights reserved. 2 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Security.Claims; 8 using System.Threading; 9 using System.Threading.Tasks; 10 using Microsoft.AspNetCore.Http; 11 using Microsoft.Extensions.Configuration; 12 using Microsoft.Extensions.DependencyInjection; 13 using Moq; 14 using Xunit; 15 16 namespace Microsoft.AspNetCore.Identity.Test 17 { 18 public class UserManagerTest 19 { 20 [Fact] EnsureDefaultServicesDefaultsWithStoreWorks()21 public void EnsureDefaultServicesDefaultsWithStoreWorks() 22 { 23 var config = new ConfigurationBuilder().Build(); 24 var services = new ServiceCollection() 25 .AddSingleton<IConfiguration>(config) 26 .AddTransient<IUserStore<PocoUser>, NoopUserStore>(); 27 services.AddIdentity<PocoUser, PocoRole>(); 28 services.AddHttpContextAccessor(); 29 services.AddLogging(); 30 var manager = services.BuildServiceProvider().GetRequiredService<UserManager<PocoUser>>(); 31 Assert.NotNull(manager.PasswordHasher); 32 Assert.NotNull(manager.Options); 33 } 34 35 [Fact] AddUserManagerWithCustomManagerReturnsSameInstance()36 public void AddUserManagerWithCustomManagerReturnsSameInstance() 37 { 38 var config = new ConfigurationBuilder().Build(); 39 var services = new ServiceCollection() 40 .AddSingleton<IConfiguration>(config) 41 .AddTransient<IUserStore<PocoUser>, NoopUserStore>() 42 .AddHttpContextAccessor(); 43 44 services.AddLogging(); 45 46 services.AddIdentity<PocoUser, PocoRole>() 47 .AddUserManager<CustomUserManager>() 48 .AddRoleManager<CustomRoleManager>(); 49 var provider = services.BuildServiceProvider(); 50 Assert.Same(provider.GetRequiredService<UserManager<PocoUser>>(), 51 provider.GetRequiredService<CustomUserManager>()); 52 Assert.Same(provider.GetRequiredService<RoleManager<PocoRole>>(), 53 provider.GetRequiredService<CustomRoleManager>()); 54 } 55 56 public class CustomUserManager : UserManager<PocoUser> 57 { CustomUserManager()58 public CustomUserManager() : base(new Mock<IUserStore<PocoUser>>().Object, null, null, null, null, null, null, null, null) 59 { } 60 } 61 62 public class CustomRoleManager : RoleManager<PocoRole> 63 { CustomRoleManager()64 public CustomRoleManager() : base(new Mock<IRoleStore<PocoRole>>().Object, null, null, null, null) 65 { } 66 } 67 68 [Fact] CreateCallsStore()69 public async Task CreateCallsStore() 70 { 71 // Setup 72 var store = new Mock<IUserStore<PocoUser>>(); 73 var user = new PocoUser { UserName = "Foo" }; 74 store.Setup(s => s.CreateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 75 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.UserName)).Verifiable(); 76 store.Setup(s => s.SetNormalizedUserNameAsync(user, user.UserName.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 77 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 78 79 // Act 80 var result = await userManager.CreateAsync(user); 81 82 // Assert 83 Assert.True(result.Succeeded); 84 store.VerifyAll(); 85 } 86 87 [Fact] CreateCallsUpdateEmailStore()88 public async Task CreateCallsUpdateEmailStore() 89 { 90 // Setup 91 var store = new Mock<IUserEmailStore<PocoUser>>(); 92 var user = new PocoUser { UserName = "Foo", Email = "Foo@foo.com" }; 93 store.Setup(s => s.CreateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 94 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.UserName)).Verifiable(); 95 store.Setup(s => s.GetEmailAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.Email)).Verifiable(); 96 store.Setup(s => s.SetNormalizedEmailAsync(user, user.Email.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 97 store.Setup(s => s.SetNormalizedUserNameAsync(user, user.UserName.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 98 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 99 100 // Act 101 var result = await userManager.CreateAsync(user); 102 103 // Assert 104 Assert.True(result.Succeeded); 105 store.VerifyAll(); 106 } 107 108 [Fact] DeleteCallsStore()109 public async Task DeleteCallsStore() 110 { 111 // Setup 112 var store = new Mock<IUserStore<PocoUser>>(); 113 var user = new PocoUser { UserName = "Foo" }; 114 store.Setup(s => s.DeleteAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 115 var userManager = MockHelpers.TestUserManager(store.Object); 116 117 // Act 118 var result = await userManager.DeleteAsync(user); 119 120 // Assert 121 Assert.True(result.Succeeded); 122 store.VerifyAll(); 123 } 124 125 [Fact] UpdateCallsStore()126 public async Task UpdateCallsStore() 127 { 128 // Setup 129 var store = new Mock<IUserStore<PocoUser>>(); 130 var user = new PocoUser { UserName = "Foo" }; 131 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.UserName)).Verifiable(); 132 store.Setup(s => s.SetNormalizedUserNameAsync(user, user.UserName.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 133 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 134 var userManager = MockHelpers.TestUserManager(store.Object); 135 136 // Act 137 var result = await userManager.UpdateAsync(user); 138 139 // Assert 140 Assert.True(result.Succeeded); 141 store.VerifyAll(); 142 } 143 144 [Fact] UpdateWillUpdateNormalizedEmail()145 public async Task UpdateWillUpdateNormalizedEmail() 146 { 147 // Setup 148 var store = new Mock<IUserEmailStore<PocoUser>>(); 149 var user = new PocoUser { UserName = "Foo", Email = "email" }; 150 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.UserName)).Verifiable(); 151 store.Setup(s => s.GetEmailAsync(user, CancellationToken.None)).Returns(Task.FromResult(user.Email)).Verifiable(); 152 store.Setup(s => s.SetNormalizedUserNameAsync(user, user.UserName.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 153 store.Setup(s => s.SetNormalizedEmailAsync(user, user.Email.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 154 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 155 var userManager = MockHelpers.TestUserManager(store.Object); 156 157 // Act 158 var result = await userManager.UpdateAsync(user); 159 160 // Assert 161 Assert.True(result.Succeeded); 162 store.VerifyAll(); 163 } 164 165 [Fact] SetUserNameCallsStore()166 public async Task SetUserNameCallsStore() 167 { 168 // Setup 169 var store = new Mock<IUserStore<PocoUser>>(); 170 var user = new PocoUser(); 171 store.Setup(s => s.SetUserNameAsync(user, "foo", CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 172 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).Returns(Task.FromResult("foo")).Verifiable(); 173 store.Setup(s => s.SetNormalizedUserNameAsync(user, "FOO", CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 174 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable(); 175 var userManager = MockHelpers.TestUserManager(store.Object); 176 177 // Act 178 var result = await userManager.SetUserNameAsync(user, "foo"); 179 180 // Assert 181 Assert.True(result.Succeeded); 182 store.VerifyAll(); 183 } 184 185 [Fact] FindByIdCallsStore()186 public async Task FindByIdCallsStore() 187 { 188 // Setup 189 var store = new Mock<IUserStore<PocoUser>>(); 190 var user = new PocoUser { UserName = "Foo" }; 191 store.Setup(s => s.FindByIdAsync(user.Id, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable(); 192 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 193 194 // Act 195 var result = await userManager.FindByIdAsync(user.Id); 196 197 // Assert 198 Assert.Equal(user, result); 199 store.VerifyAll(); 200 } 201 202 [Fact] FindByNameCallsStoreWithNormalizedName()203 public async Task FindByNameCallsStoreWithNormalizedName() 204 { 205 // Setup 206 var store = new Mock<IUserStore<PocoUser>>(); 207 var user = new PocoUser { UserName = "Foo" }; 208 store.Setup(s => s.FindByNameAsync(user.UserName.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable(); 209 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 210 211 // Act 212 var result = await userManager.FindByNameAsync(user.UserName); 213 214 // Assert 215 Assert.Equal(user, result); 216 store.VerifyAll(); 217 } 218 219 [Fact] CanFindByNameCallsStoreWithoutNormalizedName()220 public async Task CanFindByNameCallsStoreWithoutNormalizedName() 221 { 222 // Setup 223 var store = new Mock<IUserStore<PocoUser>>(); 224 var user = new PocoUser { UserName = "Foo" }; 225 store.Setup(s => s.FindByNameAsync(user.UserName, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable(); 226 var userManager = MockHelpers.TestUserManager(store.Object); 227 userManager.KeyNormalizer = null; 228 229 // Act 230 var result = await userManager.FindByNameAsync(user.UserName); 231 232 // Assert 233 Assert.Equal(user, result); 234 store.VerifyAll(); 235 } 236 237 [Fact] FindByEmailCallsStoreWithNormalizedEmail()238 public async Task FindByEmailCallsStoreWithNormalizedEmail() 239 { 240 // Setup 241 var store = new Mock<IUserEmailStore<PocoUser>>(); 242 var user = new PocoUser { Email = "Foo" }; 243 store.Setup(s => s.FindByEmailAsync(user.Email.ToUpperInvariant(), CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable(); 244 var userManager = MockHelpers.TestUserManager(store.Object); 245 246 // Act 247 var result = await userManager.FindByEmailAsync(user.Email); 248 249 // Assert 250 Assert.Equal(user, result); 251 store.VerifyAll(); 252 } 253 254 [Fact] CanFindByEmailCallsStoreWithoutNormalizedEmail()255 public async Task CanFindByEmailCallsStoreWithoutNormalizedEmail() 256 { 257 // Setup 258 var store = new Mock<IUserEmailStore<PocoUser>>(); 259 var user = new PocoUser { Email = "Foo" }; 260 store.Setup(s => s.FindByEmailAsync(user.Email, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable(); 261 var userManager = MockHelpers.TestUserManager(store.Object); 262 userManager.KeyNormalizer = null; 263 264 // Act 265 var result = await userManager.FindByEmailAsync(user.Email); 266 267 // Assert 268 Assert.Equal(user, result); 269 store.VerifyAll(); 270 } 271 272 [Fact] AddToRolesCallsStore()273 public async Task AddToRolesCallsStore() 274 { 275 // Setup 276 var store = new Mock<IUserRoleStore<PocoUser>>(); 277 var user = new PocoUser { UserName = "Foo" }; 278 var roles = new string[] { "A", "B", "C", "C" }; 279 store.Setup(s => s.AddToRoleAsync(user, "A", CancellationToken.None)) 280 .Returns(Task.FromResult(0)) 281 .Verifiable(); 282 store.Setup(s => s.AddToRoleAsync(user, "B", CancellationToken.None)) 283 .Returns(Task.FromResult(0)) 284 .Verifiable(); 285 store.Setup(s => s.AddToRoleAsync(user, "C", CancellationToken.None)) 286 .Returns(Task.FromResult(0)) 287 .Verifiable(); 288 289 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 290 store.Setup(s => s.IsInRoleAsync(user, "A", CancellationToken.None)) 291 .Returns(Task.FromResult(false)) 292 .Verifiable(); 293 store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None)) 294 .Returns(Task.FromResult(false)) 295 .Verifiable(); 296 store.Setup(s => s.IsInRoleAsync(user, "C", CancellationToken.None)) 297 .Returns(Task.FromResult(false)) 298 .Verifiable(); 299 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 300 301 // Act 302 var result = await userManager.AddToRolesAsync(user, roles); 303 304 // Assert 305 Assert.True(result.Succeeded); 306 store.VerifyAll(); 307 store.Verify(s => s.AddToRoleAsync(user, "C", CancellationToken.None), Times.Once()); 308 } 309 310 [Fact] AddToRolesFailsIfUserInRole()311 public async Task AddToRolesFailsIfUserInRole() 312 { 313 // Setup 314 var store = new Mock<IUserRoleStore<PocoUser>>(); 315 var user = new PocoUser { UserName = "Foo" }; 316 var roles = new[] { "A", "B", "C" }; 317 store.Setup(s => s.AddToRoleAsync(user, "A", CancellationToken.None)) 318 .Returns(Task.FromResult(0)) 319 .Verifiable(); 320 store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None)) 321 .Returns(Task.FromResult(true)) 322 .Verifiable(); 323 var userManager = MockHelpers.TestUserManager(store.Object); 324 325 // Act 326 var result = await userManager.AddToRolesAsync(user, roles); 327 328 // Assert 329 IdentityResultAssert.IsFailure(result, new IdentityErrorDescriber().UserAlreadyInRole("B")); 330 store.VerifyAll(); 331 } 332 333 [Fact] RemoveFromRolesCallsStore()334 public async Task RemoveFromRolesCallsStore() 335 { 336 // Setup 337 var store = new Mock<IUserRoleStore<PocoUser>>(); 338 var user = new PocoUser { UserName = "Foo" }; 339 var roles = new[] { "A", "B", "C" }; 340 store.Setup(s => s.RemoveFromRoleAsync(user, "A", CancellationToken.None)) 341 .Returns(Task.FromResult(0)) 342 .Verifiable(); 343 store.Setup(s => s.RemoveFromRoleAsync(user, "B", CancellationToken.None)) 344 .Returns(Task.FromResult(0)) 345 .Verifiable(); 346 store.Setup(s => s.RemoveFromRoleAsync(user, "C", CancellationToken.None)) 347 .Returns(Task.FromResult(0)) 348 .Verifiable(); 349 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 350 store.Setup(s => s.IsInRoleAsync(user, "A", CancellationToken.None)) 351 .Returns(Task.FromResult(true)) 352 .Verifiable(); 353 store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None)) 354 .Returns(Task.FromResult(true)) 355 .Verifiable(); 356 store.Setup(s => s.IsInRoleAsync(user, "C", CancellationToken.None)) 357 .Returns(Task.FromResult(true)) 358 .Verifiable(); 359 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 360 361 // Act 362 var result = await userManager.RemoveFromRolesAsync(user, roles); 363 364 // Assert 365 Assert.True(result.Succeeded); 366 store.VerifyAll(); 367 } 368 369 [Fact] RemoveFromRolesFailsIfNotInRole()370 public async Task RemoveFromRolesFailsIfNotInRole() 371 { 372 // Setup 373 var store = new Mock<IUserRoleStore<PocoUser>>(); 374 var user = new PocoUser { UserName = "Foo" }; 375 var roles = new string[] { "A", "B", "C" }; 376 store.Setup(s => s.RemoveFromRoleAsync(user, "A", CancellationToken.None)) 377 .Returns(Task.FromResult(0)) 378 .Verifiable(); 379 store.Setup(s => s.IsInRoleAsync(user, "A", CancellationToken.None)) 380 .Returns(Task.FromResult(true)) 381 .Verifiable(); 382 store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None)) 383 .Returns(Task.FromResult(false)) 384 .Verifiable(); 385 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 386 387 // Act 388 var result = await userManager.RemoveFromRolesAsync(user, roles); 389 390 // Assert 391 IdentityResultAssert.IsFailure(result, new IdentityErrorDescriber().UserNotInRole("B")); 392 store.VerifyAll(); 393 } 394 395 [Fact] AddClaimsCallsStore()396 public async Task AddClaimsCallsStore() 397 { 398 // Setup 399 var store = new Mock<IUserClaimStore<PocoUser>>(); 400 var user = new PocoUser { UserName = "Foo" }; 401 var claims = new Claim[] { new Claim("1", "1"), new Claim("2", "2"), new Claim("3", "3") }; 402 store.Setup(s => s.AddClaimsAsync(user, claims, CancellationToken.None)) 403 .Returns(Task.FromResult(0)) 404 .Verifiable(); 405 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 406 var userManager = MockHelpers.TestUserManager(store.Object); 407 408 // Act 409 var result = await userManager.AddClaimsAsync(user, claims); 410 411 // Assert 412 Assert.True(result.Succeeded); 413 store.VerifyAll(); 414 } 415 416 [Fact] AddClaimCallsStore()417 public async Task AddClaimCallsStore() 418 { 419 // Setup 420 var store = new Mock<IUserClaimStore<PocoUser>>(); 421 var user = new PocoUser { UserName = "Foo" }; 422 var claim = new Claim("1", "1"); 423 store.Setup(s => s.AddClaimsAsync(user, It.IsAny<IEnumerable<Claim>>(), CancellationToken.None)) 424 .Returns(Task.FromResult(0)) 425 .Verifiable(); 426 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 427 var userManager = MockHelpers.TestUserManager(store.Object); 428 429 // Act 430 var result = await userManager.AddClaimAsync(user, claim); 431 432 // Assert 433 Assert.True(result.Succeeded); 434 store.VerifyAll(); 435 } 436 437 [Fact] UpdateClaimCallsStore()438 public async Task UpdateClaimCallsStore() 439 { 440 // Setup 441 var store = new Mock<IUserClaimStore<PocoUser>>(); 442 var user = new PocoUser { UserName = "Foo" }; 443 var claim = new Claim("1", "1"); 444 var newClaim = new Claim("1", "2"); 445 store.Setup(s => s.ReplaceClaimAsync(user, It.IsAny<Claim>(), It.IsAny<Claim>(), CancellationToken.None)) 446 .Returns(Task.FromResult(0)) 447 .Verifiable(); 448 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable(); 449 var userManager = MockHelpers.TestUserManager(store.Object); 450 451 // Act 452 var result = await userManager.ReplaceClaimAsync(user, claim, newClaim); 453 454 // Assert 455 Assert.True(result.Succeeded); 456 store.VerifyAll(); 457 } 458 459 [Fact] CheckPasswordWillRehashPasswordWhenNeeded()460 public async Task CheckPasswordWillRehashPasswordWhenNeeded() 461 { 462 // Setup 463 var store = new Mock<IUserPasswordStore<PocoUser>>(); 464 var hasher = new Mock<IPasswordHasher<PocoUser>>(); 465 var user = new PocoUser { UserName = "Foo" }; 466 var pwd = "password"; 467 var hashed = "hashed"; 468 var rehashed = "rehashed"; 469 470 store.Setup(s => s.GetPasswordHashAsync(user, CancellationToken.None)) 471 .ReturnsAsync(hashed) 472 .Verifiable(); 473 store.Setup(s => s.SetPasswordHashAsync(user, It.IsAny<string>(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable(); 474 store.Setup(x => x.UpdateAsync(It.IsAny<PocoUser>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(IdentityResult.Success)); 475 476 hasher.Setup(s => s.VerifyHashedPassword(user, hashed, pwd)).Returns(PasswordVerificationResult.SuccessRehashNeeded).Verifiable(); 477 hasher.Setup(s => s.HashPassword(user, pwd)).Returns(rehashed).Verifiable(); 478 var userManager = MockHelpers.TestUserManager(store.Object); 479 userManager.PasswordHasher = hasher.Object; 480 481 // Act 482 var result = await userManager.CheckPasswordAsync(user, pwd); 483 484 // Assert 485 Assert.True(result); 486 store.VerifyAll(); 487 hasher.VerifyAll(); 488 } 489 490 [Fact] CreateFailsWithNullSecurityStamp()491 public async Task CreateFailsWithNullSecurityStamp() 492 { 493 // Setup 494 var store = new Mock<IUserSecurityStampStore<PocoUser>>(); 495 var manager = MockHelpers.TestUserManager(store.Object); 496 var user = new PocoUser { UserName = "nulldude" }; 497 store.Setup(s => s.GetSecurityStampAsync(user, It.IsAny<CancellationToken>())).ReturnsAsync(default(string)).Verifiable(); 498 499 // Act 500 // Assert 501 var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => manager.CreateAsync(user)); 502 Assert.Contains(Extensions.Identity.Core.Resources.NullSecurityStamp, ex.Message); 503 504 store.VerifyAll(); 505 } 506 507 [Fact] UpdateFailsWithNullSecurityStamp()508 public async Task UpdateFailsWithNullSecurityStamp() 509 { 510 // Setup 511 var store = new Mock<IUserSecurityStampStore<PocoUser>>(); 512 var manager = MockHelpers.TestUserManager(store.Object); 513 var user = new PocoUser { UserName = "nulldude" }; 514 store.Setup(s => s.GetSecurityStampAsync(user, It.IsAny<CancellationToken>())).ReturnsAsync(default(string)).Verifiable(); 515 516 // Act 517 // Assert 518 var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => manager.UpdateAsync(user)); 519 Assert.Contains(Extensions.Identity.Core.Resources.NullSecurityStamp, ex.Message); 520 521 store.VerifyAll(); 522 } 523 524 525 526 [Fact] RemoveClaimsCallsStore()527 public async Task RemoveClaimsCallsStore() 528 { 529 // Setup 530 var store = new Mock<IUserClaimStore<PocoUser>>(); 531 var user = new PocoUser { UserName = "Foo" }; 532 var claims = new Claim[] { new Claim("1", "1"), new Claim("2", "2"), new Claim("3", "3") }; 533 store.Setup(s => s.RemoveClaimsAsync(user, claims, CancellationToken.None)) 534 .Returns(Task.FromResult(0)) 535 .Verifiable(); 536 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 537 var userManager = MockHelpers.TestUserManager(store.Object); 538 539 // Act 540 var result = await userManager.RemoveClaimsAsync(user, claims); 541 542 // Assert 543 Assert.True(result.Succeeded); 544 store.VerifyAll(); 545 } 546 547 [Fact] RemoveClaimCallsStore()548 public async Task RemoveClaimCallsStore() 549 { 550 // Setup 551 var store = new Mock<IUserClaimStore<PocoUser>>(); 552 var user = new PocoUser { UserName = "Foo" }; 553 var claim = new Claim("1", "1"); 554 store.Setup(s => s.RemoveClaimsAsync(user, It.IsAny<IEnumerable<Claim>>(), CancellationToken.None)) 555 .Returns(Task.FromResult(0)) 556 .Verifiable(); 557 store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).ReturnsAsync(IdentityResult.Success).Verifiable(); 558 var userManager = MockHelpers.TestUserManager<PocoUser>(store.Object); 559 560 // Act 561 var result = await userManager.RemoveClaimAsync(user, claim); 562 563 // Assert 564 Assert.True(result.Succeeded); 565 store.VerifyAll(); 566 } 567 568 [Fact] CheckPasswordWithNullUserReturnsFalse()569 public async Task CheckPasswordWithNullUserReturnsFalse() 570 { 571 var manager = MockHelpers.TestUserManager(new EmptyStore()); 572 Assert.False(await manager.CheckPasswordAsync(null, "whatevs")); 573 } 574 575 [Fact] UsersQueryableFailWhenStoreNotImplemented()576 public void UsersQueryableFailWhenStoreNotImplemented() 577 { 578 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 579 Assert.False(manager.SupportsQueryableUsers); 580 Assert.Throws<NotSupportedException>(() => manager.Users.Count()); 581 } 582 583 [Fact] UsersEmailMethodsFailWhenStoreNotImplemented()584 public async Task UsersEmailMethodsFailWhenStoreNotImplemented() 585 { 586 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 587 Assert.False(manager.SupportsUserEmail); 588 await Assert.ThrowsAsync<NotSupportedException>(() => manager.FindByEmailAsync(null)); 589 await Assert.ThrowsAsync<NotSupportedException>(() => manager.SetEmailAsync(null, null)); 590 await Assert.ThrowsAsync<NotSupportedException>(() => manager.GetEmailAsync(null)); 591 await Assert.ThrowsAsync<NotSupportedException>(() => manager.IsEmailConfirmedAsync(null)); 592 await Assert.ThrowsAsync<NotSupportedException>(() => manager.ConfirmEmailAsync(null, null)); 593 } 594 595 [Fact] UsersPhoneNumberMethodsFailWhenStoreNotImplemented()596 public async Task UsersPhoneNumberMethodsFailWhenStoreNotImplemented() 597 { 598 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 599 Assert.False(manager.SupportsUserPhoneNumber); 600 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null)); 601 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null)); 602 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetPhoneNumberAsync(null)); 603 } 604 605 [Fact] TokenMethodsThrowWithNoTokenProvider()606 public async Task TokenMethodsThrowWithNoTokenProvider() 607 { 608 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 609 var user = new PocoUser(); 610 await Assert.ThrowsAsync<NotSupportedException>( 611 async () => await manager.GenerateUserTokenAsync(user, "bogus", null)); 612 await Assert.ThrowsAsync<NotSupportedException>( 613 async () => await manager.VerifyUserTokenAsync(user, "bogus", null, null)); 614 } 615 616 [Fact] PasswordMethodsFailWhenStoreNotImplemented()617 public async Task PasswordMethodsFailWhenStoreNotImplemented() 618 { 619 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 620 Assert.False(manager.SupportsUserPassword); 621 await Assert.ThrowsAsync<NotSupportedException>(() => manager.CreateAsync(null, null)); 622 await Assert.ThrowsAsync<NotSupportedException>(() => manager.ChangePasswordAsync(null, null, null)); 623 await Assert.ThrowsAsync<NotSupportedException>(() => manager.AddPasswordAsync(null, null)); 624 await Assert.ThrowsAsync<NotSupportedException>(() => manager.RemovePasswordAsync(null)); 625 await Assert.ThrowsAsync<NotSupportedException>(() => manager.CheckPasswordAsync(null, null)); 626 await Assert.ThrowsAsync<NotSupportedException>(() => manager.HasPasswordAsync(null)); 627 } 628 629 [Fact] SecurityStampMethodsFailWhenStoreNotImplemented()630 public async Task SecurityStampMethodsFailWhenStoreNotImplemented() 631 { 632 var store = new Mock<IUserStore<PocoUser>>(); 633 store.Setup(x => x.GetUserIdAsync(It.IsAny<PocoUser>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(Guid.NewGuid().ToString())); 634 var manager = MockHelpers.TestUserManager(store.Object); 635 Assert.False(manager.SupportsUserSecurityStamp); 636 await Assert.ThrowsAsync<NotSupportedException>(() => manager.UpdateSecurityStampAsync(null)); 637 await Assert.ThrowsAsync<NotSupportedException>(() => manager.GetSecurityStampAsync(null)); 638 await Assert.ThrowsAsync<NotSupportedException>( 639 () => manager.VerifyChangePhoneNumberTokenAsync(new PocoUser(), "1", "111-111-1111")); 640 await Assert.ThrowsAsync<NotSupportedException>( 641 () => manager.GenerateChangePhoneNumberTokenAsync(new PocoUser(), "111-111-1111")); 642 } 643 644 [Fact] LoginMethodsFailWhenStoreNotImplemented()645 public async Task LoginMethodsFailWhenStoreNotImplemented() 646 { 647 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 648 Assert.False(manager.SupportsUserLogin); 649 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddLoginAsync(null, null)); 650 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveLoginAsync(null, null, null)); 651 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetLoginsAsync(null)); 652 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.FindByLoginAsync(null, null)); 653 } 654 655 [Fact] ClaimMethodsFailWhenStoreNotImplemented()656 public async Task ClaimMethodsFailWhenStoreNotImplemented() 657 { 658 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 659 Assert.False(manager.SupportsUserClaim); 660 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddClaimAsync(null, null)); 661 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.ReplaceClaimAsync(null, null, null)); 662 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveClaimAsync(null, null)); 663 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetClaimsAsync(null)); 664 } 665 666 private class ATokenProvider : IUserTwoFactorTokenProvider<PocoUser> 667 { CanGenerateTwoFactorTokenAsync(UserManager<PocoUser> manager, PocoUser user)668 public Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<PocoUser> manager, PocoUser user) 669 { 670 throw new NotImplementedException(); 671 } 672 GenerateAsync(string purpose, UserManager<PocoUser> manager, PocoUser user)673 public Task<string> GenerateAsync(string purpose, UserManager<PocoUser> manager, PocoUser user) 674 { 675 throw new NotImplementedException(); 676 } 677 ValidateAsync(string purpose, string token, UserManager<PocoUser> manager, PocoUser user)678 public Task<bool> ValidateAsync(string purpose, string token, UserManager<PocoUser> manager, PocoUser user) 679 { 680 throw new NotImplementedException(); 681 } 682 } 683 684 [Fact] UserManagerWillUseTokenProviderInstance()685 public void UserManagerWillUseTokenProviderInstance() 686 { 687 var provider = new ATokenProvider(); 688 var config = new ConfigurationBuilder().Build(); 689 var services = new ServiceCollection() 690 .AddSingleton<IConfiguration>(config) 691 .AddLogging(); 692 693 services.AddIdentity<PocoUser, PocoRole>(o => o.Tokens.ProviderMap.Add("A", new TokenProviderDescriptor(typeof(ATokenProvider)) 694 { 695 ProviderInstance = provider 696 })).AddUserStore<NoopUserStore>(); 697 var manager = services.BuildServiceProvider().GetService<UserManager<PocoUser>>(); 698 Assert.ThrowsAsync<NotImplementedException>(() => manager.GenerateUserTokenAsync(new PocoUser(), "A", "purpose")); 699 } 700 701 [Fact] UserManagerThrowsIfStoreDoesNotSupportProtection()702 public void UserManagerThrowsIfStoreDoesNotSupportProtection() 703 { 704 var services = new ServiceCollection() 705 .AddLogging(); 706 services.AddIdentity<PocoUser, PocoRole>(o => o.Stores.ProtectPersonalData = true) 707 .AddUserStore<NoopUserStore>(); 708 var e = Assert.Throws<InvalidOperationException>(() => services.BuildServiceProvider().GetService<UserManager<PocoUser>>()); 709 Assert.Contains("Store does not implement IProtectedUserStore", e.Message); 710 } 711 712 [Fact] UserManagerThrowsIfMissingPersonalDataProtection()713 public void UserManagerThrowsIfMissingPersonalDataProtection() 714 { 715 var services = new ServiceCollection() 716 .AddLogging(); 717 services.AddIdentity<PocoUser, PocoRole>(o => o.Stores.ProtectPersonalData = true) 718 .AddUserStore<ProtectedStore>(); 719 var e = Assert.Throws<InvalidOperationException>(() => services.BuildServiceProvider().GetService<UserManager<PocoUser>>()); 720 Assert.Contains("No IPersonalDataProtector service was registered", e.Message); 721 } 722 723 private class ProtectedStore : IProtectedUserStore<PocoUser> 724 { CreateAsync(PocoUser user, CancellationToken cancellationToken)725 public Task<IdentityResult> CreateAsync(PocoUser user, CancellationToken cancellationToken) 726 { 727 throw new NotImplementedException(); 728 } 729 DeleteAsync(PocoUser user, CancellationToken cancellationToken)730 public Task<IdentityResult> DeleteAsync(PocoUser user, CancellationToken cancellationToken) 731 { 732 throw new NotImplementedException(); 733 } 734 Dispose()735 public void Dispose() 736 { 737 throw new NotImplementedException(); 738 } 739 FindByIdAsync(string userId, CancellationToken cancellationToken)740 public Task<PocoUser> FindByIdAsync(string userId, CancellationToken cancellationToken) 741 { 742 throw new NotImplementedException(); 743 } 744 FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)745 public Task<PocoUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken) 746 { 747 throw new NotImplementedException(); 748 } 749 GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken)750 public Task<string> GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken) 751 { 752 throw new NotImplementedException(); 753 } 754 GetUserIdAsync(PocoUser user, CancellationToken cancellationToken)755 public Task<string> GetUserIdAsync(PocoUser user, CancellationToken cancellationToken) 756 { 757 throw new NotImplementedException(); 758 } 759 GetUserNameAsync(PocoUser user, CancellationToken cancellationToken)760 public Task<string> GetUserNameAsync(PocoUser user, CancellationToken cancellationToken) 761 { 762 throw new NotImplementedException(); 763 } 764 SetNormalizedUserNameAsync(PocoUser user, string normalizedName, CancellationToken cancellationToken)765 public Task SetNormalizedUserNameAsync(PocoUser user, string normalizedName, CancellationToken cancellationToken) 766 { 767 throw new NotImplementedException(); 768 } 769 SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken)770 public Task SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken) 771 { 772 throw new NotImplementedException(); 773 } 774 UpdateAsync(PocoUser user, CancellationToken cancellationToken)775 public Task<IdentityResult> UpdateAsync(PocoUser user, CancellationToken cancellationToken) 776 { 777 throw new NotImplementedException(); 778 } 779 } 780 781 [Fact] UserManagerWillUseTokenProviderInstanceOverDefaults()782 public void UserManagerWillUseTokenProviderInstanceOverDefaults() 783 { 784 var provider = new ATokenProvider(); 785 var config = new ConfigurationBuilder().Build(); 786 var services = new ServiceCollection() 787 .AddSingleton<IConfiguration>(config) 788 .AddLogging(); 789 790 services.AddIdentity<PocoUser, PocoRole>(o => o.Tokens.ProviderMap.Add(TokenOptions.DefaultProvider, new TokenProviderDescriptor(typeof(ATokenProvider)) 791 { 792 ProviderInstance = provider 793 })).AddUserStore<NoopUserStore>().AddDefaultTokenProviders(); 794 var manager = services.BuildServiceProvider().GetService<UserManager<PocoUser>>(); 795 Assert.ThrowsAsync<NotImplementedException>(() => manager.GenerateUserTokenAsync(new PocoUser(), TokenOptions.DefaultProvider, "purpose")); 796 } 797 798 [Fact] TwoFactorStoreMethodsFailWhenStoreNotImplemented()799 public async Task TwoFactorStoreMethodsFailWhenStoreNotImplemented() 800 { 801 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 802 Assert.False(manager.SupportsUserTwoFactor); 803 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetTwoFactorEnabledAsync(null)); 804 await 805 Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetTwoFactorEnabledAsync(null, true)); 806 } 807 808 [Fact] LockoutStoreMethodsFailWhenStoreNotImplemented()809 public async Task LockoutStoreMethodsFailWhenStoreNotImplemented() 810 { 811 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 812 Assert.False(manager.SupportsUserLockout); 813 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetLockoutEnabledAsync(null)); 814 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetLockoutEnabledAsync(null, true)); 815 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AccessFailedAsync(null)); 816 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.IsLockedOutAsync(null)); 817 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.ResetAccessFailedCountAsync(null)); 818 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetAccessFailedCountAsync(null)); 819 } 820 821 [Fact] RoleMethodsFailWhenStoreNotImplemented()822 public async Task RoleMethodsFailWhenStoreNotImplemented() 823 { 824 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 825 Assert.False(manager.SupportsUserRole); 826 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRoleAsync(null, "bogus")); 827 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRolesAsync(null, null)); 828 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetRolesAsync(null)); 829 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveFromRoleAsync(null, "bogus")); 830 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveFromRolesAsync(null, null)); 831 await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.IsInRoleAsync(null, "bogus")); 832 } 833 834 [Fact] AuthTokenMethodsFailWhenStoreNotImplemented()835 public async Task AuthTokenMethodsFailWhenStoreNotImplemented() 836 { 837 var error = Extensions.Identity.Core.Resources.StoreNotIUserAuthenticationTokenStore; 838 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 839 Assert.False(manager.SupportsUserAuthenticationTokens); 840 await VerifyException<NotSupportedException>(async () => await manager.GetAuthenticationTokenAsync(null, null, null), error); 841 await VerifyException<NotSupportedException>(async () => await manager.SetAuthenticationTokenAsync(null, null, null, null), error); 842 await VerifyException<NotSupportedException>(async () => await manager.RemoveAuthenticationTokenAsync(null, null, null), error); 843 } 844 845 [Fact] AuthenticatorMethodsFailWhenStoreNotImplemented()846 public async Task AuthenticatorMethodsFailWhenStoreNotImplemented() 847 { 848 var error = Extensions.Identity.Core.Resources.StoreNotIUserAuthenticatorKeyStore; 849 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 850 Assert.False(manager.SupportsUserAuthenticatorKey); 851 await VerifyException<NotSupportedException>(async () => await manager.GetAuthenticatorKeyAsync(null), error); 852 await VerifyException<NotSupportedException>(async () => await manager.ResetAuthenticatorKeyAsync(null), error); 853 } 854 855 [Fact] RecoveryMethodsFailWhenStoreNotImplemented()856 public async Task RecoveryMethodsFailWhenStoreNotImplemented() 857 { 858 var error = Extensions.Identity.Core.Resources.StoreNotIUserTwoFactorRecoveryCodeStore; 859 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 860 Assert.False(manager.SupportsUserTwoFactorRecoveryCodes); 861 await VerifyException<NotSupportedException>(async () => await manager.RedeemTwoFactorRecoveryCodeAsync(null, null), error); 862 await VerifyException<NotSupportedException>(async () => await manager.GenerateNewTwoFactorRecoveryCodesAsync(null, 10), error); 863 } 864 865 private async Task VerifyException<TException>(Func<Task> code, string expectedMessage) where TException : Exception 866 { 867 var error = await Assert.ThrowsAsync<TException>(code); 868 Assert.Equal(expectedMessage, error.Message); 869 } 870 871 [Fact] DisposeAfterDisposeDoesNotThrow()872 public void DisposeAfterDisposeDoesNotThrow() 873 { 874 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 875 manager.Dispose(); 876 manager.Dispose(); 877 } 878 879 [Fact] PasswordValidatorBlocksCreate()880 public async Task PasswordValidatorBlocksCreate() 881 { 882 // TODO: Can switch to Mock eventually 883 var manager = MockHelpers.TestUserManager(new EmptyStore()); 884 manager.PasswordValidators.Clear(); 885 manager.PasswordValidators.Add(new BadPasswordValidator<PocoUser>()); 886 IdentityResultAssert.IsFailure(await manager.CreateAsync(new PocoUser(), "password"), 887 BadPasswordValidator<PocoUser>.ErrorMessage); 888 } 889 890 [Fact] ResetTokenCallNoopForTokenValueZero()891 public async Task ResetTokenCallNoopForTokenValueZero() 892 { 893 var user = new PocoUser() { UserName = Guid.NewGuid().ToString() }; 894 var store = new Mock<IUserLockoutStore<PocoUser>>(); 895 store.Setup(x => x.ResetAccessFailedCountAsync(user, It.IsAny<CancellationToken>())).Returns(() => 896 { 897 throw new Exception(); 898 }); 899 var manager = MockHelpers.TestUserManager(store.Object); 900 901 IdentityResultAssert.IsSuccess(await manager.ResetAccessFailedCountAsync(user)); 902 } 903 904 [Fact] ManagerPublicNullChecks()905 public async Task ManagerPublicNullChecks() 906 { 907 Assert.Throws<ArgumentNullException>("store", 908 () => new UserManager<PocoUser>(null, null, null, null, null, null, null, null, null)); 909 910 var manager = MockHelpers.TestUserManager(new NotImplementedStore()); 911 912 await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.CreateAsync(null)); 913 await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.CreateAsync(null, null)); 914 await 915 Assert.ThrowsAsync<ArgumentNullException>("password", 916 async () => await manager.CreateAsync(new PocoUser(), null)); 917 await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.UpdateAsync(null)); 918 await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await manager.DeleteAsync(null)); 919 await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.AddClaimAsync(null, null)); 920 await Assert.ThrowsAsync<ArgumentNullException>("claim", async () => await manager.ReplaceClaimAsync(null, null, null)); 921 await Assert.ThrowsAsync<ArgumentNullException>("claims", async () => await manager.AddClaimsAsync(null, null)); 922 await Assert.ThrowsAsync<ArgumentNullException>("userName", async () => await manager.FindByNameAsync(null)); 923 await Assert.ThrowsAsync<ArgumentNullException>("login", async () => await manager.AddLoginAsync(null, null)); 924 await Assert.ThrowsAsync<ArgumentNullException>("loginProvider", 925 async () => await manager.RemoveLoginAsync(null, null, null)); 926 await Assert.ThrowsAsync<ArgumentNullException>("providerKey", 927 async () => await manager.RemoveLoginAsync(null, "", null)); 928 await Assert.ThrowsAsync<ArgumentNullException>("email", async () => await manager.FindByEmailAsync(null)); 929 Assert.Throws<ArgumentNullException>("provider", () => manager.RegisterTokenProvider("whatever", null)); 930 await Assert.ThrowsAsync<ArgumentNullException>("roles", async () => await manager.AddToRolesAsync(new PocoUser(), null)); 931 await Assert.ThrowsAsync<ArgumentNullException>("roles", async () => await manager.RemoveFromRolesAsync(new PocoUser(), null)); 932 } 933 934 [Fact] MethodsFailWithUnknownUserTest()935 public async Task MethodsFailWithUnknownUserTest() 936 { 937 var manager = MockHelpers.TestUserManager(new EmptyStore()); 938 manager.RegisterTokenProvider("whatever", new NoOpTokenProvider()); 939 await Assert.ThrowsAsync<ArgumentNullException>("user", 940 async () => await manager.GetUserNameAsync(null)); 941 await Assert.ThrowsAsync<ArgumentNullException>("user", 942 async () => await manager.SetUserNameAsync(null, "bogus")); 943 await Assert.ThrowsAsync<ArgumentNullException>("user", 944 async () => await manager.AddClaimAsync(null, new Claim("a", "b"))); 945 await Assert.ThrowsAsync<ArgumentNullException>("user", 946 async () => await manager.AddLoginAsync(null, new UserLoginInfo("", "", ""))); 947 await Assert.ThrowsAsync<ArgumentNullException>("user", 948 async () => await manager.AddPasswordAsync(null, null)); 949 await Assert.ThrowsAsync<ArgumentNullException>("user", 950 async () => await manager.AddToRoleAsync(null, null)); 951 await Assert.ThrowsAsync<ArgumentNullException>("user", 952 async () => await manager.AddToRolesAsync(null, null)); 953 await Assert.ThrowsAsync<ArgumentNullException>("user", 954 async () => await manager.ChangePasswordAsync(null, null, null)); 955 await Assert.ThrowsAsync<ArgumentNullException>("user", 956 async () => await manager.GetClaimsAsync(null)); 957 await Assert.ThrowsAsync<ArgumentNullException>("user", 958 async () => await manager.GetLoginsAsync(null)); 959 await Assert.ThrowsAsync<ArgumentNullException>("user", 960 async () => await manager.GetRolesAsync(null)); 961 await Assert.ThrowsAsync<ArgumentNullException>("user", 962 async () => await manager.IsInRoleAsync(null, null)); 963 await Assert.ThrowsAsync<ArgumentNullException>("user", 964 async () => await manager.RemoveClaimAsync(null, new Claim("a", "b"))); 965 await Assert.ThrowsAsync<ArgumentNullException>("user", 966 async () => await manager.RemoveLoginAsync(null, "", "")); 967 await Assert.ThrowsAsync<ArgumentNullException>("user", 968 async () => await manager.RemovePasswordAsync(null)); 969 await Assert.ThrowsAsync<ArgumentNullException>("user", 970 async () => await manager.RemoveFromRoleAsync(null, null)); 971 await Assert.ThrowsAsync<ArgumentNullException>("user", 972 async () => await manager.RemoveFromRolesAsync(null, null)); 973 await Assert.ThrowsAsync<ArgumentNullException>("user", 974 async () => await manager.ReplaceClaimAsync(null, new Claim("a", "b"), new Claim("a", "c"))); 975 await Assert.ThrowsAsync<ArgumentNullException>("user", 976 async () => await manager.UpdateSecurityStampAsync(null)); 977 await Assert.ThrowsAsync<ArgumentNullException>("user", 978 async () => await manager.GetSecurityStampAsync(null)); 979 await Assert.ThrowsAsync<ArgumentNullException>("user", 980 async () => await manager.HasPasswordAsync(null)); 981 await Assert.ThrowsAsync<ArgumentNullException>("user", 982 async () => await manager.GeneratePasswordResetTokenAsync(null)); 983 await Assert.ThrowsAsync<ArgumentNullException>("user", 984 async () => await manager.ResetPasswordAsync(null, null, null)); 985 await Assert.ThrowsAsync<ArgumentNullException>("user", 986 async () => await manager.IsEmailConfirmedAsync(null)); 987 await Assert.ThrowsAsync<ArgumentNullException>("user", 988 async () => await manager.GenerateEmailConfirmationTokenAsync(null)); 989 await Assert.ThrowsAsync<ArgumentNullException>("user", 990 async () => await manager.ConfirmEmailAsync(null, null)); 991 await Assert.ThrowsAsync<ArgumentNullException>("user", 992 async () => await manager.GetEmailAsync(null)); 993 await Assert.ThrowsAsync<ArgumentNullException>("user", 994 async () => await manager.SetEmailAsync(null, null)); 995 await Assert.ThrowsAsync<ArgumentNullException>("user", 996 async () => await manager.IsPhoneNumberConfirmedAsync(null)); 997 await Assert.ThrowsAsync<ArgumentNullException>("user", 998 async () => await manager.ChangePhoneNumberAsync(null, null, null)); 999 await Assert.ThrowsAsync<ArgumentNullException>("user", 1000 async () => await manager.VerifyChangePhoneNumberTokenAsync(null, null, null)); 1001 await Assert.ThrowsAsync<ArgumentNullException>("user", 1002 async () => await manager.GetPhoneNumberAsync(null)); 1003 await Assert.ThrowsAsync<ArgumentNullException>("user", 1004 async () => await manager.SetPhoneNumberAsync(null, null)); 1005 await Assert.ThrowsAsync<ArgumentNullException>("user", 1006 async () => await manager.GetTwoFactorEnabledAsync(null)); 1007 await Assert.ThrowsAsync<ArgumentNullException>("user", 1008 async () => await manager.SetTwoFactorEnabledAsync(null, true)); 1009 await Assert.ThrowsAsync<ArgumentNullException>("user", 1010 async () => await manager.GenerateTwoFactorTokenAsync(null, null)); 1011 await Assert.ThrowsAsync<ArgumentNullException>("user", 1012 async () => await manager.VerifyTwoFactorTokenAsync(null, null, null)); 1013 await Assert.ThrowsAsync<ArgumentNullException>("user", 1014 async () => await manager.GetValidTwoFactorProvidersAsync(null)); 1015 await Assert.ThrowsAsync<ArgumentNullException>("user", 1016 async () => await manager.VerifyUserTokenAsync(null, null, null, null)); 1017 await Assert.ThrowsAsync<ArgumentNullException>("user", 1018 async () => await manager.AccessFailedAsync(null)); 1019 await Assert.ThrowsAsync<ArgumentNullException>("user", 1020 async () => await manager.ResetAccessFailedCountAsync(null)); 1021 await Assert.ThrowsAsync<ArgumentNullException>("user", 1022 async () => await manager.GetAccessFailedCountAsync(null)); 1023 await Assert.ThrowsAsync<ArgumentNullException>("user", 1024 async () => await manager.GetLockoutEnabledAsync(null)); 1025 await Assert.ThrowsAsync<ArgumentNullException>("user", 1026 async () => await manager.SetLockoutEnabledAsync(null, false)); 1027 await Assert.ThrowsAsync<ArgumentNullException>("user", 1028 async () => await manager.SetLockoutEndDateAsync(null, DateTimeOffset.UtcNow)); 1029 await Assert.ThrowsAsync<ArgumentNullException>("user", 1030 async () => await manager.GetLockoutEndDateAsync(null)); 1031 await Assert.ThrowsAsync<ArgumentNullException>("user", 1032 async () => await manager.IsLockedOutAsync(null)); 1033 } 1034 1035 [Fact] MethodsThrowWhenDisposedTest()1036 public async Task MethodsThrowWhenDisposedTest() 1037 { 1038 var manager = MockHelpers.TestUserManager(new NoopUserStore()); 1039 manager.Dispose(); 1040 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddClaimAsync(null, null)); 1041 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddClaimsAsync(null, null)); 1042 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddLoginAsync(null, null)); 1043 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddPasswordAsync(null, null)); 1044 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddToRoleAsync(null, null)); 1045 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddToRolesAsync(null, null)); 1046 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ChangePasswordAsync(null, null, null)); 1047 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetClaimsAsync(null)); 1048 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetLoginsAsync(null)); 1049 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetRolesAsync(null)); 1050 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.IsInRoleAsync(null, null)); 1051 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveClaimAsync(null, null)); 1052 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveClaimsAsync(null, null)); 1053 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveLoginAsync(null, null, null)); 1054 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemovePasswordAsync(null)); 1055 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveFromRoleAsync(null, null)); 1056 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.RemoveFromRolesAsync(null, null)); 1057 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByLoginAsync(null, null)); 1058 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByIdAsync(null)); 1059 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByNameAsync(null)); 1060 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.CreateAsync(null)); 1061 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.CreateAsync(null, null)); 1062 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateAsync(null)); 1063 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.DeleteAsync(null)); 1064 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ReplaceClaimAsync(null, null, null)); 1065 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateSecurityStampAsync(null)); 1066 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetSecurityStampAsync(null)); 1067 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GeneratePasswordResetTokenAsync(null)); 1068 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ResetPasswordAsync(null, null, null)); 1069 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GenerateEmailConfirmationTokenAsync(null)); 1070 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.IsEmailConfirmedAsync(null)); 1071 await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmailAsync(null, null)); 1072 } 1073 1074 private class BadPasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class 1075 { 1076 public static readonly IdentityError ErrorMessage = new IdentityError { Description = "I'm Bad." }; 1077 ValidateAsync(UserManager<TUser> manager, TUser user, string password)1078 public Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user, string password) 1079 { 1080 return Task.FromResult(IdentityResult.Failed(ErrorMessage)); 1081 } 1082 } 1083 1084 private class EmptyStore : 1085 IUserPasswordStore<PocoUser>, 1086 IUserClaimStore<PocoUser>, 1087 IUserLoginStore<PocoUser>, 1088 IUserEmailStore<PocoUser>, 1089 IUserPhoneNumberStore<PocoUser>, 1090 IUserLockoutStore<PocoUser>, 1091 IUserTwoFactorStore<PocoUser>, 1092 IUserRoleStore<PocoUser>, 1093 IUserSecurityStampStore<PocoUser> 1094 { GetClaimsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1095 public Task<IList<Claim>> GetClaimsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1096 { 1097 return Task.FromResult<IList<Claim>>(new List<Claim>()); 1098 } 1099 AddClaimsAsync(PocoUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken))1100 public Task AddClaimsAsync(PocoUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken)) 1101 { 1102 return Task.FromResult(0); 1103 } 1104 ReplaceClaimAsync(PocoUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken))1105 public Task ReplaceClaimAsync(PocoUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken)) 1106 { 1107 return Task.FromResult(0); 1108 } 1109 RemoveClaimsAsync(PocoUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken))1110 public Task RemoveClaimsAsync(PocoUser user, IEnumerable<Claim> claim, CancellationToken cancellationToken = default(CancellationToken)) 1111 { 1112 return Task.FromResult(0); 1113 } 1114 SetEmailAsync(PocoUser user, string email, CancellationToken cancellationToken = default(CancellationToken))1115 public Task SetEmailAsync(PocoUser user, string email, CancellationToken cancellationToken = default(CancellationToken)) 1116 { 1117 return Task.FromResult(0); 1118 } 1119 GetEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1120 public Task<string> GetEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1121 { 1122 return Task.FromResult(""); 1123 } 1124 GetEmailConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1125 public Task<bool> GetEmailConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1126 { 1127 return Task.FromResult(false); 1128 } 1129 SetEmailConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken))1130 public Task SetEmailConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) 1131 { 1132 return Task.FromResult(0); 1133 } 1134 FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken))1135 public Task<PocoUser> FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken)) 1136 { 1137 return Task.FromResult<PocoUser>(null); 1138 } 1139 GetLockoutEndDateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1140 public Task<DateTimeOffset?> GetLockoutEndDateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1141 { 1142 return Task.FromResult<DateTimeOffset?>(DateTimeOffset.MinValue); 1143 } 1144 SetLockoutEndDateAsync(PocoUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken))1145 public Task SetLockoutEndDateAsync(PocoUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken)) 1146 { 1147 return Task.FromResult(0); 1148 } 1149 IncrementAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1150 public Task<int> IncrementAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1151 { 1152 return Task.FromResult(0); 1153 } 1154 ResetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1155 public Task ResetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1156 { 1157 return Task.FromResult(0); 1158 } 1159 GetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1160 public Task<int> GetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1161 { 1162 return Task.FromResult(0); 1163 } 1164 GetLockoutEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1165 public Task<bool> GetLockoutEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1166 { 1167 return Task.FromResult(false); 1168 } 1169 SetLockoutEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken))1170 public Task SetLockoutEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) 1171 { 1172 return Task.FromResult(0); 1173 } 1174 AddLoginAsync(PocoUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))1175 public Task AddLoginAsync(PocoUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) 1176 { 1177 return Task.FromResult(0); 1178 } 1179 RemoveLoginAsync(PocoUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))1180 public Task RemoveLoginAsync(PocoUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) 1181 { 1182 return Task.FromResult(0); 1183 } 1184 GetLoginsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1185 public Task<IList<UserLoginInfo>> GetLoginsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1186 { 1187 return Task.FromResult<IList<UserLoginInfo>>(new List<UserLoginInfo>()); 1188 } 1189 FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))1190 public Task<PocoUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) 1191 { 1192 return Task.FromResult<PocoUser>(null); 1193 } 1194 Dispose()1195 public void Dispose() 1196 { 1197 } 1198 SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken))1199 public Task SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) 1200 { 1201 return Task.FromResult(0); 1202 } 1203 CreateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1204 public Task<IdentityResult> CreateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1205 { 1206 return Task.FromResult(IdentityResult.Success); 1207 } 1208 UpdateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1209 public Task<IdentityResult> UpdateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1210 { 1211 return Task.FromResult(IdentityResult.Success); 1212 } 1213 DeleteAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1214 public Task<IdentityResult> DeleteAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1215 { 1216 return Task.FromResult(IdentityResult.Success); 1217 } 1218 FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))1219 public Task<PocoUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) 1220 { 1221 return Task.FromResult<PocoUser>(null); 1222 } 1223 FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken))1224 public Task<PocoUser> FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken)) 1225 { 1226 return Task.FromResult<PocoUser>(null); 1227 } 1228 SetPasswordHashAsync(PocoUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken))1229 public Task SetPasswordHashAsync(PocoUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken)) 1230 { 1231 return Task.FromResult(0); 1232 } 1233 GetPasswordHashAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1234 public Task<string> GetPasswordHashAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1235 { 1236 return Task.FromResult<string>(null); 1237 } 1238 HasPasswordAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1239 public Task<bool> HasPasswordAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1240 { 1241 return Task.FromResult(false); 1242 } 1243 SetPhoneNumberAsync(PocoUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken))1244 public Task SetPhoneNumberAsync(PocoUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken)) 1245 { 1246 return Task.FromResult(0); 1247 } 1248 GetPhoneNumberAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1249 public Task<string> GetPhoneNumberAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1250 { 1251 return Task.FromResult(""); 1252 } 1253 GetPhoneNumberConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1254 public Task<bool> GetPhoneNumberConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1255 { 1256 return Task.FromResult(false); 1257 } 1258 SetPhoneNumberConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken))1259 public Task SetPhoneNumberConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) 1260 { 1261 return Task.FromResult(0); 1262 } 1263 AddToRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1264 public Task AddToRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1265 { 1266 return Task.FromResult(0); 1267 } 1268 RemoveFromRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1269 public Task RemoveFromRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1270 { 1271 return Task.FromResult(0); 1272 } 1273 GetRolesAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1274 public Task<IList<string>> GetRolesAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1275 { 1276 return Task.FromResult<IList<string>>(new List<string>()); 1277 } 1278 IsInRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1279 public Task<bool> IsInRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1280 { 1281 return Task.FromResult(false); 1282 } 1283 SetSecurityStampAsync(PocoUser user, string stamp, CancellationToken cancellationToken = default(CancellationToken))1284 public Task SetSecurityStampAsync(PocoUser user, string stamp, CancellationToken cancellationToken = default(CancellationToken)) 1285 { 1286 return Task.FromResult(0); 1287 } 1288 GetSecurityStampAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1289 public Task<string> GetSecurityStampAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1290 { 1291 return Task.FromResult(""); 1292 } 1293 SetTwoFactorEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken))1294 public Task SetTwoFactorEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) 1295 { 1296 return Task.FromResult(0); 1297 } 1298 GetTwoFactorEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1299 public Task<bool> GetTwoFactorEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1300 { 1301 return Task.FromResult(false); 1302 } 1303 GetUserIdAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1304 public Task<string> GetUserIdAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1305 { 1306 return Task.FromResult<string>(null); 1307 } 1308 GetUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1309 public Task<string> GetUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1310 { 1311 return Task.FromResult<string>(null); 1312 } 1313 GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1314 public Task<string> GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1315 { 1316 return Task.FromResult<string>(null); 1317 } 1318 SetNormalizedUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken))1319 public Task SetNormalizedUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) 1320 { 1321 return Task.FromResult(0); 1322 } 1323 GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken))1324 public Task<IList<PocoUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) 1325 { 1326 return Task.FromResult<IList<PocoUser>>(new List<PocoUser>()); 1327 } 1328 GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))1329 public Task<IList<PocoUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1330 { 1331 return Task.FromResult<IList<PocoUser>>(new List<PocoUser>()); 1332 } 1333 GetNormalizedEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1334 public Task<string> GetNormalizedEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1335 { 1336 return Task.FromResult(""); 1337 } 1338 SetNormalizedEmailAsync(PocoUser user, string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken))1339 public Task SetNormalizedEmailAsync(PocoUser user, string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken)) 1340 { 1341 return Task.FromResult(0); 1342 } 1343 } 1344 1345 private class NoOpTokenProvider : IUserTwoFactorTokenProvider<PocoUser> 1346 { 1347 public string Name { get; } = "Noop"; 1348 GenerateAsync(string purpose, UserManager<PocoUser> manager, PocoUser user)1349 public Task<string> GenerateAsync(string purpose, UserManager<PocoUser> manager, PocoUser user) 1350 { 1351 return Task.FromResult("Test"); 1352 } 1353 ValidateAsync(string purpose, string token, UserManager<PocoUser> manager, PocoUser user)1354 public Task<bool> ValidateAsync(string purpose, string token, UserManager<PocoUser> manager, PocoUser user) 1355 { 1356 return Task.FromResult(true); 1357 } 1358 CanGenerateTwoFactorTokenAsync(UserManager<PocoUser> manager, PocoUser user)1359 public Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<PocoUser> manager, PocoUser user) 1360 { 1361 return Task.FromResult(true); 1362 } 1363 } 1364 1365 private class NotImplementedStore : 1366 IUserPasswordStore<PocoUser>, 1367 IUserClaimStore<PocoUser>, 1368 IUserLoginStore<PocoUser>, 1369 IUserRoleStore<PocoUser>, 1370 IUserEmailStore<PocoUser>, 1371 IUserPhoneNumberStore<PocoUser>, 1372 IUserLockoutStore<PocoUser>, 1373 IUserTwoFactorStore<PocoUser> 1374 { GetClaimsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1375 public Task<IList<Claim>> GetClaimsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1376 { 1377 throw new NotImplementedException(); 1378 } 1379 AddClaimsAsync(PocoUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))1380 public Task AddClaimsAsync(PocoUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken)) 1381 { 1382 throw new NotImplementedException(); 1383 } 1384 ReplaceClaimAsync(PocoUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken))1385 public Task ReplaceClaimAsync(PocoUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken)) 1386 { 1387 throw new NotImplementedException(); 1388 } 1389 RemoveClaimsAsync(PocoUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken))1390 public Task RemoveClaimsAsync(PocoUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken)) 1391 { 1392 throw new NotImplementedException(); 1393 } 1394 SetEmailAsync(PocoUser user, string email, CancellationToken cancellationToken = default(CancellationToken))1395 public Task SetEmailAsync(PocoUser user, string email, CancellationToken cancellationToken = default(CancellationToken)) 1396 { 1397 throw new NotImplementedException(); 1398 } 1399 GetEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1400 public Task<string> GetEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1401 { 1402 throw new NotImplementedException(); 1403 } 1404 GetEmailConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1405 public Task<bool> GetEmailConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1406 { 1407 throw new NotImplementedException(); 1408 } 1409 SetEmailConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken))1410 public Task SetEmailConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) 1411 { 1412 throw new NotImplementedException(); 1413 } 1414 FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken))1415 public Task<PocoUser> FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken)) 1416 { 1417 throw new NotImplementedException(); 1418 } 1419 GetLockoutEndDateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1420 public Task<DateTimeOffset?> GetLockoutEndDateAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1421 { 1422 throw new NotImplementedException(); 1423 } 1424 SetLockoutEndDateAsync(PocoUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken))1425 public Task SetLockoutEndDateAsync(PocoUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken)) 1426 { 1427 throw new NotImplementedException(); 1428 } 1429 IncrementAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1430 public Task<int> IncrementAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1431 { 1432 throw new NotImplementedException(); 1433 } 1434 ResetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1435 public Task ResetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1436 { 1437 throw new NotImplementedException(); 1438 } 1439 GetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1440 public Task<int> GetAccessFailedCountAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1441 { 1442 throw new NotImplementedException(); 1443 } 1444 GetLockoutEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1445 public Task<bool> GetLockoutEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1446 { 1447 throw new NotImplementedException(); 1448 } 1449 SetLockoutEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken))1450 public Task SetLockoutEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) 1451 { 1452 throw new NotImplementedException(); 1453 } 1454 AddLoginAsync(PocoUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken))1455 public Task AddLoginAsync(PocoUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) 1456 { 1457 throw new NotImplementedException(); 1458 } 1459 RemoveLoginAsync(PocoUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))1460 public Task RemoveLoginAsync(PocoUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) 1461 { 1462 throw new NotImplementedException(); 1463 } 1464 GetLoginsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1465 public Task<IList<UserLoginInfo>> GetLoginsAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1466 { 1467 throw new NotImplementedException(); 1468 } 1469 FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken))1470 public Task<PocoUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) 1471 { 1472 throw new NotImplementedException(); 1473 } 1474 Dispose()1475 public void Dispose() 1476 { 1477 throw new NotImplementedException(); 1478 } 1479 GetUserIdAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1480 public Task<string> GetUserIdAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1481 { 1482 throw new NotImplementedException(); 1483 } 1484 GetUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1485 public Task<string> GetUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1486 { 1487 throw new NotImplementedException(); 1488 } 1489 SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken))1490 public Task SetUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) 1491 { 1492 throw new NotImplementedException(); 1493 } 1494 FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))1495 public Task<PocoUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) 1496 { 1497 throw new NotImplementedException(); 1498 } 1499 FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken))1500 public Task<PocoUser> FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken)) 1501 { 1502 throw new NotImplementedException(); 1503 } 1504 SetPasswordHashAsync(PocoUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken))1505 public Task SetPasswordHashAsync(PocoUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken)) 1506 { 1507 throw new NotImplementedException(); 1508 } 1509 GetPasswordHashAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1510 public Task<string> GetPasswordHashAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1511 { 1512 throw new NotImplementedException(); 1513 } 1514 HasPasswordAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1515 public Task<bool> HasPasswordAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1516 { 1517 throw new NotImplementedException(); 1518 } 1519 SetPhoneNumberAsync(PocoUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken))1520 public Task SetPhoneNumberAsync(PocoUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken)) 1521 { 1522 throw new NotImplementedException(); 1523 } 1524 GetPhoneNumberAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1525 public Task<string> GetPhoneNumberAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1526 { 1527 throw new NotImplementedException(); 1528 } 1529 GetPhoneNumberConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1530 public Task<bool> GetPhoneNumberConfirmedAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1531 { 1532 throw new NotImplementedException(); 1533 } 1534 SetPhoneNumberConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken))1535 public Task SetPhoneNumberConfirmedAsync(PocoUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) 1536 { 1537 throw new NotImplementedException(); 1538 } 1539 SetTwoFactorEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken))1540 public Task SetTwoFactorEnabledAsync(PocoUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) 1541 { 1542 throw new NotImplementedException(); 1543 } 1544 GetTwoFactorEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1545 public Task<bool> GetTwoFactorEnabledAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1546 { 1547 throw new NotImplementedException(); 1548 } 1549 AddToRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1550 public Task AddToRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1551 { 1552 throw new NotImplementedException(); 1553 } 1554 RemoveFromRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1555 public Task RemoveFromRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1556 { 1557 throw new NotImplementedException(); 1558 } 1559 GetRolesAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1560 public Task<IList<string>> GetRolesAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1561 { 1562 throw new NotImplementedException(); 1563 } 1564 IsInRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken))1565 public Task<bool> IsInRoleAsync(PocoUser user, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1566 { 1567 throw new NotImplementedException(); 1568 } 1569 GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1570 public Task<string> GetNormalizedUserNameAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1571 { 1572 throw new NotImplementedException(); 1573 } 1574 SetNormalizedUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken))1575 public Task SetNormalizedUserNameAsync(PocoUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) 1576 { 1577 throw new NotImplementedException(); 1578 } 1579 GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken))1580 public Task<IList<PocoUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) 1581 { 1582 throw new NotImplementedException(); 1583 } 1584 GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))1585 public Task<IList<PocoUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) 1586 { 1587 throw new NotImplementedException(); 1588 } 1589 CreateAsync(PocoUser user, CancellationToken cancellationToken)1590 Task<IdentityResult> IUserStore<PocoUser>.CreateAsync(PocoUser user, CancellationToken cancellationToken) 1591 { 1592 throw new NotImplementedException(); 1593 } 1594 UpdateAsync(PocoUser user, CancellationToken cancellationToken)1595 Task<IdentityResult> IUserStore<PocoUser>.UpdateAsync(PocoUser user, CancellationToken cancellationToken) 1596 { 1597 throw new NotImplementedException(); 1598 } 1599 DeleteAsync(PocoUser user, CancellationToken cancellationToken)1600 Task<IdentityResult> IUserStore<PocoUser>.DeleteAsync(PocoUser user, CancellationToken cancellationToken) 1601 { 1602 throw new NotImplementedException(); 1603 } 1604 GetNormalizedEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken))1605 public Task<string> GetNormalizedEmailAsync(PocoUser user, CancellationToken cancellationToken = default(CancellationToken)) 1606 { 1607 throw new NotImplementedException(); 1608 } 1609 SetNormalizedEmailAsync(PocoUser user, string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken))1610 public Task SetNormalizedEmailAsync(PocoUser user, string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken)) 1611 { 1612 throw new NotImplementedException(); 1613 } 1614 } 1615 1616 [Fact] CanCustomizeUserValidatorErrors()1617 public async Task CanCustomizeUserValidatorErrors() 1618 { 1619 var store = new Mock<IUserEmailStore<PocoUser>>(); 1620 var describer = new TestErrorDescriber(); 1621 var config = new ConfigurationBuilder().Build(); 1622 var services = new ServiceCollection() 1623 .AddSingleton<IConfiguration>(config) 1624 .AddLogging() 1625 .AddSingleton<IdentityErrorDescriber>(describer) 1626 .AddSingleton<IUserStore<PocoUser>>(store.Object) 1627 .AddHttpContextAccessor(); 1628 1629 services.AddIdentity<PocoUser, PocoRole>(); 1630 1631 var manager = services.BuildServiceProvider().GetRequiredService<UserManager<PocoUser>>(); 1632 1633 manager.Options.User.RequireUniqueEmail = true; 1634 var user = new PocoUser() { UserName = "dupeEmail", Email = "dupe@email.com" }; 1635 var user2 = new PocoUser() { UserName = "dupeEmail2", Email = "dupe@email.com" }; 1636 store.Setup(s => s.FindByEmailAsync("DUPE@EMAIL.COM", CancellationToken.None)) 1637 .Returns(Task.FromResult(user2)) 1638 .Verifiable(); 1639 store.Setup(s => s.GetUserIdAsync(user2, CancellationToken.None)) 1640 .Returns(Task.FromResult(user2.Id)) 1641 .Verifiable(); 1642 store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)) 1643 .Returns(Task.FromResult(user.UserName)) 1644 .Verifiable(); 1645 store.Setup(s => s.GetEmailAsync(user, CancellationToken.None)) 1646 .Returns(Task.FromResult(user.Email)) 1647 .Verifiable(); 1648 1649 Assert.Same(describer, manager.ErrorDescriber); 1650 IdentityResultAssert.IsFailure(await manager.CreateAsync(user), describer.DuplicateEmail(user.Email)); 1651 1652 store.VerifyAll(); 1653 } 1654 1655 public class TestErrorDescriber : IdentityErrorDescriber 1656 { 1657 public static string Code = "Error"; 1658 public static string FormatError = "FormatError {0}"; 1659 DuplicateEmail(string email)1660 public override IdentityError DuplicateEmail(string email) 1661 { 1662 return new IdentityError { Code = Code, Description = string.Format(FormatError, email) }; 1663 } 1664 } 1665 1666 } 1667 }