mirror of
https://github.com/bitwarden/server.git
synced 2026-02-03 23:53:19 +08:00
[PM-20592] [PM-22737] [PM-22738] Send grant validator (#6151)
**feat**: create `SendGrantValidator` and initial `SendPasswordValidator` for Send access grants **feat**: add feature flag to toggle Send grant validation logic **feat**: add Send client to Identity and update `ApiClient` to generic `Client` **feat**: register Send services in DI pipeline **feat**: add claims management support to `ProfileService` **feat**: distinguish between invalid grant and invalid request in `SendAccessGrantValidator` **fix**: update parsing of `send_id` from request **fix**: add early return when feature flag is disabled **fix**: rename and organize Send access scope and grant type **fix**: dotnet format **test**: add unit and integration tests for `SendGrantValidator` **test**: update OpenID configuration and API resource claims **doc**: move documentation to interfaces and update inline comments **chore**: add TODO for future support of `CustomGrantTypes`
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
using System.Security.Claims;
|
||||
using Bit.Core.Identity;
|
||||
using Bit.Core.KeyManagement.Sends;
|
||||
using Bit.Core.Tools.Models.Data;
|
||||
using Bit.Identity.IdentityServer.Enums;
|
||||
using Bit.Identity.IdentityServer.RequestValidators.SendAccess.Enums;
|
||||
using Duende.IdentityServer.Models;
|
||||
using Duende.IdentityServer.Validation;
|
||||
|
||||
namespace Bit.Identity.IdentityServer.RequestValidators.SendAccess;
|
||||
|
||||
public class SendPasswordRequestValidator(ISendPasswordHasher sendPasswordHasher) : ISendPasswordRequestValidator
|
||||
{
|
||||
private readonly ISendPasswordHasher _sendPasswordHasher = sendPasswordHasher;
|
||||
|
||||
/// <summary>
|
||||
/// static object that contains the error messages for the SendPasswordRequestValidator.
|
||||
/// </summary>
|
||||
private static Dictionary<SendPasswordValidatorResultTypes, string> _sendPasswordValidatorErrors = new()
|
||||
{
|
||||
{ SendPasswordValidatorResultTypes.RequestPasswordDoesNotMatch, "Request Password hash is invalid." }
|
||||
};
|
||||
|
||||
public GrantValidationResult ValidateSendPassword(ExtensionGrantValidationContext context, ResourcePassword resourcePassword, Guid sendId)
|
||||
{
|
||||
var request = context.Request.Raw;
|
||||
var clientHashedPassword = request.Get("password_hash");
|
||||
|
||||
if (string.IsNullOrEmpty(clientHashedPassword))
|
||||
{
|
||||
return new GrantValidationResult(
|
||||
TokenRequestErrors.InvalidRequest,
|
||||
errorDescription: _sendPasswordValidatorErrors[SendPasswordValidatorResultTypes.RequestPasswordDoesNotMatch]);
|
||||
}
|
||||
|
||||
var hashMatches = _sendPasswordHasher.PasswordHashMatches(
|
||||
resourcePassword.Hash, clientHashedPassword);
|
||||
|
||||
if (!hashMatches)
|
||||
{
|
||||
return new GrantValidationResult(
|
||||
TokenRequestErrors.InvalidGrant,
|
||||
errorDescription: _sendPasswordValidatorErrors[SendPasswordValidatorResultTypes.RequestPasswordDoesNotMatch]);
|
||||
}
|
||||
|
||||
return BuildSendPasswordSuccessResult(sendId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a successful validation result for the Send password send_access grant.
|
||||
/// </summary>
|
||||
/// <param name="sendId"></param>
|
||||
/// <returns></returns>
|
||||
private static GrantValidationResult BuildSendPasswordSuccessResult(Guid sendId)
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new(Claims.SendId, sendId.ToString()),
|
||||
new(Claims.Type, IdentityClientType.Send.ToString())
|
||||
};
|
||||
|
||||
return new GrantValidationResult(
|
||||
subject: sendId.ToString(),
|
||||
authenticationMethod: CustomGrantTypes.SendAccess,
|
||||
claims: claims);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user