| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- #nullable disable
- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using System.Linq;
- using System.Text;
- using System.Text.Encodings.Web;
- using System.Threading;
- using System.Threading.Tasks;
- using bitforum.Models.User;
- using Microsoft.AspNetCore.Authentication;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.AspNetCore.Identity.UI.Services;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.AspNetCore.Mvc.RazorPages;
- using Microsoft.AspNetCore.WebUtilities;
- using Microsoft.Extensions.Logging;
- namespace bitforum.Areas.Identity.Pages.Account
- {
- public class RegisterModel : PageModel
- {
- private readonly SignInManager<ApplicationUser> _signInManager;
- private readonly UserManager<ApplicationUser> _userManager;
- private readonly IUserStore<ApplicationUser> _userStore;
- private readonly IUserEmailStore<ApplicationUser> _emailStore;
- private readonly ILogger<RegisterModel> _logger;
- private readonly IEmailSender _emailSender;
- public RegisterModel(
- UserManager<ApplicationUser> userManager,
- IUserStore<ApplicationUser> userStore,
- SignInManager<ApplicationUser> signInManager,
- ILogger<RegisterModel> logger,
- IEmailSender emailSender)
- {
- _userManager = userManager;
- _userStore = userStore;
- _emailStore = GetEmailStore();
- _signInManager = signInManager;
- _logger = logger;
- _emailSender = emailSender;
- }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- [BindProperty]
- public InputModel Input { get; set; }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- public string ReturnUrl { get; set; }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- public IList<AuthenticationScheme> ExternalLogins { get; set; }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- public class InputModel
- {
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- [Required]
- [EmailAddress]
- [Display(Name = "Email")]
- public string Email { get; set; }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- [Required]
- [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
- [DataType(DataType.Password)]
- [Display(Name = "Password")]
- public string Password { get; set; }
- /// <summary>
- /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
- /// directly from your code. This API may change or be removed in future releases.
- /// </summary>
- [DataType(DataType.Password)]
- [Display(Name = "Confirm password")]
- [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
- public string ConfirmPassword { get; set; }
- }
- public async Task OnGetAsync(string returnUrl = null)
- {
- ReturnUrl = returnUrl;
- ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
- }
- public async Task<IActionResult> OnPostAsync(string returnUrl = null)
- {
- returnUrl ??= Url.Content("~/");
- ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
- if (ModelState.IsValid)
- {
- var user = CreateUser();
- await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
- await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
- var result = await _userManager.CreateAsync(user, Input.Password);
- if (result.Succeeded)
- {
- _logger.LogInformation("User created a new account with password.");
- var userId = await _userManager.GetUserIdAsync(user);
- var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
- code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
- var callbackUrl = Url.Page(
- "/Account/ConfirmEmail",
- pageHandler: null,
- values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
- protocol: Request.Scheme);
- await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
- $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
- if (_userManager.Options.SignIn.RequireConfirmedAccount)
- {
- return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
- }
- else
- {
- await _signInManager.SignInAsync(user, isPersistent: false);
- return LocalRedirect(returnUrl);
- }
- }
- foreach (var error in result.Errors)
- {
- ModelState.AddModelError(string.Empty, error.Description);
- }
- }
- // If we got this far, something failed, redisplay form
- return Page();
- }
- private ApplicationUser CreateUser()
- {
- try
- {
- return Activator.CreateInstance<ApplicationUser>();
- }
- catch
- {
- throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " +
- $"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
- $"override the register page in /Areas/Identity/Pages/Account/Register.cshtml");
- }
- }
- private IUserEmailStore<ApplicationUser> GetEmailStore()
- {
- if (!_userManager.SupportsUserEmail)
- {
- throw new NotSupportedException("The default UI requires a user store with email support.");
- }
- return (IUserEmailStore<ApplicationUser>)_userStore;
- }
- }
- }
|