mirror of
https://github.com/hmaxnl/DotBased.git
synced 2025-01-18 18:14:20 +01:00
[ADD] Pwd validator, reworked classes
This commit is contained in:
parent
ebfafa2f29
commit
172d5838e7
|
@ -21,9 +21,11 @@ public static class AuthorityProviderExtensions
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
services.Configure<AuthorityOptions>(optionsAction);
|
services.Configure<AuthorityOptions>(optionsAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
services.TryAddScoped<ICryptographer, Cryptographer>();
|
services.TryAddScoped<ICryptographer, Cryptographer>();
|
||||||
services.TryAddScoped<IPasswordHasher, PasswordHasher>();
|
services.TryAddScoped<IPasswordHasher, PasswordHasher>();
|
||||||
services.TryAddScoped<IPasswordValidator<TUser>, PasswordOptionsValidator<TUser>>();
|
services.TryAddScoped<IPasswordValidator<TUser>, PasswordOptionsValidator<TUser>>();
|
||||||
|
services.TryAddScoped<IPasswordValidator<TUser>, PasswordEqualsValidator<TUser>>();
|
||||||
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
|
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
|
||||||
/*services.TryAddScoped<IEmailVerifier, EmailVerifier>();
|
/*services.TryAddScoped<IEmailVerifier, EmailVerifier>();
|
||||||
services.TryAddScoped<IPhoneNumberVerifier, PhoneNumberVerifier>();
|
services.TryAddScoped<IPhoneNumberVerifier, PhoneNumberVerifier>();
|
||||||
|
@ -44,4 +46,20 @@ public static class AuthorityProviderExtensions
|
||||||
{
|
{
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Type GetBaseGenericArgumentType<TModel>(Type baseType)
|
||||||
|
{
|
||||||
|
var userGenericBaseTypeDefinition = typeof(TModel).BaseType?.GetGenericTypeDefinition();
|
||||||
|
if (userGenericBaseTypeDefinition != null && userGenericBaseTypeDefinition == baseType)
|
||||||
|
{
|
||||||
|
var userBaseGenericArguments = userGenericBaseTypeDefinition.GetGenericArguments();
|
||||||
|
if (userBaseGenericArguments.Length <= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Base implementation does not have the required generic argument.", nameof(TModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
return userBaseGenericArguments[0];
|
||||||
|
}
|
||||||
|
throw new ArgumentException($"Given object {typeof(TModel).Name} does not have the base implementation type of: {baseType.Name}", nameof(TModel));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,10 +16,13 @@ public class AuthorityUser : AuthorityUser<Guid>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AuthorityUser<TKey> where TKey : IEquatable<TKey>
|
public abstract class AuthorityUser<TKey> : AuthorityUserBase where TKey : IEquatable<TKey>
|
||||||
{
|
{
|
||||||
public TKey Id { get; set; }
|
public TKey Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AuthorityUserBase
|
||||||
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
public bool Confirmed { get; set; }
|
public bool Confirmed { get; set; }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
namespace DotBased.AspNet.Authority.Repositories;
|
namespace DotBased.AspNet.Authority.Repositories;
|
||||||
|
|
||||||
public interface IUserRepository<TUser, TId> where TUser : class where TId : IEquatable<TId>
|
public interface IUserRepository<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
public Task<TUser?> GetUserByIdAsync(TId id);
|
public Task<TUser?> GetUserByIdAsync(string id);
|
||||||
public Task<TId> GetUserIdAsync(TUser user);
|
public Task<string> GetUserIdAsync(TUser user);
|
||||||
public Task SetVersion(TUser user, long version);
|
public Task SetVersion(TUser user, long version);
|
||||||
public Task SetSecurityVersion(TUser user, long version);
|
public Task SetSecurityVersion(TUser user, long version);
|
||||||
}
|
}
|
|
@ -33,6 +33,7 @@ public class AuthorityManager
|
||||||
|
|
||||||
public long GenerateVersion() => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
public long GenerateVersion() => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Protect or unprotect the properties with the <see cref="ProtectAttribute"/>
|
/// Protect or unprotect the properties with the <see cref="ProtectAttribute"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
|
using DotBased.AspNet.Authority.Crypto;
|
||||||
|
using DotBased.AspNet.Authority.Models.Validation;
|
||||||
|
using DotBased.AspNet.Authority.Repositories;
|
||||||
using DotBased.AspNet.Authority.Validators;
|
using DotBased.AspNet.Authority.Validators;
|
||||||
using DotBased.Logging;
|
using DotBased.Logging;
|
||||||
|
|
||||||
namespace DotBased.AspNet.Authority.Services;
|
namespace DotBased.AspNet.Authority.Services;
|
||||||
|
|
||||||
public class AuthorityUserManager<TUser>
|
public class AuthorityUserManager<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
public AuthorityUserManager(
|
public AuthorityUserManager(
|
||||||
AuthorityManager manager,
|
AuthorityManager manager,
|
||||||
|
IUserRepository<TUser> userRepository,
|
||||||
|
IPasswordHasher passwordHasher,
|
||||||
IEnumerable<IPasswordValidator<TUser>>? passwordValidators,
|
IEnumerable<IPasswordValidator<TUser>>? passwordValidators,
|
||||||
IEnumerable<IUserValidator<TUser>>? userValidators)
|
IEnumerable<IUserValidator<TUser>>? userValidators)
|
||||||
{
|
{
|
||||||
_logger = LogService.RegisterLogger<AuthorityUserManager<TUser>>();
|
_logger = LogService.RegisterLogger<AuthorityUserManager<TUser>>();
|
||||||
AuthorityManager = manager;
|
AuthorityManager = manager;
|
||||||
|
UserRepository = userRepository;
|
||||||
|
PasswordHasher = passwordHasher;
|
||||||
if (passwordValidators != null)
|
if (passwordValidators != null)
|
||||||
PasswordValidators = passwordValidators;
|
PasswordValidators = passwordValidators;
|
||||||
if (userValidators != null)
|
if (userValidators != null)
|
||||||
|
@ -20,9 +27,24 @@ public class AuthorityUserManager<TUser>
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
public AuthorityManager AuthorityManager { get; }
|
public AuthorityManager AuthorityManager { get; }
|
||||||
|
public IUserRepository<TUser> UserRepository { get; }
|
||||||
|
|
||||||
|
public IPasswordHasher PasswordHasher { get; }
|
||||||
|
|
||||||
public IEnumerable<IPasswordValidator<TUser>> PasswordValidators { get; } = [];
|
public IEnumerable<IPasswordValidator<TUser>> PasswordValidators { get; } = [];
|
||||||
public IEnumerable<IUserValidator<TUser>> UserValidators { get; } = [];
|
public IEnumerable<IUserValidator<TUser>> UserValidators { get; } = [];
|
||||||
|
|
||||||
|
public async Task<ValidationResult> ValidatePasswordAsync(TUser user, string password)
|
||||||
|
{
|
||||||
|
List<ValidationError> errors = [];
|
||||||
|
foreach (var validator in PasswordValidators)
|
||||||
|
{
|
||||||
|
var validatorResult = await validator.ValidatePasswordAsync(this, user, password);
|
||||||
|
if (!validatorResult.Success)
|
||||||
|
{
|
||||||
|
errors.AddRange(validatorResult.Errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.Count > 0 ? ValidationResult.Failed(errors) : ValidationResult.Ok();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ using DotBased.AspNet.Authority.Services;
|
||||||
|
|
||||||
namespace DotBased.AspNet.Authority.Validators;
|
namespace DotBased.AspNet.Authority.Validators;
|
||||||
|
|
||||||
public interface IPasswordValidator<TUser>
|
public interface IPasswordValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
public Task<ValidationResult> ValidatePasswordAsync(AuthorityUserManager<TUser> userManager, string password);
|
public Task<ValidationResult> ValidatePasswordAsync(AuthorityUserManager<TUser> userManager, TUser user, string password);
|
||||||
}
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using DotBased.AspNet.Authority.Models.Authority;
|
||||||
|
using DotBased.AspNet.Authority.Models.Validation;
|
||||||
|
using DotBased.AspNet.Authority.Services;
|
||||||
|
|
||||||
|
namespace DotBased.AspNet.Authority.Validators;
|
||||||
|
|
||||||
|
public class PasswordEqualsValidator<TUser> : IPasswordValidator<TUser> where TUser : class
|
||||||
|
{
|
||||||
|
private const string ValidatorId = "Authority.Validator.Password.Equals";
|
||||||
|
private const string ValidationBase = "Authority.Validation.Password";
|
||||||
|
public async Task<ValidationResult> ValidatePasswordAsync(AuthorityUserManager<TUser> userManager, TUser user, string password)
|
||||||
|
{
|
||||||
|
if (user == null || user is not AuthorityUserBase authorityUser)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid user given!", nameof(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ValidationError> errors = [];
|
||||||
|
var hashedPassword = await userManager.PasswordHasher.HashPasswordAsync(password);
|
||||||
|
if (authorityUser.PasswordHash != null && authorityUser.PasswordHash.Equals(hashedPassword, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
errors.Add(new ValidationError(ValidatorId, $"{ValidationBase}.InUse", "User uses this password already!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Count > 0 ? ValidationResult.Failed(errors) : ValidationResult.Ok();
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,12 +8,12 @@ namespace DotBased.AspNet.Authority.Validators;
|
||||||
/// Validates the password against the options that is configured.
|
/// Validates the password against the options that is configured.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TUser">The user model used.</typeparam>
|
/// <typeparam name="TUser">The user model used.</typeparam>
|
||||||
public class PasswordOptionsValidator<TUser> : IPasswordValidator<TUser>
|
public class PasswordOptionsValidator<TUser> : IPasswordValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
private const string ValidatorId = "Authority.Validator.Password.Options";
|
private const string ValidatorId = "Authority.Validator.Password.Options";
|
||||||
private const string ValidationBase = "Authority.Validation.Password";
|
private const string ValidationBase = "Authority.Validation.Password";
|
||||||
|
|
||||||
public async Task<ValidationResult> ValidatePasswordAsync(AuthorityUserManager<TUser> userManager, string password)
|
public async Task<ValidationResult> ValidatePasswordAsync(AuthorityUserManager<TUser> userManager, TUser user, string password)
|
||||||
{
|
{
|
||||||
if (userManager == null)
|
if (userManager == null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user