51 lines
1.8 KiB
C#
51 lines
1.8 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Localization;
|
|
|
|
namespace gehGassi.Pwned
|
|
{
|
|
/// <summary>
|
|
/// An <see cref="IPasswordValidator{TUser}"/> for verifying a given password has not appeared in a data breach
|
|
/// </summary>
|
|
/// <typeparam name="TUser"></typeparam>
|
|
[ExcludeFromCodeCoverage]
|
|
public class PwnedPasswordValidator<TUser> : IPasswordValidator<TUser>
|
|
where TUser : class
|
|
{
|
|
private readonly IPwnedPasswordService _passwordService;
|
|
private readonly IStringLocalizer _localizer;
|
|
|
|
/// <summary>
|
|
/// Constructor for <see cref="IPwnedPasswordService"/>.
|
|
/// </summary>
|
|
/// <param name="passwordService"></param>
|
|
/// <param name="localizer">Instanz eines IStringLocalizer</param>
|
|
public PwnedPasswordValidator(IPwnedPasswordService passwordService, IStringLocalizer<PwnedBreachService> localizer)
|
|
{
|
|
_passwordService = passwordService;
|
|
_localizer = localizer;
|
|
}
|
|
|
|
///<inheritdoc/>
|
|
public async Task<IdentityResult> ValidateAsync(
|
|
UserManager<TUser> manager,
|
|
TUser user,
|
|
string password)
|
|
{
|
|
var (pwned, count) = await _passwordService.IsPasswordPwnedAsync(password);
|
|
|
|
if (pwned)
|
|
{
|
|
var errorMessage = _localizer["Err_PwnedPassword", count];
|
|
return await Task.FromResult(IdentityResult.Failed(new IdentityError
|
|
{
|
|
Code = "PwnedPassword",
|
|
Description = errorMessage
|
|
})).ConfigureAwait(false);
|
|
}
|
|
return await Task.FromResult(IdentityResult.Success).ConfigureAwait(false);
|
|
}
|
|
}
|
|
}
|