Browse Source

Refactor: Extract class RandomPasswordGenerator

pull/4979/head
Halil İbrahim Kalkan 6 years ago
parent
commit
e98084fdf6
  1. 47
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs
  2. 84
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RandomPasswordGenerator.cs
  3. 2
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityClaimTypeManager_Tests.cs
  4. 23
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RandomPasswordGenerator_Tests.cs

47
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs

@ -19,6 +19,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
public class RegisterModel : AccountPageModel public class RegisterModel : AccountPageModel
{ {
protected IAccountAppService AccountAppService { get; } protected IAccountAppService AccountAppService { get; }
protected RandomPasswordGenerator RandomPasswordGenerator { get; }
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public string ReturnUrl { get; set; } public string ReturnUrl { get; set; }
@ -35,9 +36,10 @@ namespace Volo.Abp.Account.Web.Pages.Account
[BindProperty(SupportsGet = true)] [BindProperty(SupportsGet = true)]
public string ExternalLoginAuthSchema { get; set; } public string ExternalLoginAuthSchema { get; set; }
public RegisterModel(IAccountAppService accountAppService) public RegisterModel(IAccountAppService accountAppService, RandomPasswordGenerator randomPasswordGenerator)
{ {
AccountAppService = accountAppService; AccountAppService = accountAppService;
RandomPasswordGenerator = randomPasswordGenerator;
} }
public virtual async Task<IActionResult> OnGetAsync() public virtual async Task<IActionResult> OnGetAsync()
@ -94,7 +96,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
registerDto.EmailAddress = Input.EmailAddress; registerDto.EmailAddress = Input.EmailAddress;
registerDto.UserName = Input.EmailAddress; registerDto.UserName = Input.EmailAddress;
registerDto.Password = GeneratePassword(); registerDto.Password = await RandomPasswordGenerator.CreateAsync();
} }
else else
{ {
@ -137,47 +139,6 @@ namespace Volo.Abp.Account.Web.Pages.Account
} }
} }
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() protected virtual async Task CheckSelfRegistrationAsync()
{ {
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) || if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) ||

84
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/RandomPasswordGenerator.cs

@ -0,0 +1,84 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Identity
{
/// <summary>
/// This class can be used to generate random password
/// based on the rules defined in the <see cref="IdentityOptions"/>.
/// </summary>
public class RandomPasswordGenerator : ITransientDependency
{
public const int MinPasswordLength = 32;
protected IdentityOptions Options { get; }
protected Random Random { get; }
public RandomPasswordGenerator(IOptions<IdentityOptions> options)
{
Options = options.Value;
Random = new Random();
}
public virtual Task<string> CreateAsync()
{
var nonAlphanumeric = Options.Password.RequireNonAlphanumeric;
var digit = Options.Password.RequireDigit;
var lowercase = Options.Password.RequireLowercase;
var uppercase = Options.Password.RequireUppercase;
var passwordBuilder = new StringBuilder();
var length = Math.Max(Options.Password.RequiredLength, MinPasswordLength);
while (passwordBuilder.Length < length)
{
var nextChar = (char)Random.Next(32, 126);
passwordBuilder.Append(nextChar);
if (char.IsDigit(nextChar))
{
digit = false;
}
else if (char.IsLower(nextChar))
{
lowercase = false;
}
else if (char.IsUpper(nextChar))
{
uppercase = false;
}
else if (!char.IsLetterOrDigit(nextChar))
{
nonAlphanumeric = false;
}
}
if (nonAlphanumeric)
{
passwordBuilder.Append((char)Random.Next(33, 48));
}
if (digit)
{
passwordBuilder.Append((char)Random.Next(48, 58));
}
if (lowercase)
{
passwordBuilder.Append((char)Random.Next(97, 123));
}
if (uppercase)
{
passwordBuilder.Append((char)Random.Next(65, 91));
}
return Task.FromResult(passwordBuilder.ToString());
}
}
}

2
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityClaimTypeManager_Tests.cs

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Shouldly; using Shouldly;
using Xunit; using Xunit;

23
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/RandomPasswordGenerator_Tests.cs

@ -0,0 +1,23 @@
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace Volo.Abp.Identity
{
public class RandomPasswordGenerator_Tests : AbpIdentityDomainTestBase
{
private readonly RandomPasswordGenerator _randomPasswordGenerator;
public RandomPasswordGenerator_Tests()
{
_randomPasswordGenerator = GetRequiredService<RandomPasswordGenerator>();
}
[Fact]
public async Task CreateAsync()
{
var password = await _randomPasswordGenerator.CreateAsync();
password.Length.ShouldBeGreaterThanOrEqualTo(RandomPasswordGenerator.MinPasswordLength);
}
}
}
Loading…
Cancel
Save