committed by
GitHub
5 changed files with 61 additions and 247 deletions
@ -0,0 +1,12 @@ |
|||
@page |
|||
@model ConfirmEmailModel |
|||
@{ |
|||
ViewData["Title"] = "Confirm email"; |
|||
} |
|||
|
|||
<h2>@ViewData["Title"]</h2> |
|||
<div> |
|||
<p> |
|||
Thank you for confirming your email. |
|||
</p> |
|||
</div> |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Areas.Identity.Pages.Account |
|||
{ |
|||
[AllowAnonymous] |
|||
public class ConfirmEmailModel : PageModel |
|||
{ |
|||
private readonly UserManager<ApplicationUser> _userManager; |
|||
|
|||
public ConfirmEmailModel(UserManager<ApplicationUser> userManager) |
|||
{ |
|||
_userManager = userManager; |
|||
} |
|||
|
|||
public async Task<IActionResult> OnGetAsync(string userId, string code) |
|||
{ |
|||
if (userId == null || code == null) |
|||
{ |
|||
return RedirectToPage("/Index"); |
|||
} |
|||
|
|||
var user = await _userManager.FindByIdAsync(userId); |
|||
if (user == null) |
|||
{ |
|||
return NotFound($"Unable to load user with ID '{userId}'."); |
|||
} |
|||
|
|||
var result = await _userManager.ConfirmEmailAsync(user, code); |
|||
if (!result.Succeeded) |
|||
{ |
|||
throw new InvalidOperationException($"Error confirming email for user with ID '{userId}':"); |
|||
} |
|||
|
|||
return Page(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,232 +0,0 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Microsoft.eShopWeb.Infrastructure.Identity; |
|||
using Microsoft.eShopWeb.Web.ViewModels.Account; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.Controllers |
|||
{ |
|||
[ApiExplorerSettings(IgnoreApi = true)] |
|||
[Route("[controller]/[action]")]
|
|||
[Authorize] // Controllers that mainly require Authorization still use Controller/View; other pages use Pages
|
|||
public class AccountController : Controller |
|||
{ |
|||
private readonly UserManager<ApplicationUser> _userManager; |
|||
private readonly SignInManager<ApplicationUser> _signInManager; |
|||
private readonly IBasketService _basketService; |
|||
private readonly IAppLogger<AccountController> _logger; |
|||
|
|||
public AccountController( |
|||
UserManager<ApplicationUser> userManager, |
|||
SignInManager<ApplicationUser> signInManager, |
|||
IBasketService basketService, |
|||
IAppLogger<AccountController> logger) |
|||
{ |
|||
_userManager = userManager; |
|||
_signInManager = signInManager; |
|||
_basketService = basketService; |
|||
_logger = logger; |
|||
} |
|||
|
|||
// GET: /Account/SignIn
|
|||
[HttpGet] |
|||
[AllowAnonymous] |
|||
public async Task<IActionResult> SignIn(string returnUrl = null) |
|||
{ |
|||
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); |
|||
|
|||
ViewData["ReturnUrl"] = returnUrl; |
|||
if (!String.IsNullOrEmpty(returnUrl) && |
|||
returnUrl.IndexOf("checkout", StringComparison.OrdinalIgnoreCase) >= 0) |
|||
{ |
|||
ViewData["ReturnUrl"] = "/Basket/Index"; |
|||
} |
|||
|
|||
return View(); |
|||
} |
|||
|
|||
// POST: /Account/SignIn
|
|||
[HttpPost] |
|||
[AllowAnonymous] |
|||
[ValidateAntiForgeryToken] |
|||
public async Task<IActionResult> SignIn(LoginViewModel model, string returnUrl = null) |
|||
{ |
|||
if (!ModelState.IsValid) |
|||
{ |
|||
return View(model); |
|||
} |
|||
ViewData["ReturnUrl"] = returnUrl; |
|||
|
|||
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); |
|||
if (result.RequiresTwoFactor) |
|||
{ |
|||
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe }); |
|||
} |
|||
if (result.Succeeded) |
|||
{ |
|||
string anonymousBasketId = Request.Cookies[Constants.BASKET_COOKIENAME]; |
|||
if (!String.IsNullOrEmpty(anonymousBasketId)) |
|||
{ |
|||
await _basketService.TransferBasketAsync(anonymousBasketId, model.Email); |
|||
Response.Cookies.Delete(Constants.BASKET_COOKIENAME); |
|||
} |
|||
return RedirectToLocal(returnUrl); |
|||
} |
|||
ModelState.AddModelError(string.Empty, "Invalid login attempt."); |
|||
return View(model); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[AllowAnonymous] |
|||
public async Task<IActionResult> LoginWith2fa(bool rememberMe, string returnUrl = null) |
|||
{ |
|||
// Ensure the user has gone through the username & password screen first
|
|||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); |
|||
|
|||
if (user == null) |
|||
{ |
|||
throw new ApplicationException($"Unable to load two-factor authentication user."); |
|||
} |
|||
|
|||
var model = new LoginWith2faViewModel { RememberMe = rememberMe }; |
|||
ViewData["ReturnUrl"] = returnUrl; |
|||
|
|||
return View(model); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[AllowAnonymous] |
|||
[ValidateAntiForgeryToken] |
|||
public async Task<IActionResult> LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null) |
|||
{ |
|||
if (!ModelState.IsValid) |
|||
{ |
|||
return View(model); |
|||
} |
|||
|
|||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); |
|||
if (user == null) |
|||
{ |
|||
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); |
|||
} |
|||
|
|||
var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); |
|||
|
|||
var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine); |
|||
|
|||
if (result.Succeeded) |
|||
{ |
|||
_logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id); |
|||
return RedirectToLocal(returnUrl); |
|||
} |
|||
else if (result.IsLockedOut) |
|||
{ |
|||
_logger.LogWarning("User with ID {UserId} account locked out.", user.Id); |
|||
return RedirectToAction(nameof(Lockout)); |
|||
} |
|||
else |
|||
{ |
|||
_logger.LogWarning("Invalid authenticator code entered for user with ID {UserId}.", user.Id); |
|||
ModelState.AddModelError(string.Empty, "Invalid authenticator code."); |
|||
return View(); |
|||
} |
|||
} |
|||
|
|||
[HttpGet] |
|||
[AllowAnonymous] |
|||
public IActionResult Lockout() |
|||
{ |
|||
return View(); |
|||
} |
|||
|
|||
|
|||
[HttpPost] |
|||
[ValidateAntiForgeryToken] |
|||
public async Task<ActionResult> SignOut() |
|||
{ |
|||
await _signInManager.SignOutAsync(); |
|||
|
|||
return RedirectToPage("/Index"); |
|||
} |
|||
|
|||
[AllowAnonymous] |
|||
[HttpGet] |
|||
public IActionResult Register() |
|||
{ |
|||
return View(); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[AllowAnonymous] |
|||
[ValidateAntiForgeryToken] |
|||
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null) |
|||
{ |
|||
if (ModelState.IsValid) |
|||
{ |
|||
var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; |
|||
var result = await _userManager.CreateAsync(user, model.Password); |
|||
if (result.Succeeded) |
|||
{ |
|||
await _signInManager.SignInAsync(user, isPersistent: false); |
|||
return RedirectToLocal(returnUrl); |
|||
} |
|||
AddErrors(result); |
|||
} |
|||
// If we got this far, something failed, redisplay form
|
|||
return View(model); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[AllowAnonymous] |
|||
public async Task<IActionResult> ConfirmEmail(string userId, string code) |
|||
{ |
|||
if (userId == null || code == null) |
|||
{ |
|||
return RedirectToPage("/Index"); |
|||
} |
|||
var user = await _userManager.FindByIdAsync(userId); |
|||
if (user == null) |
|||
{ |
|||
throw new ApplicationException($"Unable to load user with ID '{userId}'."); |
|||
} |
|||
var result = await _userManager.ConfirmEmailAsync(user, code); |
|||
return View(result.Succeeded ? "ConfirmEmail" : "Error"); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[AllowAnonymous] |
|||
public IActionResult ResetPassword(string code = null) |
|||
{ |
|||
if (code == null) |
|||
{ |
|||
throw new ApplicationException("A code must be supplied for password reset."); |
|||
} |
|||
var model = new ResetPasswordViewModel { Code = code }; |
|||
return View(model); |
|||
} |
|||
|
|||
private IActionResult RedirectToLocal(string returnUrl) |
|||
{ |
|||
if (Url.IsLocalUrl(returnUrl)) |
|||
{ |
|||
return Redirect(returnUrl); |
|||
} |
|||
else |
|||
{ |
|||
return RedirectToPage("/Index"); |
|||
} |
|||
} |
|||
|
|||
private void AddErrors(IdentityResult result) |
|||
{ |
|||
foreach (var error in result.Errors) |
|||
{ |
|||
ModelState.AddModelError("", error.Description); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue