|
|
|
|
@ -1,14 +1,16 @@
|
|
|
|
|
using System;
|
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Security.Claims;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Volo.Abp.Account.Settings;
|
|
|
|
|
using Volo.Abp.Auditing;
|
|
|
|
|
using Volo.Abp.Application.Dtos;
|
|
|
|
|
using Volo.Abp.Identity;
|
|
|
|
|
using Volo.Abp.Settings;
|
|
|
|
|
using Volo.Abp.Uow;
|
|
|
|
|
using Volo.Abp.Validation;
|
|
|
|
|
using IdentityUser = Volo.Abp.Identity.IdentityUser;
|
|
|
|
|
|
|
|
|
|
@ -27,6 +29,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
|
|
|
|
|
[BindProperty]
|
|
|
|
|
public PostInput Input { get; set; }
|
|
|
|
|
|
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
|
|
|
public bool IsExternalLogin { get; set; }
|
|
|
|
|
|
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
|
|
|
public string ExternalLoginAuthSchema { get; set; }
|
|
|
|
|
|
|
|
|
|
public RegisterModel(IAccountAppService accountAppService)
|
|
|
|
|
{
|
|
|
|
|
AccountAppService = accountAppService;
|
|
|
|
|
@ -35,34 +43,141 @@ namespace Volo.Abp.Account.Web.Pages.Account
|
|
|
|
|
public virtual async Task<IActionResult> OnGetAsync()
|
|
|
|
|
{
|
|
|
|
|
await CheckSelfRegistrationAsync();
|
|
|
|
|
|
|
|
|
|
await TrySetEmailAsync();
|
|
|
|
|
return Page();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual async Task<IActionResult> OnPostAsync()
|
|
|
|
|
private async Task TrySetEmailAsync()
|
|
|
|
|
{
|
|
|
|
|
ValidateModel();
|
|
|
|
|
if (IsExternalLogin)
|
|
|
|
|
{
|
|
|
|
|
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
|
|
|
|
|
if (externalLoginInfo == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!externalLoginInfo.Principal.Identities.Any())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var identity = externalLoginInfo.Principal.Identities.First();
|
|
|
|
|
var emailClaim = identity.FindFirst(ClaimTypes.Email);
|
|
|
|
|
|
|
|
|
|
if (emailClaim == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Input = new PostInput {EmailAddress = emailClaim.Value};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual async Task<IActionResult> OnPostAsync()
|
|
|
|
|
{
|
|
|
|
|
await CheckSelfRegistrationAsync();
|
|
|
|
|
|
|
|
|
|
var registerDto = new RegisterDto
|
|
|
|
|
var registerDto = new RegisterDto()
|
|
|
|
|
{
|
|
|
|
|
AppName = "MVC",
|
|
|
|
|
EmailAddress = Input.EmailAddress,
|
|
|
|
|
Password = Input.Password,
|
|
|
|
|
UserName = Input.UserName
|
|
|
|
|
AppName = "MVC"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var userDto = await AccountAppService.RegisterAsync(registerDto);
|
|
|
|
|
var user = await UserManager.GetByIdAsync(userDto.Id);
|
|
|
|
|
if (IsExternalLogin)
|
|
|
|
|
{
|
|
|
|
|
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
|
|
|
|
|
if (externalLoginInfo == null)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogWarning("External login info is not available");
|
|
|
|
|
return RedirectToPage("./Login");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
registerDto.EmailAddress = Input.EmailAddress;
|
|
|
|
|
registerDto.UserName = Input.EmailAddress;
|
|
|
|
|
registerDto.Password = GeneratePassword();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ValidateModel();
|
|
|
|
|
|
|
|
|
|
await UserManager.SetEmailAsync(user, Input.EmailAddress);
|
|
|
|
|
registerDto.EmailAddress = Input.EmailAddress;
|
|
|
|
|
registerDto.Password = Input.Password;
|
|
|
|
|
registerDto.UserName = Input.UserName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var userDto = await AccountAppService.RegisterAsync(registerDto);
|
|
|
|
|
var user = await UserManager.GetByIdAsync(userDto.Id);
|
|
|
|
|
await SignInManager.SignInAsync(user, isPersistent: false);
|
|
|
|
|
|
|
|
|
|
if (IsExternalLogin)
|
|
|
|
|
{
|
|
|
|
|
await AddToUserLogins(user);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Redirect(ReturnUrl ?? "~/"); //TODO: How to ensure safety? IdentityServer requires it however it should be checked somehow!
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual async Task AddToUserLogins(IdentityUser user)
|
|
|
|
|
{
|
|
|
|
|
var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
|
|
|
|
|
|
|
|
|
|
var userLoginAlreadyExists = user.Logins.Any(x =>
|
|
|
|
|
x.TenantId == user.TenantId &&
|
|
|
|
|
x.LoginProvider == externalLoginInfo.LoginProvider &&
|
|
|
|
|
x.ProviderKey == externalLoginInfo.ProviderKey);
|
|
|
|
|
|
|
|
|
|
if (!userLoginAlreadyExists)
|
|
|
|
|
{
|
|
|
|
|
user.AddLogin(new UserLoginInfo(
|
|
|
|
|
externalLoginInfo.LoginProvider,
|
|
|
|
|
externalLoginInfo.ProviderKey,
|
|
|
|
|
externalLoginInfo.ProviderDisplayName
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual string GeneratePassword()
|
|
|
|
|
{
|
|
|
|
|
var random = new Random();
|
|
|
|
|
var options = UserManager.Options.Password;
|
|
|
|
|
int length = random.Next(options.RequiredLength, IdentityUserConsts.MaxPasswordLength - 1);
|
|
|
|
|
|
|
|
|
|
bool nonAlphanumeric = options.RequireNonAlphanumeric;
|
|
|
|
|
bool digit = options.RequireDigit;
|
|
|
|
|
bool lowercase = options.RequireLowercase;
|
|
|
|
|
bool uppercase = options.RequireUppercase;
|
|
|
|
|
|
|
|
|
|
StringBuilder password = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
while (password.Length < length)
|
|
|
|
|
{
|
|
|
|
|
char c = (char)random.Next(32, 126);
|
|
|
|
|
|
|
|
|
|
password.Append(c);
|
|
|
|
|
|
|
|
|
|
if (char.IsDigit(c))
|
|
|
|
|
digit = false;
|
|
|
|
|
else if (char.IsLower(c))
|
|
|
|
|
lowercase = false;
|
|
|
|
|
else if (char.IsUpper(c))
|
|
|
|
|
uppercase = false;
|
|
|
|
|
else if (!char.IsLetterOrDigit(c))
|
|
|
|
|
nonAlphanumeric = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nonAlphanumeric)
|
|
|
|
|
password.Append((char)random.Next(33, 48));
|
|
|
|
|
if (digit)
|
|
|
|
|
password.Append((char)random.Next(48, 58));
|
|
|
|
|
if (lowercase)
|
|
|
|
|
password.Append((char)random.Next(97, 123));
|
|
|
|
|
if (uppercase)
|
|
|
|
|
password.Append((char)random.Next(65, 91));
|
|
|
|
|
|
|
|
|
|
return password.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual async Task CheckSelfRegistrationAsync()
|
|
|
|
|
{
|
|
|
|
|
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) ||
|
|
|
|
|
|