| | | 1 | | using System; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using System.ComponentModel.DataAnnotations; |
| | | 4 | | using System.Linq; |
| | | 5 | | using System.Text; |
| | | 6 | | using System.Text.Encodings.Web; |
| | | 7 | | using System.Threading.Tasks; |
| | | 8 | | using Microsoft.AspNetCore.Authentication; |
| | | 9 | | using Microsoft.AspNetCore.Authorization; |
| | | 10 | | using Microsoft.AspNetCore.Identity; |
| | | 11 | | using Microsoft.AspNetCore.Identity.UI.Services; |
| | | 12 | | using Microsoft.AspNetCore.Mvc; |
| | | 13 | | using Microsoft.AspNetCore.Mvc.RazorPages; |
| | | 14 | | using Microsoft.AspNetCore.WebUtilities; |
| | | 15 | | using Microsoft.Extensions.Logging; |
| | | 16 | | using MUNity.Database.Context; |
| | | 17 | | using MUNity.Database.Models.User; |
| | | 18 | | using MUNity.Services; |
| | | 19 | | |
| | | 20 | | namespace MUNityCore.Areas.Identity.Pages.Account |
| | | 21 | | { |
| | | 22 | | [AllowAnonymous] |
| | | 23 | | public class RegisterModel : PageModel |
| | | 24 | | { |
| | | 25 | | private readonly SignInManager<MunityUser> _signInManager; |
| | | 26 | | private readonly UserManager<MunityUser> _userManager; |
| | | 27 | | private readonly ILogger<RegisterModel> _logger; |
| | | 28 | | private readonly IMailService _emailSender; |
| | | 29 | | private readonly MunityContext _dbContext; |
| | | 30 | | |
| | 0 | 31 | | public RegisterModel( |
| | 0 | 32 | | UserManager<MunityUser> userManager, |
| | 0 | 33 | | SignInManager<MunityUser> signInManager, |
| | 0 | 34 | | ILogger<RegisterModel> logger, |
| | 0 | 35 | | IMailService emailSender, |
| | 0 | 36 | | MunityContext context) |
| | 0 | 37 | | { |
| | 0 | 38 | | _userManager = userManager; |
| | 0 | 39 | | _signInManager = signInManager; |
| | 0 | 40 | | _logger = logger; |
| | 0 | 41 | | _emailSender = emailSender; |
| | 0 | 42 | | _dbContext = context; |
| | 0 | 43 | | } |
| | | 44 | | |
| | | 45 | | [BindProperty] |
| | 0 | 46 | | public InputModel Input { get; set; } |
| | | 47 | | |
| | | 48 | | public enum RegistrationStates |
| | | 49 | | { |
| | | 50 | | Waiting, |
| | | 51 | | Success, |
| | | 52 | | FollowedInvitation |
| | | 53 | | } |
| | | 54 | | |
| | 0 | 55 | | public string ReturnUrl { get; set; } |
| | | 56 | | |
| | 0 | 57 | | public IList<AuthenticationScheme> ExternalLogins { get; set; } |
| | | 58 | | |
| | | 59 | | public class InputModel |
| | | 60 | | { |
| | | 61 | | [Required] |
| | | 62 | | [MinLength(3)] |
| | | 63 | | [MaxLength(30)] |
| | 0 | 64 | | public string Username { get; set; } |
| | | 65 | | |
| | | 66 | | [Required] |
| | | 67 | | [EmailAddress] |
| | | 68 | | [Display(Name = "Email")] |
| | 0 | 69 | | public string Email { get; set; } |
| | | 70 | | |
| | | 71 | | [Required] |
| | | 72 | | [MaxLength(200)] |
| | 0 | 73 | | public string Forename { get; set; } |
| | | 74 | | |
| | | 75 | | [Required] |
| | | 76 | | [MaxLength(200)] |
| | 0 | 77 | | public string Lastname { get; set; } |
| | | 78 | | |
| | | 79 | | [Required] |
| | | 80 | | [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLen |
| | | 81 | | [DataType(DataType.Password)] |
| | | 82 | | [Display(Name = "Password")] |
| | 0 | 83 | | public string Password { get; set; } |
| | | 84 | | |
| | | 85 | | [Required] |
| | | 86 | | [Display(Name = "Birthday Year")] |
| | 0 | 87 | | public int BirthdayYear { get; set; } = DateTime.Now.Year - 13; |
| | | 88 | | |
| | | 89 | | [Required] |
| | | 90 | | [Display(Name = "Birthday Month")] |
| | 0 | 91 | | public int BirthdayMonth { get; set; } = 1; |
| | | 92 | | |
| | | 93 | | [Required] |
| | | 94 | | [Display(Name = "Birthday Day")] |
| | 0 | 95 | | public int BirthdayDay { get; set; } = 1; |
| | | 96 | | |
| | | 97 | | [Required] |
| | 0 | 98 | | public bool AcceptedAGB { get; set; } |
| | | 99 | | } |
| | | 100 | | |
| | | 101 | | public async Task OnGetAsync(string returnUrl = null) |
| | 0 | 102 | | { |
| | 0 | 103 | | ReturnUrl = returnUrl; |
| | 0 | 104 | | ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); |
| | 0 | 105 | | } |
| | | 106 | | |
| | | 107 | | public async Task<IActionResult> OnPostAsync(string returnUrl = null) |
| | 0 | 108 | | { |
| | 0 | 109 | | returnUrl ??= Url.Content("~/"); |
| | | 110 | | //ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); |
| | 0 | 111 | | if (ModelState.IsValid && Input.AcceptedAGB) |
| | 0 | 112 | | { |
| | 0 | 113 | | var userFound = await _userManager.FindByEmailAsync(Input.Email); |
| | 0 | 114 | | if (userFound != null) |
| | 0 | 115 | | { |
| | 0 | 116 | | if (userFound.IsShadowUser) |
| | 0 | 117 | | { |
| | 0 | 118 | | userFound.UserName = Input.Username; |
| | 0 | 119 | | userFound.Forename = Input.Forename; |
| | 0 | 120 | | userFound.Lastname = Input.Lastname; |
| | 0 | 121 | | await _userManager.RemovePasswordAsync(userFound); |
| | 0 | 122 | | await _userManager.ChangePasswordAsync(userFound, String.Empty, Input.Password); |
| | 0 | 123 | | _dbContext.Update(userFound); |
| | 0 | 124 | | _dbContext.SaveChanges(); |
| | 0 | 125 | | await _signInManager.SignInAsync(userFound, isPersistent: false); |
| | 0 | 126 | | return LocalRedirect(returnUrl); |
| | | 127 | | } |
| | 0 | 128 | | _logger.LogWarning($"User already exisits and was not a shadow user: {Input.Username}"); |
| | 0 | 129 | | } |
| | | 130 | | else |
| | 0 | 131 | | { |
| | 0 | 132 | | var user = new MunityUser |
| | 0 | 133 | | { |
| | 0 | 134 | | UserName = Input.Username, |
| | 0 | 135 | | Email = Input.Email, |
| | 0 | 136 | | RegistrationDate = DateTime.UtcNow, |
| | 0 | 137 | | Birthday = new DateOnly(Input.BirthdayYear, Input.BirthdayMonth, Input.BirthdayDay), |
| | 0 | 138 | | Forename = Input.Forename, |
| | 0 | 139 | | Lastname = Input.Lastname |
| | 0 | 140 | | }; |
| | | 141 | | |
| | 0 | 142 | | var result = await _userManager.CreateAsync(user, Input.Password); |
| | 0 | 143 | | if (result.Succeeded) |
| | 0 | 144 | | { |
| | 0 | 145 | | _logger.LogInformation("User created a new account with password."); |
| | | 146 | | |
| | | 147 | | //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); |
| | | 148 | | //code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); |
| | | 149 | | //var callbackUrl = Url.Page( |
| | | 150 | | // "/Account/ConfirmEmail", |
| | | 151 | | // pageHandler: null, |
| | | 152 | | // values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl }, |
| | | 153 | | // protocol: Request.Scheme); |
| | | 154 | | |
| | | 155 | | //await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", |
| | | 156 | | // $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>click |
| | | 157 | | |
| | | 158 | | //if (_userManager.Options.SignIn.RequireConfirmedAccount) |
| | | 159 | | //{ |
| | | 160 | | // return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = retur |
| | | 161 | | //} |
| | | 162 | | //else |
| | | 163 | | //{ |
| | 0 | 164 | | await _signInManager.SignInAsync(user, isPersistent: false); |
| | 0 | 165 | | return LocalRedirect(returnUrl); |
| | | 166 | | //} |
| | | 167 | | } |
| | 0 | 168 | | foreach (var error in result.Errors) |
| | 0 | 169 | | { |
| | 0 | 170 | | ModelState.AddModelError(string.Empty, error.Description); |
| | 0 | 171 | | } |
| | 0 | 172 | | } |
| | | 173 | | |
| | 0 | 174 | | } |
| | | 175 | | else |
| | 0 | 176 | | { |
| | 0 | 177 | | Console.WriteLine("AGB not accepted!"); |
| | 0 | 178 | | } |
| | | 179 | | |
| | | 180 | | // If we got this far, something failed, redisplay form |
| | 0 | 181 | | return Page(); |
| | 0 | 182 | | } |
| | | 183 | | } |
| | | 184 | | } |