Allow setting a client_uri for static clients in the config (#5874)

This commit is contained in:
Quentin Gliech
2026-07-24 16:48:07 +02:00
committed by GitHub
9 changed files with 60 additions and 25 deletions
+2
View File
@@ -416,6 +416,7 @@ pub async fn config_sync(
let client_secret = client.client_secret().await?;
let client_name = client.client_name.as_ref();
let client_uri = client.client_uri.as_ref();
let client_auth_method = client.client_auth_method();
let jwks = client.jwks.as_ref();
let jwks_uri = client.jwks_uri.as_ref();
@@ -429,6 +430,7 @@ pub async fn config_sync(
.upsert_static(
client.client_id,
client_name.cloned(),
client_uri.cloned(),
client_auth_method,
encrypted_client_secret,
jwks.cloned(),
+14
View File
@@ -72,6 +72,10 @@ pub struct ClientConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub client_name: Option<String>,
/// Client URL for user-facing information about the client
#[serde(skip_serializing_if = "Option::is_none")]
pub client_uri: Option<Url>,
/// The client secret, used by the `client_secret_basic`,
/// `client_secret_post` and `client_secret_jwt` authentication methods
#[schemars(with = "ClientSecretRaw")]
@@ -281,6 +285,8 @@ mod tests {
r#"
clients:
- client_id: 01GFWR28C4KNE04WG3HKXB7C9R
client_name: Testing Triceratops
client_uri: https://testing.example.org
client_auth_method: none
redirect_uris:
- https://exemple.fr/callback
@@ -328,6 +334,14 @@ mod tests {
config.0[0].client_id,
Ulid::from_str("01GFWR28C4KNE04WG3HKXB7C9R").unwrap()
);
assert_eq!(
config.0[0].client_name,
Some("Testing Triceratops".to_string())
);
assert_eq!(
config.0[0].client_uri,
Some(Url::from_str("https://testing.example.org").unwrap())
);
assert_eq!(
config.0[0].redirect_uris,
vec!["https://exemple.fr/callback".parse().unwrap()]
@@ -308,6 +308,7 @@ mod tests {
.upsert_static(
static_id,
Some("Static Client".to_owned()),
None,
OAuthClientAuthenticationMethod::None,
None,
None,
@@ -0,0 +1,25 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO oauth2_clients\n ( oauth2_client_id\n , encrypted_client_secret\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , grant_type_client_credentials\n , grant_type_device_code\n , token_endpoint_auth_method\n , jwks\n , client_name\n , client_uri\n , jwks_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, TRUE)\n ON CONFLICT (oauth2_client_id)\n DO\n UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret\n , redirect_uris = EXCLUDED.redirect_uris\n , grant_type_authorization_code = EXCLUDED.grant_type_authorization_code\n , grant_type_refresh_token = EXCLUDED.grant_type_refresh_token\n , grant_type_client_credentials = EXCLUDED.grant_type_client_credentials\n , grant_type_device_code = EXCLUDED.grant_type_device_code\n , token_endpoint_auth_method = EXCLUDED.token_endpoint_auth_method\n , jwks = EXCLUDED.jwks\n , client_name = EXCLUDED.client_name\n , client_uri = EXCLUDED.client_uri\n , jwks_uri = EXCLUDED.jwks_uri\n , is_static = TRUE\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Text",
"TextArray",
"Bool",
"Bool",
"Bool",
"Bool",
"Text",
"Jsonb",
"Text",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "3e4b44a429aff8d45bc3c044c67baf6096d3278bd3bafed9fb65c72c714e88cf"
}
@@ -1,24 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO oauth2_clients\n ( oauth2_client_id\n , encrypted_client_secret\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , grant_type_client_credentials\n , grant_type_device_code\n , token_endpoint_auth_method\n , jwks\n , client_name\n , jwks_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, TRUE)\n ON CONFLICT (oauth2_client_id)\n DO\n UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret\n , redirect_uris = EXCLUDED.redirect_uris\n , grant_type_authorization_code = EXCLUDED.grant_type_authorization_code\n , grant_type_refresh_token = EXCLUDED.grant_type_refresh_token\n , grant_type_client_credentials = EXCLUDED.grant_type_client_credentials\n , grant_type_device_code = EXCLUDED.grant_type_device_code\n , token_endpoint_auth_method = EXCLUDED.token_endpoint_auth_method\n , jwks = EXCLUDED.jwks\n , client_name = EXCLUDED.client_name\n , jwks_uri = EXCLUDED.jwks_uri\n , is_static = TRUE\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Text",
"TextArray",
"Bool",
"Bool",
"Bool",
"Bool",
"Text",
"Jsonb",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "da02f93d7346992a9795f12b900f91ac0b326dd751c0d374d6ef4d19f671d22e"
}
+5 -1
View File
@@ -629,6 +629,7 @@ impl OAuth2ClientRepository for PgOAuth2ClientRepository<'_> {
&mut self,
client_id: Ulid,
client_name: Option<String>,
client_uri: Option<Url>,
client_auth_method: OAuthClientAuthenticationMethod,
encrypted_client_secret: Option<String>,
jwks: Option<PublicJsonWebKeySet>,
@@ -657,11 +658,12 @@ impl OAuth2ClientRepository for PgOAuth2ClientRepository<'_> {
, token_endpoint_auth_method
, jwks
, client_name
, client_uri
, jwks_uri
, is_static
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, TRUE)
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, TRUE)
ON CONFLICT (oauth2_client_id)
DO
UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret
@@ -673,6 +675,7 @@ impl OAuth2ClientRepository for PgOAuth2ClientRepository<'_> {
, token_endpoint_auth_method = EXCLUDED.token_endpoint_auth_method
, jwks = EXCLUDED.jwks
, client_name = EXCLUDED.client_name
, client_uri = EXCLUDED.client_uri
, jwks_uri = EXCLUDED.jwks_uri
, is_static = TRUE
"#,
@@ -686,6 +689,7 @@ impl OAuth2ClientRepository for PgOAuth2ClientRepository<'_> {
client_auth_method,
jwks_json,
client_name,
client_uri.as_ref().map(Url::as_str),
jwks_uri.as_ref().map(Url::as_str),
)
.traced()
+1
View File
@@ -1282,6 +1282,7 @@ mod tests {
.upsert_static(
static_id,
Some("Static client".to_owned()),
None,
OAuthClientAuthenticationMethod::None,
None,
None,
+4
View File
@@ -260,6 +260,8 @@ pub trait OAuth2ClientRepository: Send + Sync {
/// # Parameters
///
/// * `client_id`: The client ID
/// * `client_name`: Name of the `OAuth2` client
/// * `client_uri`: User-facing information about the client
/// * `client_auth_method`: The authentication method this client uses
/// * `encrypted_client_secret`: The encrypted client secret, if any
/// * `jwks`: The client JWKS, if any
@@ -274,6 +276,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
&mut self,
client_id: Ulid,
client_name: Option<String>,
client_uri: Option<Url>,
client_auth_method: OAuthClientAuthenticationMethod,
encrypted_client_secret: Option<String>,
jwks: Option<PublicJsonWebKeySet>,
@@ -382,6 +385,7 @@ repository_impl!(OAuth2ClientRepository:
&mut self,
client_id: Ulid,
client_name: Option<String>,
client_uri: Option<Url>,
client_auth_method: OAuthClientAuthenticationMethod,
encrypted_client_secret: Option<String>,
jwks: Option<PublicJsonWebKeySet>,
+8
View File
@@ -258,6 +258,14 @@
"null"
]
},
"client_uri": {
"description": "Client URL for user-facing information about the client",
"type": [
"string",
"null"
],
"format": "uri"
},
"client_secret_file": {
"description": "Path to the file containing the client secret. The client secret is used\nby the `client_secret_basic`, `client_secret_post` and\n`client_secret_jwt` authentication methods.",
"type": [