1
0
mirror of https://github.com/bitwarden/server synced 2026-02-11 14:03:24 +00:00

Initial refactor

This commit is contained in:
Anders Åberg
2025-09-25 10:28:48 +02:00
parent d2c2ae5b4d
commit ba0723c0ed
6 changed files with 39 additions and 17 deletions

View File

@@ -26,7 +26,7 @@ public class UserDecryptionOptions : ResponseModel
/// Gets or sets the WebAuthn PRF decryption keys.
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public WebAuthnPrfDecryptionOption? WebAuthnPrfOption { get; set; }
public WebAuthnPrfDecryptionOption[]? WebAuthnPrfOptions { get; set; }
/// <summary>
/// Gets or sets information regarding this users trusted device decryption setup.
@@ -45,13 +45,19 @@ public class WebAuthnPrfDecryptionOption
{
public string EncryptedPrivateKey { get; }
public string EncryptedUserKey { get; }
public string CredentialId { get; }
public string[] Transports { get; }
public WebAuthnPrfDecryptionOption(
string encryptedPrivateKey,
string encryptedUserKey)
string encryptedUserKey,
string credentialId,
string[]? transports = null)
{
EncryptedPrivateKey = encryptedPrivateKey;
EncryptedUserKey = encryptedUserKey;
CredentialId = credentialId;
Transports = transports ?? [];
}
}

View File

@@ -11,6 +11,6 @@ public interface IUserDecryptionOptionsBuilder
IUserDecryptionOptionsBuilder ForUser(User user);
IUserDecryptionOptionsBuilder WithDevice(Device device);
IUserDecryptionOptionsBuilder WithSso(SsoConfig ssoConfig);
IUserDecryptionOptionsBuilder WithWebAuthnLoginCredential(WebAuthnCredential credential);
IUserDecryptionOptionsBuilder WithWebAuthnLoginCredentials(IEnumerable<WebAuthnCredential> credentials);
Task<UserDecryptionOptions> BuildAsync();
}

View File

@@ -30,6 +30,7 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
private readonly IDataProtectorTokenFactory<WebAuthnLoginAssertionOptionsTokenable> _assertionOptionsDataProtector;
private readonly IAssertWebAuthnLoginCredentialCommand _assertWebAuthnLoginCredentialCommand;
private readonly IDeviceValidator _deviceValidator;
private readonly IWebAuthnCredentialRepository _webAuthnCredentialRepository;
public WebAuthnGrantValidator(
UserManager<User> userManager,
@@ -50,7 +51,8 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
IAssertWebAuthnLoginCredentialCommand assertWebAuthnLoginCredentialCommand,
IPolicyRequirementQuery policyRequirementQuery,
IAuthRequestRepository authRequestRepository,
IMailService mailService)
IMailService mailService,
IWebAuthnCredentialRepository webAuthnCredentialRepository)
: base(
userManager,
userService,
@@ -73,6 +75,7 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
_assertionOptionsDataProtector = assertionOptionsDataProtector;
_assertWebAuthnLoginCredentialCommand = assertWebAuthnLoginCredentialCommand;
_deviceValidator = deviceValidator;
_webAuthnCredentialRepository = webAuthnCredentialRepository;
}
string IExtensionGrantValidator.GrantType => "webauthn";
@@ -98,7 +101,8 @@ public class WebAuthnGrantValidator : BaseRequestValidator<ExtensionGrantValidat
}
var (user, credential) = await _assertWebAuthnLoginCredentialCommand.AssertWebAuthnLoginCredential(token.Options, deviceResponse);
UserDecryptionOptionsBuilder.WithWebAuthnLoginCredential(credential);
var allCredentials = await _webAuthnCredentialRepository.GetManyByUserIdAsync(user.Id);
UserDecryptionOptionsBuilder.WithWebAuthnLoginCredentials(allCredentials);
await ValidateAsync(context, context.Request, new CustomValidatorRequestContext { User = user });
}

View File

@@ -57,15 +57,25 @@ public class UserDecryptionOptionsBuilder : IUserDecryptionOptionsBuilder
public IUserDecryptionOptionsBuilder WithDevice(Device device)
{
_device = device;
_device = device;>
return this;
}
public IUserDecryptionOptionsBuilder WithWebAuthnLoginCredential(WebAuthnCredential credential)
public IUserDecryptionOptionsBuilder WithWebAuthnLoginCredentials(IEnumerable<WebAuthnCredential> credentials)
{
if (credential.GetPrfStatus() == WebAuthnPrfStatus.Enabled)
var prfEnabledCredentials = credentials
.Where(c => c.GetPrfStatus() == WebAuthnPrfStatus.Enabled)
.Select(c => new WebAuthnPrfDecryptionOption(
c.EncryptedPrivateKey,
c.EncryptedUserKey,
c.CredentialId,
[] // Stored credentials currently lack Transports, just send an empty array for now
))
.ToArray();
if (prfEnabledCredentials.Length > 0)
{
_options.WebAuthnPrfOption = new WebAuthnPrfDecryptionOption(credential.EncryptedPrivateKey, credential.EncryptedUserKey);
_options.WebAuthnPrfOptions = prfEnabledCredentials;
}
return this;
}