fix(oauth): indigo client send empty assertions

Lewis: May this revision serve well! <lu5a@proton.me>
This commit is contained in:
Lewis
2026-04-17 14:14:03 +03:00
committed by Tangled
parent 3e7a199736
commit a20e4e05e6
3 changed files with 51 additions and 8 deletions

View File

@@ -138,21 +138,29 @@ pub async fn pushed_authorization_request(
}
fn determine_client_auth(request: &ParRequest) -> Result<ClientAuth, OAuthError> {
if let (Some(assertion), Some(assertion_type)) =
(&request.client_assertion, &request.client_assertion_type)
{
let assertion = request
.client_assertion
.as_deref()
.filter(|s| !s.is_empty());
let assertion_type = request
.client_assertion_type
.as_deref()
.filter(|s| !s.is_empty());
let secret = request.client_secret.as_deref().filter(|s| !s.is_empty());
if let (Some(assertion), Some(assertion_type)) = (assertion, assertion_type) {
if assertion_type != "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" {
return Err(OAuthError::InvalidRequest(
"Unsupported client_assertion_type".to_string(),
));
}
return Ok(ClientAuth::PrivateKeyJwt {
client_assertion: assertion.clone(),
client_assertion: assertion.to_string(),
});
}
if let Some(secret) = &request.client_secret {
if let Some(secret) = secret {
return Ok(ClientAuth::SecretPost {
client_secret: secret.clone(),
client_secret: secret.to_string(),
});
}
Ok(ClientAuth::None)

View File

@@ -138,13 +138,17 @@ impl TokenRequest {
}
};
let client_auth = match (self.client_assertion, self.client_assertion_type) {
let assertion = self.client_assertion.filter(|s| !s.is_empty());
let assertion_type = self.client_assertion_type.filter(|s| !s.is_empty());
let client_secret = self.client_secret.filter(|s| !s.is_empty());
let client_auth = match (assertion, assertion_type) {
(Some(assertion), Some(assertion_type)) => RequestClientAuth::PrivateKeyJwt {
client_id: self.client_id,
assertion,
assertion_type,
},
_ => match self.client_secret {
_ => match client_secret {
Some(secret) => RequestClientAuth::SecretPost {
client_id: self.client_id,
client_secret: secret,

View File

@@ -187,6 +187,37 @@ async fn test_par_and_authorize() {
);
}
#[tokio::test]
async fn test_par_public_client_empty_assertion_fields() {
let url = base_url().await;
let client = client();
let redirect_uri = "https://nels.evil.oauth.pet/callback";
let mock_client = setup_mock_client_metadata(redirect_uri).await;
let client_id = mock_client.uri();
let (_, code_challenge) = generate_pkce();
let par_res = client
.post(format!("{}/oauth/par", url))
.form(&[
("response_type", "code"),
("client_id", &client_id),
("redirect_uri", redirect_uri),
("code_challenge", &code_challenge),
("code_challenge_method", "S256"),
("scope", "atproto"),
("state", "test-state"),
("client_assertion", ""),
("client_assertion_type", ""),
])
.send()
.await
.unwrap();
assert_eq!(
par_res.status(),
StatusCode::CREATED,
"PAR with empty assertion fields from a public client should succeed"
);
}
#[tokio::test]
async fn test_full_oauth_flow() {
let url = base_url().await;