[Fixes #1690] AddDefaultUI() throws when using IdentityUser<T>
This commit is contained in:
parent
c7711c2515
commit
971f727ea2
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26730.12
|
VisualStudioVersion = 15.0.27130.2027
|
||||||
MinimumVisualStudioVersion = 15.0.26730.03
|
MinimumVisualStudioVersion = 15.0.26730.03
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0F647068-6602-4E24-B1DC-8ED91481A50A}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0F647068-6602-4E24-B1DC-8ED91481A50A}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnGetAsync(string userId, string code) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnGetAsync(string userId, string code) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ConfirmEmailModel<TUser> : ConfirmEmailModel where TUser : IdentityUser
|
internal class ConfirmEmailModel<TUser> : ConfirmEmailModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,19 +40,22 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExternalLoginModel<TUser> : ExternalLoginModel where TUser : IdentityUser, new()
|
internal class ExternalLoginModel<TUser> : ExternalLoginModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
|
private readonly IUserFactory<TUser> _userFactory;
|
||||||
private readonly ILogger<ExternalLoginModel> _logger;
|
private readonly ILogger<ExternalLoginModel> _logger;
|
||||||
|
|
||||||
public ExternalLoginModel(
|
public ExternalLoginModel(
|
||||||
SignInManager<TUser> signInManager,
|
SignInManager<TUser> signInManager,
|
||||||
UserManager<TUser> userManager,
|
UserManager<TUser> userManager,
|
||||||
|
IUserFactory<TUser> userFactory,
|
||||||
ILogger<ExternalLoginModel> logger)
|
ILogger<ExternalLoginModel> logger)
|
||||||
{
|
{
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
|
_userFactory = userFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +127,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
|
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
var user = new TUser { UserName = Input.Email, Email = Input.Email };
|
var user = _userFactory.CreateUser(email: Input.Email, userName: Input.Email);
|
||||||
var result = await _userManager.CreateAsync(user);
|
var result = await _userManager.CreateAsync(user);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ForgotPasswordModel<TUser> : ForgotPasswordModel where TUser : IdentityUser
|
internal class ForgotPasswordModel<TUser> : ForgotPasswordModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly IEmailSender _emailSender;
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LoginModel<TUser> : LoginModel where TUser : IdentityUser
|
internal class LoginModel<TUser> : LoginModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
private readonly ILogger<LoginModel> _logger;
|
private readonly ILogger<LoginModel> _logger;
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,19 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync(bool rememberMe, string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync(bool rememberMe, string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LoginWith2faModel<TUser> : LoginWith2faModel where TUser : IdentityUser
|
internal class LoginWith2faModel<TUser> : LoginWith2faModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<LoginWith2faModel> _logger;
|
private readonly ILogger<LoginWith2faModel> _logger;
|
||||||
|
|
||||||
public LoginWith2faModel(SignInManager<TUser> signInManager, ILogger<LoginWith2faModel> logger)
|
public LoginWith2faModel(
|
||||||
|
SignInManager<TUser> signInManager,
|
||||||
|
UserManager<TUser> userManager,
|
||||||
|
ILogger<LoginWith2faModel> logger)
|
||||||
{
|
{
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
|
_userManager = userManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,19 +90,21 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
|
|
||||||
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, Input.RememberMachine);
|
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, Input.RememberMachine);
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User with ID '{UserId}' logged in with 2fa.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' logged in with 2fa.", userId);
|
||||||
return LocalRedirect(returnUrl);
|
return LocalRedirect(returnUrl);
|
||||||
}
|
}
|
||||||
else if (result.IsLockedOut)
|
else if (result.IsLockedOut)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User with ID '{UserId}' account locked out.", user.Id);
|
_logger.LogWarning("User with ID '{UserId}' account locked out.", userId);
|
||||||
return RedirectToPage("./Lockout");
|
return RedirectToPage("./Lockout");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Invalid authenticator code entered for user with ID '{UserId}'.", user.Id);
|
_logger.LogWarning("Invalid authenticator code entered for user with ID '{UserId}'.", userId);
|
||||||
ModelState.AddModelError(string.Empty, "Invalid authenticator code.");
|
ModelState.AddModelError(string.Empty, "Invalid authenticator code.");
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,19 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LoginWithRecoveryCodeModel<TUser> : LoginWithRecoveryCodeModel where TUser : IdentityUser
|
internal class LoginWithRecoveryCodeModel<TUser> : LoginWithRecoveryCodeModel where TUser: class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<LoginWithRecoveryCodeModel> _logger;
|
private readonly ILogger<LoginWithRecoveryCodeModel> _logger;
|
||||||
|
|
||||||
public LoginWithRecoveryCodeModel(SignInManager<TUser> signInManager, ILogger<LoginWithRecoveryCodeModel> logger)
|
public LoginWithRecoveryCodeModel(
|
||||||
|
SignInManager<TUser> signInManager,
|
||||||
|
UserManager<TUser> userManager,
|
||||||
|
ILogger<LoginWithRecoveryCodeModel> logger)
|
||||||
{
|
{
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
|
_userManager = userManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,19 +81,21 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
|
|
||||||
var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);
|
var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", userId);
|
||||||
return LocalRedirect(returnUrl ?? Url.Content("~/"));
|
return LocalRedirect(returnUrl ?? Url.Content("~/"));
|
||||||
}
|
}
|
||||||
if (result.IsLockedOut)
|
if (result.IsLockedOut)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User with ID '{UserId}' account locked out.", user.Id);
|
_logger.LogWarning("User with ID '{UserId}' account locked out.", userId);
|
||||||
return RedirectToPage("./Lockout");
|
return RedirectToPage("./Lockout");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", user.Id);
|
_logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", userId);
|
||||||
ModelState.AddModelError(string.Empty, "Invalid recovery code entered.");
|
ModelState.AddModelError(string.Empty, "Invalid recovery code entered.");
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPost(string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPost(string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LogoutModel<TUser> : LogoutModel where TUser : IdentityUser
|
internal class LogoutModel<TUser> : LogoutModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
private readonly ILogger<LogoutModel> _logger;
|
private readonly ILogger<LogoutModel> _logger;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ChangePasswordModel<TUser> : ChangePasswordModel where TUser : IdentityUser
|
internal class ChangePasswordModel<TUser> : ChangePasswordModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DeletePersonalDataModel<TUser> : DeletePersonalDataModel where TUser : IdentityUser
|
internal class DeletePersonalDataModel<TUser> : DeletePersonalDataModel where TUser: class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
@ -77,14 +77,15 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await _userManager.DeleteAsync(user);
|
var result = await _userManager.DeleteAsync(user);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred deleteing user with ID '{user.Id}'.");
|
throw new InvalidOperationException($"Unexpected error occurred deleteing user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _signInManager.SignOutAsync();
|
await _signInManager.SignOutAsync();
|
||||||
|
|
||||||
_logger.LogInformation("User with ID '{UserId}' deleted themselves.", _userManager.GetUserId(User));
|
_logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId);
|
||||||
|
|
||||||
return Redirect("~/");
|
return Redirect("~/");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Disable2faModel<TUser> : Disable2faModel where TUser : IdentityUser
|
internal class Disable2faModel<TUser> : Disable2faModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<Disable2faModel> _logger;
|
private readonly ILogger<Disable2faModel> _logger;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DownloadPersonalDataModel<TUser> : DownloadPersonalDataModel where TUser : IdentityUser
|
internal class DownloadPersonalDataModel<TUser> : DownloadPersonalDataModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<DownloadPersonalDataModel> _logger;
|
private readonly ILogger<DownloadPersonalDataModel> _logger;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class EnableAuthenticatorModel<TUser> : EnableAuthenticatorModel where TUser : IdentityUser
|
internal class EnableAuthenticatorModel<TUser> : EnableAuthenticatorModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<EnableAuthenticatorModel> _logger;
|
private readonly ILogger<EnableAuthenticatorModel> _logger;
|
||||||
|
|
@ -102,7 +102,8 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
||||||
_logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", user.Id);
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", userId);
|
||||||
|
|
||||||
StatusMessage = "Your authenticator app has been verified.";
|
StatusMessage = "Your authenticator app has been verified.";
|
||||||
|
|
||||||
|
|
@ -129,7 +130,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedKey = FormatKey(unformattedKey);
|
SharedKey = FormatKey(unformattedKey);
|
||||||
AuthenticatorUri = GenerateQrCodeUri(user.Email, unformattedKey);
|
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
AuthenticatorUri = GenerateQrCodeUri(email, unformattedKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatKey(string unformattedKey)
|
private string FormatKey(string unformattedKey)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
@ -32,17 +33,20 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnGetLinkLoginCallbackAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnGetLinkLoginCallbackAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ExternalLoginsModel<TUser> : ExternalLoginsModel where TUser : IdentityUser
|
internal class ExternalLoginsModel<TUser> : ExternalLoginsModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
private readonly IUserStore<TUser> _userStore;
|
||||||
|
|
||||||
public ExternalLoginsModel(
|
public ExternalLoginsModel(
|
||||||
UserManager<TUser> userManager,
|
UserManager<TUser> userManager,
|
||||||
SignInManager<TUser> signInManager)
|
SignInManager<TUser> signInManager,
|
||||||
|
IUserStore<TUser> userStore)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
|
_userStore = userStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<IActionResult> OnGetAsync()
|
public override async Task<IActionResult> OnGetAsync()
|
||||||
|
|
@ -57,7 +61,14 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
OtherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
|
OtherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
|
||||||
.Where(auth => CurrentLogins.All(ul => auth.Name != ul.LoginProvider))
|
.Where(auth => CurrentLogins.All(ul => auth.Name != ul.LoginProvider))
|
||||||
.ToList();
|
.ToList();
|
||||||
ShowRemoveButton = user.PasswordHash != null || CurrentLogins.Count > 1;
|
|
||||||
|
string passwordHash = null;
|
||||||
|
if (_userStore is IUserPasswordStore<TUser> userPasswordStore)
|
||||||
|
{
|
||||||
|
passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowRemoveButton = passwordHash != null || CurrentLogins.Count > 1;
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +83,8 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
var result = await _userManager.RemoveLoginAsync(user, loginProvider, providerKey);
|
var result = await _userManager.RemoveLoginAsync(user, loginProvider, providerKey);
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred removing external login for user with ID '{user.Id}'.");
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred removing external login for user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _signInManager.RefreshSignInAsync(user);
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
|
|
@ -99,16 +111,17 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var info = await _signInManager.GetExternalLoginInfoAsync(userId);
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred loading external login info for user with ID '{user.Id}'.");
|
throw new InvalidOperationException($"Unexpected error occurred loading external login info for user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await _userManager.AddLoginAsync(user, info);
|
var result = await _userManager.AddLoginAsync(user, info);
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred adding external login for user with ID '{user.Id}'.");
|
throw new InvalidOperationException($"Unexpected error occurred adding external login for user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the existing external cookie to ensure a clean login process
|
// Clear the existing external cookie to ensure a clean login process
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GenerateRecoveryCodesModel<TUser> : GenerateRecoveryCodesModel where TUser : IdentityUser
|
internal class GenerateRecoveryCodesModel<TUser> : GenerateRecoveryCodesModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<GenerateRecoveryCodesModel> _logger;
|
private readonly ILogger<GenerateRecoveryCodesModel> _logger;
|
||||||
|
|
@ -45,9 +45,11 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.TwoFactorEnabled)
|
var isTwoFactorEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
if (!isTwoFactorEnabled)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{user.Id}' because they do not have 2FA enabled.");
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{userId}' because they do not have 2FA enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Page();
|
return Page();
|
||||||
|
|
@ -61,15 +63,17 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.TwoFactorEnabled)
|
var isTwoFactorEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
if (!isTwoFactorEnabled)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{user.Id}' as they do not have 2FA enabled.");
|
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{userId}' as they do not have 2FA enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
||||||
RecoveryCodes = recoveryCodes.ToArray();
|
RecoveryCodes = recoveryCodes.ToArray();
|
||||||
|
|
||||||
_logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", userId);
|
||||||
StatusMessage = "You have generated new recovery codes.";
|
StatusMessage = "You have generated new recovery codes.";
|
||||||
return RedirectToPage("./ShowRecoveryCodes");
|
return RedirectToPage("./ShowRecoveryCodes");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostSendVerificationEmailAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostSendVerificationEmailAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class IndexModel<TUser> : IndexModel where TUser : IdentityUser
|
internal class IndexModel<TUser> : IndexModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
@ -65,13 +65,16 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
{
|
{
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
var userName = await _userManager.GetUserNameAsync(user);
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
|
||||||
|
|
||||||
Username = user.UserName;
|
Username = userName;
|
||||||
|
|
||||||
Input = new InputModel
|
Input = new InputModel
|
||||||
{
|
{
|
||||||
Email = user.Email,
|
Email = email,
|
||||||
PhoneNumber = user.PhoneNumber
|
PhoneNumber = phoneNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
|
IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
|
||||||
|
|
@ -92,21 +95,25 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.Email != user.Email)
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
|
if (Input.Email != email)
|
||||||
{
|
{
|
||||||
var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
|
var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
|
||||||
if (!setEmailResult.Succeeded)
|
if (!setEmailResult.Succeeded)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred setting email for user with ID '{user.Id}'.");
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred setting email for user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.PhoneNumber != user.PhoneNumber)
|
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
|
||||||
|
if (Input.PhoneNumber != phoneNumber)
|
||||||
{
|
{
|
||||||
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
|
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
|
||||||
if (!setPhoneResult.Succeeded)
|
if (!setPhoneResult.Succeeded)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{user.Id}'.");
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,14 +135,17 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
var email = await _userManager.GetEmailAsync(user);
|
||||||
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
var callbackUrl = Url.Page(
|
var callbackUrl = Url.Page(
|
||||||
"/Account/ConfirmEmail",
|
"/Account/ConfirmEmail",
|
||||||
pageHandler: null,
|
pageHandler: null,
|
||||||
values: new { userId = user.Id, code = code },
|
values: new { userId = userId, code = code },
|
||||||
protocol: Request.Scheme);
|
protocol: Request.Scheme);
|
||||||
await _emailSender.SendEmailAsync(
|
await _emailSender.SendEmailAsync(
|
||||||
user.Email,
|
email,
|
||||||
"Confirm your email",
|
"Confirm your email",
|
||||||
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnGet() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnGet() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class PersonalDataModel<TUser> : PersonalDataModel where TUser : IdentityUser
|
internal class PersonalDataModel<TUser> : PersonalDataModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<PersonalDataModel> _logger;
|
private readonly ILogger<PersonalDataModel> _logger;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ResetAuthenticatorModel<TUser> : ResetAuthenticatorModel where TUser : IdentityUser
|
internal class ResetAuthenticatorModel<TUser> : ResetAuthenticatorModel where TUser : class
|
||||||
{
|
{
|
||||||
UserManager<TUser> _userManager;
|
UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
@ -57,7 +57,8 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
|
|
||||||
await _userManager.SetTwoFactorEnabledAsync(user, false);
|
await _userManager.SetTwoFactorEnabledAsync(user, false);
|
||||||
await _userManager.ResetAuthenticatorKeyAsync(user);
|
await _userManager.ResetAuthenticatorKeyAsync(user);
|
||||||
_logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", user.Id);
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
|
_logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", userId);
|
||||||
|
|
||||||
await _signInManager.RefreshSignInAsync(user);
|
await _signInManager.RefreshSignInAsync(user);
|
||||||
StatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.";
|
StatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.";
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SetPasswordModel<TUser> : SetPasswordModel where TUser : IdentityUser
|
internal class SetPasswordModel<TUser> : SetPasswordModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage.Internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TwoFactorAuthenticationModel<TUser> : TwoFactorAuthenticationModel where TUser : IdentityUser
|
internal class TwoFactorAuthenticationModel<TUser> : TwoFactorAuthenticationModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,10 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync(string returnUrl = null) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class RegisterModel<TUser> : RegisterModel where TUser : IdentityUser, new()
|
internal class RegisterModel<TUser> : RegisterModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly SignInManager<TUser> _signInManager;
|
private readonly SignInManager<TUser> _signInManager;
|
||||||
|
private readonly IUserFactory<TUser> _userFactory;
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
private readonly ILogger<LoginModel> _logger;
|
private readonly ILogger<LoginModel> _logger;
|
||||||
private readonly IEmailSender _emailSender;
|
private readonly IEmailSender _emailSender;
|
||||||
|
|
@ -56,11 +57,13 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public RegisterModel(
|
public RegisterModel(
|
||||||
UserManager<TUser> userManager,
|
UserManager<TUser> userManager,
|
||||||
SignInManager<TUser> signInManager,
|
SignInManager<TUser> signInManager,
|
||||||
|
IUserFactory<TUser> userFactory,
|
||||||
ILogger<LoginModel> logger,
|
ILogger<LoginModel> logger,
|
||||||
IEmailSender emailSender)
|
IEmailSender emailSender)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_signInManager = signInManager;
|
_signInManager = signInManager;
|
||||||
|
_userFactory = userFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_emailSender = emailSender;
|
_emailSender = emailSender;
|
||||||
}
|
}
|
||||||
|
|
@ -75,17 +78,18 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
returnUrl = returnUrl ?? Url.Content("~/");
|
returnUrl = returnUrl ?? Url.Content("~/");
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
var user = new TUser { UserName = Input.Email, Email = Input.Email };
|
var user = _userFactory.CreateUser(email: Input.Email, userName: Input.Email);
|
||||||
var result = await _userManager.CreateAsync(user, Input.Password);
|
var result = await _userManager.CreateAsync(user, Input.Password);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User created a new account with password.");
|
_logger.LogInformation("User created a new account with password.");
|
||||||
|
|
||||||
|
var userId = await _userManager.GetUserIdAsync(user);
|
||||||
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||||
var callbackUrl = Url.Page(
|
var callbackUrl = Url.Page(
|
||||||
"/Account/ConfirmEmail",
|
"/Account/ConfirmEmail",
|
||||||
pageHandler: null,
|
pageHandler: null,
|
||||||
values: new { userId = user.Id, code = code },
|
values: new { userId = userId, code = code },
|
||||||
protocol: Request.Scheme);
|
protocol: Request.Scheme);
|
||||||
|
|
||||||
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
|
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
||||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ResetPasswordModel<TUser> : ResetPasswordModel where TUser : IdentityUser
|
internal class ResetPasswordModel<TUser> : ResetPasswordModel where TUser : class
|
||||||
{
|
{
|
||||||
private readonly UserManager<TUser> _userManager;
|
private readonly UserManager<TUser> _userManager;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Identity.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides an abstraction for instantiating the given user type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TUser">The type of user.</typeparam>
|
||||||
|
public interface IUserFactory<TUser> where TUser : class
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates an instance of a user and assigns the provided values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="email">Email address</param>
|
||||||
|
/// <param name="userName">User name</param>
|
||||||
|
/// <returns>Created user</returns>
|
||||||
|
TUser CreateUser(string email, string userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Identity.UI;
|
using Microsoft.AspNetCore.Identity.UI;
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
|
@ -36,6 +37,13 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
.MakeGenericType(builder.UserType));
|
.MakeGenericType(builder.UserType));
|
||||||
builder.Services.TryAddTransient<IEmailSender, EmailSender>();
|
builder.Services.TryAddTransient<IEmailSender, EmailSender>();
|
||||||
|
|
||||||
|
if (TryGetIdentityUserType(builder.UserType, out var primaryKeyType))
|
||||||
|
{
|
||||||
|
var userFactoryType = typeof(IUserFactory<>).MakeGenericType(builder.UserType);
|
||||||
|
var defaultUserFactoryType = typeof(UserFactory<,>).MakeGenericType(builder.UserType, primaryKeyType);
|
||||||
|
builder.Services.TryAddSingleton(userFactoryType, defaultUserFactoryType);
|
||||||
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,5 +71,24 @@ namespace Microsoft.AspNetCore.Identity
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetIdentityUserType(Type userType, out Type primaryKeyType)
|
||||||
|
{
|
||||||
|
primaryKeyType = null;
|
||||||
|
|
||||||
|
var baseType = userType.BaseType;
|
||||||
|
while (baseType != null)
|
||||||
|
{
|
||||||
|
if (baseType.IsGenericType &&
|
||||||
|
baseType.GetGenericTypeDefinition() == typeof(IdentityUser<>))
|
||||||
|
{
|
||||||
|
primaryKeyType = baseType.GetGenericArguments()[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
baseType = baseType.BaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Identity.UI
|
||||||
internal class IdentityDefaultUIConfigureOptions<TUser> :
|
internal class IdentityDefaultUIConfigureOptions<TUser> :
|
||||||
IPostConfigureOptions<RazorPagesOptions>,
|
IPostConfigureOptions<RazorPagesOptions>,
|
||||||
IPostConfigureOptions<StaticFileOptions>,
|
IPostConfigureOptions<StaticFileOptions>,
|
||||||
IPostConfigureOptions<CookieAuthenticationOptions> where TUser : IdentityUser
|
IPostConfigureOptions<CookieAuthenticationOptions> where TUser : class
|
||||||
{
|
{
|
||||||
private const string IdentityUIDefaultAreaName = "Identity";
|
private const string IdentityUIDefaultAreaName = "Identity";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.UI
|
namespace Microsoft.AspNetCore.Identity.UI
|
||||||
{
|
{
|
||||||
internal class IdentityPageModelConvention<TUser> : IPageApplicationModelConvention where TUser : IdentityUser
|
internal class IdentityPageModelConvention<TUser> : IPageApplicationModelConvention where TUser : class
|
||||||
{
|
{
|
||||||
public void Apply(PageApplicationModel model)
|
public void Apply(PageApplicationModel model)
|
||||||
{
|
{
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Identity.UI
|
||||||
|
|
||||||
private void ValidateTemplate(Type template)
|
private void ValidateTemplate(Type template)
|
||||||
{
|
{
|
||||||
if(template.IsAbstract || !template.IsGenericTypeDefinition)
|
if (template.IsAbstract || !template.IsGenericTypeDefinition)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Implementation type can't be abstract or non generic.");
|
throw new InvalidOperationException("Implementation type can't be abstract or non generic.");
|
||||||
}
|
}
|
||||||
|
|
@ -33,11 +33,6 @@ namespace Microsoft.AspNetCore.Identity.UI
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Implementation type contains wrong generic arity.");
|
throw new InvalidOperationException("Implementation type contains wrong generic arity.");
|
||||||
}
|
}
|
||||||
var argument = genericArguments[0];
|
|
||||||
if (!typeof(IdentityUser).IsAssignableFrom(typeof(TUser)))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Generic implementation type is not compatible.");
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Identity.UI
|
||||||
|
{
|
||||||
|
internal class UserFactory<TUser, TKey> : IUserFactory<TUser>
|
||||||
|
where TUser : IdentityUser<TKey>, new()
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
{
|
||||||
|
public TUser CreateUser(string email, string userName)
|
||||||
|
{
|
||||||
|
return new TUser() { Email = email, UserName = userName };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue