diff --git a/backend/ee-repo-ref.txt b/backend/ee-repo-ref.txt index 3b37119381..8ba0c97c0b 100644 --- a/backend/ee-repo-ref.txt +++ b/backend/ee-repo-ref.txt @@ -1 +1 @@ -3b6bd2b15d9bddb0bb8f1de08b30b897db0415b4 +d29a7c0dad120e137105b1186d0bbe3ea1504b5d diff --git a/backend/tests/job_token_scopes.rs b/backend/tests/job_token_scopes.rs index f805168bfa..71ecaa444e 100644 --- a/backend/tests/job_token_scopes.rs +++ b/backend/tests/job_token_scopes.rs @@ -363,7 +363,8 @@ async fn test_deploy_without_the_field_keeps_the_restriction( Ok(()) } -/// The OIDC `job_token_scopes` claim states the scopes of the token that asked for it. +/// The OIDC `job_token_scopes` claim states the scopes of the token that asked for it, in a +/// payload that strict JSON parsers accept (no duplicate `email` key). #[cfg(all(feature = "enterprise", feature = "private", feature = "openidconnect"))] #[sqlx::test(fixtures("base"))] async fn test_oidc_claim_carries_the_presented_scopes(db: Pool) -> anyhow::Result<()> { @@ -404,10 +405,12 @@ async fn test_oidc_claim_carries_the_presented_scopes(db: Pool) -> any let status = resp.status(); let id_token = resp.text().await?; assert_eq!(status, StatusCode::OK, "{id_token}"); - let payload = id_token.split('.').nth(1).expect("a JWT payload"); - let claims: serde_json::Value = serde_json::from_slice( - &base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(payload)?, - )?; + let payload = base64::engine::general_purpose::URL_SAFE_NO_PAD + .decode(id_token.split('.').nth(1).expect("a JWT payload"))?; + // serde_json keeps the last of duplicate keys, so count them on the raw payload. + let raw = String::from_utf8(payload.clone())?; + assert_eq!(raw.matches("\"email\":").count(), 1, "{raw}"); + let claims: serde_json::Value = serde_json::from_slice(&payload)?; assert_eq!(claims["job_token_scopes"], expected, "{job}"); }