You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Save the application_type and the contacts in the OAuth 2.0 clients
This also removes the dedicated "redirect_uris" table and makes it a field of the "oauth2_clients" table
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
[workspace]
|
||||
default-members = ["crates/cli"]
|
||||
members = ["crates/*"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
|
@ -140,7 +140,6 @@ impl Options {
|
||||
#[tracing::instrument(name = "cli.config.sync", skip(root), err(Debug))]
|
||||
async fn sync(root: &super::Options, prune: bool, dry_run: bool) -> anyhow::Result<()> {
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
let mut rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
let clock = SystemClock::default();
|
||||
|
||||
let config: SyncConfig = root.load_config()?;
|
||||
@ -282,8 +281,6 @@ async fn sync(root: &super::Options, prune: bool, dry_run: bool) -> anyhow::Resu
|
||||
|
||||
repo.oauth2_client()
|
||||
.upsert_static(
|
||||
&mut rng,
|
||||
&clock,
|
||||
client.client_id,
|
||||
client_auth_method,
|
||||
encrypted_client_secret,
|
||||
|
@ -18,7 +18,7 @@ use mas_iana::{
|
||||
oauth::{OAuthAuthorizationEndpointResponseType, OAuthClientAuthenticationMethod},
|
||||
};
|
||||
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||
use oauth2_types::requests::GrantType;
|
||||
use oauth2_types::{oidc::ApplicationType, requests::GrantType};
|
||||
use rand::RngCore;
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
@ -44,6 +44,8 @@ pub struct Client {
|
||||
|
||||
pub encrypted_client_secret: Option<String>,
|
||||
|
||||
pub application_type: Option<ApplicationType>,
|
||||
|
||||
/// Array of Redirection URI values used by the Client
|
||||
pub redirect_uris: Vec<Url>,
|
||||
|
||||
@ -130,6 +132,7 @@ impl Client {
|
||||
id: Ulid::from_datetime_with_source(now.into(), rng),
|
||||
client_id: "client1".to_owned(),
|
||||
encrypted_client_secret: None,
|
||||
application_type: Some(ApplicationType::Web),
|
||||
redirect_uris: vec![
|
||||
Url::parse("https://client1.example.com/redirect").unwrap(),
|
||||
Url::parse("https://client1.example.com/redirect2").unwrap(),
|
||||
@ -156,6 +159,7 @@ impl Client {
|
||||
id: Ulid::from_datetime_with_source(now.into(), rng),
|
||||
client_id: "client2".to_owned(),
|
||||
encrypted_client_secret: None,
|
||||
application_type: Some(ApplicationType::Native),
|
||||
redirect_uris: vec![Url::parse("https://client2.example.com/redirect").unwrap()],
|
||||
response_types: vec![OAuthAuthorizationEndpointResponseType::Code],
|
||||
grant_types: vec![GrantType::AuthorizationCode, GrantType::RefreshToken],
|
||||
|
@ -17,7 +17,7 @@ use async_graphql::{Context, Description, Enum, Object, ID};
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::SessionState;
|
||||
use mas_storage::{oauth2::OAuth2ClientRepository, user::BrowserSessionRepository};
|
||||
use oauth2_types::scope::Scope;
|
||||
use oauth2_types::{oidc::ApplicationType, scope::Scope};
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
|
||||
@ -110,6 +110,16 @@ impl OAuth2Session {
|
||||
}
|
||||
}
|
||||
|
||||
/// The application type advertised by the client.
|
||||
#[derive(Enum, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum OAuth2ApplicationType {
|
||||
/// Client is a web application.
|
||||
Web,
|
||||
|
||||
/// Client is a native application.
|
||||
Native,
|
||||
}
|
||||
|
||||
/// An OAuth 2.0 client
|
||||
#[derive(Description)]
|
||||
pub struct OAuth2Client(pub mas_data_model::Client);
|
||||
@ -150,6 +160,19 @@ impl OAuth2Client {
|
||||
pub async fn redirect_uris(&self) -> &[Url] {
|
||||
&self.0.redirect_uris
|
||||
}
|
||||
|
||||
/// List of contacts advertised by the client.
|
||||
pub async fn contacts(&self) -> &[String] {
|
||||
&self.0.contacts
|
||||
}
|
||||
|
||||
/// The application type advertised by the client.
|
||||
pub async fn application_type(&self) -> Option<OAuth2ApplicationType> {
|
||||
match self.0.application_type? {
|
||||
ApplicationType::Web => Some(OAuth2ApplicationType::Web),
|
||||
ApplicationType::Native => Some(OAuth2ApplicationType::Native),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An OAuth 2.0 consent represents the scope a user consented to grant to a
|
||||
|
@ -33,6 +33,7 @@ async fn create_test_client(state: &TestState) -> Client {
|
||||
&state.clock,
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
vec![],
|
||||
vec![],
|
||||
None,
|
||||
|
@ -175,6 +175,7 @@ pub(crate) async fn post(
|
||||
&clock,
|
||||
metadata.redirect_uris().to_vec(),
|
||||
encrypted_client_secret,
|
||||
metadata.application_type,
|
||||
//&metadata.response_types(),
|
||||
metadata.grant_types().to_vec(),
|
||||
metadata.contacts.clone().unwrap_or_default(),
|
||||
|
@ -1,29 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO oauth2_clients\n ( oauth2_client_id\n , encrypted_client_secret\n , grant_type_authorization_code\n , grant_type_refresh_token\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, FALSE)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Jsonb",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "31cbbd841029812c6d3500cae04a8e9e5723e4749d339465492b68e072c3a802"
|
||||
}
|
31
crates/storage-pg/.sqlx/query-34fbe0f0485a9c4060399509f087964c454252b9b111a57c9106cfc3fdc71b8a.json
generated
Normal file
31
crates/storage-pg/.sqlx/query-34fbe0f0485a9c4060399509f087964c454252b9b111a57c9106cfc3fdc71b8a.json
generated
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO oauth2_clients\n ( oauth2_client_id\n , encrypted_client_secret\n , application_type\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, FALSE)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Jsonb",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "34fbe0f0485a9c4060399509f087964c454252b9b111a57c9106cfc3fdc71b8a"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , ARRAY(\n SELECT redirect_uri\n FROM oauth2_client_redirect_uris r\n WHERE r.oauth2_client_id = c.oauth2_client_id\n ) AS \"redirect_uris!\"\n , grant_type_authorization_code\n , grant_type_refresh_token\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n\n WHERE oauth2_client_id = ANY($1::uuid[])\n ",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , application_type\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , contacts\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n\n WHERE oauth2_client_id = ANY($1::uuid[])\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@ -15,76 +15,86 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "redirect_uris!",
|
||||
"type_info": "TextArray"
|
||||
"name": "application_type",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "redirect_uris",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "grant_type_authorization_code",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"ordinal": 5,
|
||||
"name": "grant_type_refresh_token",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"ordinal": 6,
|
||||
"name": "contacts",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "client_name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"ordinal": 8,
|
||||
"name": "logo_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 9,
|
||||
"name": "client_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 10,
|
||||
"name": "policy_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 11,
|
||||
"name": "tos_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 12,
|
||||
"name": "jwks_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 13,
|
||||
"name": "jwks",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 14,
|
||||
"name": "id_token_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 15,
|
||||
"name": "userinfo_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 16,
|
||||
"name": "token_endpoint_auth_method",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 17,
|
||||
"name": "token_endpoint_auth_signing_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 18,
|
||||
"name": "initiate_login_uri",
|
||||
"type_info": "Text"
|
||||
}
|
||||
@ -97,7 +107,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
@ -114,5 +126,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "85499663f1adc7b7439592063f06914089f6243126a177b365bde37db5f6b33d"
|
||||
"hash": "35734c4b54d2f1b2c311806af3e9a592f5f55f4898c6e39eb0d7c1b9cef7ca63"
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO oauth2_clients\n ( oauth2_client_id\n , encrypted_client_secret\n , grant_type_authorization_code\n , grant_type_refresh_token\n , token_endpoint_auth_method\n , jwks\n , jwks_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, TRUE)\n ON CONFLICT (oauth2_client_id)\n DO\n UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret\n , grant_type_authorization_code = EXCLUDED.grant_type_authorization_code\n , grant_type_refresh_token = EXCLUDED.grant_type_refresh_token\n , token_endpoint_auth_method = EXCLUDED.token_endpoint_auth_method\n , jwks = EXCLUDED.jwks\n , jwks_uri = EXCLUDED.jwks_uri\n , is_static = TRUE\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Jsonb",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "68c4cd463e4035ba8384f11818b7be602e2fbc34a5582f31f95b0cc5fa2aeb92"
|
||||
}
|
21
crates/storage-pg/.sqlx/query-73ea17a71d62bf96f7811b7f57802f5065f0ae831bc8f3c66b5be4a47b37467e.json
generated
Normal file
21
crates/storage-pg/.sqlx/query-73ea17a71d62bf96f7811b7f57802f5065f0ae831bc8f3c66b5be4a47b37467e.json
generated
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"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 , token_endpoint_auth_method\n , jwks\n , jwks_uri\n , is_static\n )\n VALUES\n ($1, $2, $3, $4, $5, $6, $7, $8, TRUE)\n ON CONFLICT (oauth2_client_id)\n DO\n UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret\n , grant_type_authorization_code = EXCLUDED.grant_type_authorization_code\n , grant_type_refresh_token = EXCLUDED.grant_type_refresh_token\n , token_endpoint_auth_method = EXCLUDED.token_endpoint_auth_method\n , jwks = EXCLUDED.jwks\n , jwks_uri = EXCLUDED.jwks_uri\n , is_static = TRUE\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Jsonb",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "73ea17a71d62bf96f7811b7f57802f5065f0ae831bc8f3c66b5be4a47b37467e"
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO oauth2_client_redirect_uris\n (oauth2_client_redirect_uri_id, oauth2_client_id, redirect_uri)\n SELECT id, $2, redirect_uri\n FROM UNNEST($1::uuid[], $3::text[]) r(id, redirect_uri)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"UuidArray",
|
||||
"Uuid",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "7be139553610ace03193a99fe27fcb4e3d50c90accdaf22ca1cfeefdc9734300"
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n DELETE FROM oauth2_client_redirect_uris\n WHERE oauth2_client_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "7cd0264707100f5b3cb2582f3f840bf66649742374e3643f1902ae69377fc9b6"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , ARRAY(\n SELECT redirect_uri\n FROM oauth2_client_redirect_uris r\n WHERE r.oauth2_client_id = c.oauth2_client_id\n ) AS \"redirect_uris!\"\n , grant_type_authorization_code\n , grant_type_refresh_token\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n WHERE is_static = TRUE\n ",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , application_type\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , contacts\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n WHERE is_static = TRUE\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@ -15,76 +15,86 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "redirect_uris!",
|
||||
"type_info": "TextArray"
|
||||
"name": "application_type",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "redirect_uris",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "grant_type_authorization_code",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"ordinal": 5,
|
||||
"name": "grant_type_refresh_token",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"ordinal": 6,
|
||||
"name": "contacts",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "client_name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"ordinal": 8,
|
||||
"name": "logo_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 9,
|
||||
"name": "client_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 10,
|
||||
"name": "policy_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 11,
|
||||
"name": "tos_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 12,
|
||||
"name": "jwks_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 13,
|
||||
"name": "jwks",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 14,
|
||||
"name": "id_token_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 15,
|
||||
"name": "userinfo_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 16,
|
||||
"name": "token_endpoint_auth_method",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 17,
|
||||
"name": "token_endpoint_auth_signing_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 18,
|
||||
"name": "initiate_login_uri",
|
||||
"type_info": "Text"
|
||||
}
|
||||
@ -95,7 +105,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
@ -112,5 +124,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "7e676491b077d4bc8a9cdb4a27ebf119d98cd35ebb52b1064fdb2d9eed78d0e8"
|
||||
"hash": "b2b71d12c3a4a7436bbe961c6c57e17a5c5e4105d01184a38d12607d853df802"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , ARRAY(\n SELECT redirect_uri\n FROM oauth2_client_redirect_uris r\n WHERE r.oauth2_client_id = c.oauth2_client_id\n ) AS \"redirect_uris!\"\n , grant_type_authorization_code\n , grant_type_refresh_token\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n\n WHERE oauth2_client_id = $1\n ",
|
||||
"query": "\n SELECT oauth2_client_id\n , encrypted_client_secret\n , application_type\n , redirect_uris\n , grant_type_authorization_code\n , grant_type_refresh_token\n , contacts\n , client_name\n , logo_uri\n , client_uri\n , policy_uri\n , tos_uri\n , jwks_uri\n , jwks\n , id_token_signed_response_alg\n , userinfo_signed_response_alg\n , token_endpoint_auth_method\n , token_endpoint_auth_signing_alg\n , initiate_login_uri\n FROM oauth2_clients c\n\n WHERE oauth2_client_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@ -15,76 +15,86 @@
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "redirect_uris!",
|
||||
"type_info": "TextArray"
|
||||
"name": "application_type",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "redirect_uris",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "grant_type_authorization_code",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"ordinal": 5,
|
||||
"name": "grant_type_refresh_token",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"ordinal": 6,
|
||||
"name": "contacts",
|
||||
"type_info": "TextArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "client_name",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"ordinal": 8,
|
||||
"name": "logo_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"ordinal": 9,
|
||||
"name": "client_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"ordinal": 10,
|
||||
"name": "policy_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"ordinal": 11,
|
||||
"name": "tos_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"ordinal": 12,
|
||||
"name": "jwks_uri",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"ordinal": 13,
|
||||
"name": "jwks",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"ordinal": 14,
|
||||
"name": "id_token_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"ordinal": 15,
|
||||
"name": "userinfo_signed_response_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"ordinal": 16,
|
||||
"name": "token_endpoint_auth_method",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"ordinal": 17,
|
||||
"name": "token_endpoint_auth_signing_alg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"ordinal": 18,
|
||||
"name": "initiate_login_uri",
|
||||
"type_info": "Text"
|
||||
}
|
||||
@ -97,7 +107,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
@ -114,5 +126,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "db90cbc406a399f5447bd2c1d8018464f83b927dec620353516c0285b76fcf24"
|
||||
"hash": "e6250ea5c861cd7568999fd8f490daf1407b1b3619e3a05c70b5fe9ccf9aa7b5"
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
-- Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
-- Adds a few fields to OAuth 2.0 clients, and squash the redirect_uris in the same table
|
||||
|
||||
ALTER TABLE "oauth2_clients"
|
||||
ADD COLUMN "redirect_uris" TEXT[] NOT NULL DEFAULT '{}',
|
||||
ADD COLUMN "application_type" TEXT,
|
||||
ADD COLUMN "contacts" TEXT[] NOT NULL DEFAULT '{}';
|
||||
|
||||
-- Insert in the new `redirect_uris` column the values from the old table
|
||||
UPDATE "oauth2_clients"
|
||||
SET "redirect_uris" = ARRAY(
|
||||
SELECT "redirect_uri"
|
||||
FROM "oauth2_client_redirect_uris"
|
||||
WHERE "oauth2_client_redirect_uris"."oauth2_client_id" = "oauth2_clients"."oauth2_client_id"
|
||||
GROUP BY "redirect_uri"
|
||||
);
|
||||
|
||||
-- Drop the old table
|
||||
DROP TABLE "oauth2_client_redirect_uris";
|
@ -27,6 +27,7 @@ use mas_iana::{
|
||||
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||
use mas_storage::{oauth2::OAuth2ClientRepository, Clock};
|
||||
use oauth2_types::{
|
||||
oidc::ApplicationType,
|
||||
requests::GrantType,
|
||||
scope::{Scope, ScopeToken},
|
||||
};
|
||||
@ -57,11 +58,12 @@ impl<'c> PgOAuth2ClientRepository<'c> {
|
||||
struct OAuth2ClientLookup {
|
||||
oauth2_client_id: Uuid,
|
||||
encrypted_client_secret: Option<String>,
|
||||
application_type: Option<String>,
|
||||
redirect_uris: Vec<String>,
|
||||
// response_types: Vec<String>,
|
||||
grant_type_authorization_code: bool,
|
||||
grant_type_refresh_token: bool,
|
||||
// contacts: Vec<String>,
|
||||
contacts: Vec<String>,
|
||||
client_name: Option<String>,
|
||||
logo_uri: Option<String>,
|
||||
client_uri: Option<String>,
|
||||
@ -92,6 +94,17 @@ impl TryInto<Client> for OAuth2ClientLookup {
|
||||
.source(e)
|
||||
})?;
|
||||
|
||||
let application_type = self
|
||||
.application_type
|
||||
.map(|s| s.parse())
|
||||
.transpose()
|
||||
.map_err(|e| {
|
||||
DatabaseInconsistencyError::on("oauth2_clients")
|
||||
.column("application_type")
|
||||
.row(id)
|
||||
.source(e)
|
||||
})?;
|
||||
|
||||
let response_types = vec![
|
||||
OAuthAuthorizationEndpointResponseType::Code,
|
||||
OAuthAuthorizationEndpointResponseType::IdToken,
|
||||
@ -237,11 +250,11 @@ impl TryInto<Client> for OAuth2ClientLookup {
|
||||
id,
|
||||
client_id: id.to_string(),
|
||||
encrypted_client_secret: self.encrypted_client_secret,
|
||||
application_type,
|
||||
redirect_uris,
|
||||
response_types,
|
||||
grant_types,
|
||||
// contacts: self.contacts,
|
||||
contacts: vec![],
|
||||
contacts: self.contacts,
|
||||
client_name: self.client_name,
|
||||
logo_uri,
|
||||
client_uri,
|
||||
@ -276,13 +289,11 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
r#"
|
||||
SELECT oauth2_client_id
|
||||
, encrypted_client_secret
|
||||
, ARRAY(
|
||||
SELECT redirect_uri
|
||||
FROM oauth2_client_redirect_uris r
|
||||
WHERE r.oauth2_client_id = c.oauth2_client_id
|
||||
) AS "redirect_uris!"
|
||||
, application_type
|
||||
, redirect_uris
|
||||
, grant_type_authorization_code
|
||||
, grant_type_refresh_token
|
||||
, contacts
|
||||
, client_name
|
||||
, logo_uri
|
||||
, client_uri
|
||||
@ -328,13 +339,11 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
r#"
|
||||
SELECT oauth2_client_id
|
||||
, encrypted_client_secret
|
||||
, ARRAY(
|
||||
SELECT redirect_uri
|
||||
FROM oauth2_client_redirect_uris r
|
||||
WHERE r.oauth2_client_id = c.oauth2_client_id
|
||||
) AS "redirect_uris!"
|
||||
, application_type
|
||||
, redirect_uris
|
||||
, grant_type_authorization_code
|
||||
, grant_type_refresh_token
|
||||
, contacts
|
||||
, client_name
|
||||
, logo_uri
|
||||
, client_uri
|
||||
@ -379,10 +388,11 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
mut rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
encrypted_client_secret: Option<String>,
|
||||
application_type: Option<ApplicationType>,
|
||||
grant_types: Vec<GrantType>,
|
||||
contacts: Vec<String>,
|
||||
client_name: Option<String>,
|
||||
@ -408,11 +418,15 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
.transpose()
|
||||
.map_err(DatabaseError::to_invalid_operation)?;
|
||||
|
||||
let redirect_uris_array = redirect_uris.iter().map(Url::to_string).collect::<Vec<_>>();
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO oauth2_clients
|
||||
( oauth2_client_id
|
||||
, encrypted_client_secret
|
||||
, application_type
|
||||
, redirect_uris
|
||||
, grant_type_authorization_code
|
||||
, grant_type_refresh_token
|
||||
, client_name
|
||||
@ -430,10 +444,12 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
, is_static
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, FALSE)
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, FALSE)
|
||||
"#,
|
||||
Uuid::from(id),
|
||||
encrypted_client_secret,
|
||||
application_type.map(|a| a.to_string()),
|
||||
&redirect_uris_array,
|
||||
grant_types.contains(&GrantType::AuthorizationCode),
|
||||
grant_types.contains(&GrantType::RefreshToken),
|
||||
client_name,
|
||||
@ -459,40 +475,6 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
.execute(&mut *self.conn)
|
||||
.await?;
|
||||
|
||||
{
|
||||
let span = info_span!(
|
||||
"db.oauth2_client.add.redirect_uris",
|
||||
db.statement = tracing::field::Empty,
|
||||
client.id = %id,
|
||||
);
|
||||
|
||||
let (uri_ids, redirect_uris): (Vec<Uuid>, Vec<String>) = redirect_uris
|
||||
.iter()
|
||||
.map(|uri| {
|
||||
(
|
||||
Uuid::from(Ulid::from_datetime_with_source(now.into(), &mut rng)),
|
||||
uri.as_str().to_owned(),
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO oauth2_client_redirect_uris
|
||||
(oauth2_client_redirect_uri_id, oauth2_client_id, redirect_uri)
|
||||
SELECT id, $2, redirect_uri
|
||||
FROM UNNEST($1::uuid[], $3::text[]) r(id, redirect_uri)
|
||||
"#,
|
||||
&uri_ids,
|
||||
Uuid::from(id),
|
||||
&redirect_uris,
|
||||
)
|
||||
.record(&span)
|
||||
.execute(&mut *self.conn)
|
||||
.instrument(span)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let jwks = match (jwks, jwks_uri) {
|
||||
(None, None) => None,
|
||||
(Some(jwks), None) => Some(JwksOrJwksUri::Jwks(jwks)),
|
||||
@ -504,6 +486,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
id,
|
||||
client_id: id.to_string(),
|
||||
encrypted_client_secret,
|
||||
application_type,
|
||||
redirect_uris,
|
||||
response_types: vec![
|
||||
OAuthAuthorizationEndpointResponseType::Code,
|
||||
@ -537,8 +520,6 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
)]
|
||||
async fn upsert_static(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
clock: &dyn Clock,
|
||||
client_id: Ulid,
|
||||
client_auth_method: OAuthClientAuthenticationMethod,
|
||||
encrypted_client_secret: Option<String>,
|
||||
@ -553,12 +534,14 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
.map_err(DatabaseError::to_invalid_operation)?;
|
||||
|
||||
let client_auth_method = client_auth_method.to_string();
|
||||
let redirect_uris_array = redirect_uris.iter().map(Url::to_string).collect::<Vec<_>>();
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO oauth2_clients
|
||||
( oauth2_client_id
|
||||
, encrypted_client_secret
|
||||
, redirect_uris
|
||||
, grant_type_authorization_code
|
||||
, grant_type_refresh_token
|
||||
, token_endpoint_auth_method
|
||||
@ -567,7 +550,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
, is_static
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, TRUE)
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, TRUE)
|
||||
ON CONFLICT (oauth2_client_id)
|
||||
DO
|
||||
UPDATE SET encrypted_client_secret = EXCLUDED.encrypted_client_secret
|
||||
@ -580,6 +563,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
"#,
|
||||
Uuid::from(client_id),
|
||||
encrypted_client_secret,
|
||||
&redirect_uris_array,
|
||||
true,
|
||||
true,
|
||||
client_auth_method,
|
||||
@ -590,41 +574,6 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
.execute(&mut *self.conn)
|
||||
.await?;
|
||||
|
||||
{
|
||||
let span = info_span!(
|
||||
"db.oauth2_client.upsert_static.redirect_uris",
|
||||
client.id = %client_id,
|
||||
db.statement = tracing::field::Empty,
|
||||
);
|
||||
|
||||
let now = clock.now();
|
||||
let (ids, redirect_uris): (Vec<Uuid>, Vec<String>) = redirect_uris
|
||||
.iter()
|
||||
.map(|uri| {
|
||||
(
|
||||
Uuid::from(Ulid::from_datetime_with_source(now.into(), &mut *rng)),
|
||||
uri.as_str().to_owned(),
|
||||
)
|
||||
})
|
||||
.unzip();
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO oauth2_client_redirect_uris
|
||||
(oauth2_client_redirect_uri_id, oauth2_client_id, redirect_uri)
|
||||
SELECT id, $2, redirect_uri
|
||||
FROM UNNEST($1::uuid[], $3::text[]) r(id, redirect_uri)
|
||||
"#,
|
||||
&ids,
|
||||
Uuid::from(client_id),
|
||||
&redirect_uris,
|
||||
)
|
||||
.record(&span)
|
||||
.execute(&mut *self.conn)
|
||||
.instrument(span)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let jwks = match (jwks, jwks_uri) {
|
||||
(None, None) => None,
|
||||
(Some(jwks), None) => Some(JwksOrJwksUri::Jwks(jwks)),
|
||||
@ -636,6 +585,7 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
id: client_id,
|
||||
client_id: client_id.to_string(),
|
||||
encrypted_client_secret,
|
||||
application_type: None,
|
||||
redirect_uris,
|
||||
response_types: vec![
|
||||
OAuthAuthorizationEndpointResponseType::Code,
|
||||
@ -672,13 +622,11 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
r#"
|
||||
SELECT oauth2_client_id
|
||||
, encrypted_client_secret
|
||||
, ARRAY(
|
||||
SELECT redirect_uri
|
||||
FROM oauth2_client_redirect_uris r
|
||||
WHERE r.oauth2_client_id = c.oauth2_client_id
|
||||
) AS "redirect_uris!"
|
||||
, application_type
|
||||
, redirect_uris
|
||||
, grant_type_authorization_code
|
||||
, grant_type_refresh_token
|
||||
, contacts
|
||||
, client_name
|
||||
, logo_uri
|
||||
, client_uri
|
||||
@ -911,26 +859,6 @@ impl<'c> OAuth2ClientRepository for PgOAuth2ClientRepository<'c> {
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Delete the redirect URIs
|
||||
{
|
||||
let span = info_span!(
|
||||
"db.oauth2_client.delete_by_id.redirect_uris",
|
||||
db.statement = tracing::field::Empty,
|
||||
);
|
||||
|
||||
sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM oauth2_client_redirect_uris
|
||||
WHERE oauth2_client_id = $1
|
||||
"#,
|
||||
Uuid::from(id),
|
||||
)
|
||||
.record(&span)
|
||||
.execute(&mut *self.conn)
|
||||
.instrument(span)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Now delete the client itself
|
||||
let res = sqlx::query!(
|
||||
r#"
|
||||
|
@ -73,6 +73,7 @@ mod tests {
|
||||
&clock,
|
||||
vec!["https://example.com/redirect".parse().unwrap()],
|
||||
None,
|
||||
None,
|
||||
vec![GrantType::AuthorizationCode],
|
||||
Vec::new(), // TODO: contacts are not yet saved
|
||||
// vec!["contact@example.com".to_owned()],
|
||||
@ -409,6 +410,7 @@ mod tests {
|
||||
&clock,
|
||||
vec!["https://first.example.com/redirect".parse().unwrap()],
|
||||
None,
|
||||
None,
|
||||
vec![GrantType::AuthorizationCode],
|
||||
Vec::new(), // TODO: contacts are not yet saved
|
||||
// vec!["contact@first.example.com".to_owned()],
|
||||
@ -434,6 +436,7 @@ mod tests {
|
||||
&clock,
|
||||
vec!["https://second.example.com/redirect".parse().unwrap()],
|
||||
None,
|
||||
None,
|
||||
vec![GrantType::AuthorizationCode],
|
||||
Vec::new(), // TODO: contacts are not yet saved
|
||||
// vec!["contact@second.example.com".to_owned()],
|
||||
|
@ -18,7 +18,7 @@ use async_trait::async_trait;
|
||||
use mas_data_model::{Client, User};
|
||||
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
|
||||
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||
use oauth2_types::{requests::GrantType, scope::Scope};
|
||||
use oauth2_types::{oidc::ApplicationType, requests::GrantType, scope::Scope};
|
||||
use rand_core::RngCore;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
@ -80,6 +80,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
|
||||
/// * `clock`: The clock used to generate timestamps
|
||||
/// * `redirect_uris`: The list of redirect URIs used by this client
|
||||
/// * `encrypted_client_secret`: The encrypted client secret, if any
|
||||
/// * `application_type`: The application type of this client
|
||||
/// * `grant_types`: The list of grant types this client can use
|
||||
/// * `contacts`: The list of contacts for this client
|
||||
/// * `client_name`: The human-readable name of this client, if given
|
||||
@ -110,6 +111,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
encrypted_client_secret: Option<String>,
|
||||
application_type: Option<ApplicationType>,
|
||||
grant_types: Vec<GrantType>,
|
||||
contacts: Vec<String>,
|
||||
client_name: Option<String>,
|
||||
@ -132,8 +134,6 @@ pub trait OAuth2ClientRepository: Send + Sync {
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `rng`: The random number generator to use
|
||||
/// * `clock`: The clock used to generate timestamps
|
||||
/// * `client_id`: The client ID
|
||||
/// * `client_auth_method`: The authentication method this client uses
|
||||
/// * `encrypted_client_secret`: The encrypted client secret, if any
|
||||
@ -147,8 +147,6 @@ pub trait OAuth2ClientRepository: Send + Sync {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn upsert_static(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
clock: &dyn Clock,
|
||||
client_id: Ulid,
|
||||
client_auth_method: OAuthClientAuthenticationMethod,
|
||||
encrypted_client_secret: Option<String>,
|
||||
@ -244,6 +242,7 @@ repository_impl!(OAuth2ClientRepository:
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
encrypted_client_secret: Option<String>,
|
||||
application_type: Option<ApplicationType>,
|
||||
grant_types: Vec<GrantType>,
|
||||
contacts: Vec<String>,
|
||||
client_name: Option<String>,
|
||||
@ -262,8 +261,6 @@ repository_impl!(OAuth2ClientRepository:
|
||||
|
||||
async fn upsert_static(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
clock: &dyn Clock,
|
||||
client_id: Ulid,
|
||||
client_auth_method: OAuthClientAuthenticationMethod,
|
||||
encrypted_client_secret: Option<String>,
|
||||
|
@ -475,6 +475,20 @@ interface Node {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
"""
|
||||
The application type advertised by the client.
|
||||
"""
|
||||
enum Oauth2ApplicationType {
|
||||
"""
|
||||
Client is a web application.
|
||||
"""
|
||||
WEB
|
||||
"""
|
||||
Client is a native application.
|
||||
"""
|
||||
NATIVE
|
||||
}
|
||||
|
||||
"""
|
||||
An OAuth 2.0 client
|
||||
"""
|
||||
@ -507,6 +521,14 @@ type Oauth2Client implements Node {
|
||||
List of redirect URIs used for authorization grants by the client.
|
||||
"""
|
||||
redirectUris: [Url!]!
|
||||
"""
|
||||
List of contacts advertised by the client.
|
||||
"""
|
||||
contacts: [String!]!
|
||||
"""
|
||||
The application type advertised by the client.
|
||||
"""
|
||||
applicationType: Oauth2ApplicationType
|
||||
}
|
||||
|
||||
"""
|
||||
|
@ -382,15 +382,27 @@ export type Node = {
|
||||
id: Scalars["ID"]["output"];
|
||||
};
|
||||
|
||||
/** The application type advertised by the client. */
|
||||
export enum Oauth2ApplicationType {
|
||||
/** Client is a native application. */
|
||||
Native = "NATIVE",
|
||||
/** Client is a web application. */
|
||||
Web = "WEB",
|
||||
}
|
||||
|
||||
/** An OAuth 2.0 client */
|
||||
export type Oauth2Client = Node & {
|
||||
__typename?: "Oauth2Client";
|
||||
/** The application type advertised by the client. */
|
||||
applicationType?: Maybe<Oauth2ApplicationType>;
|
||||
/** OAuth 2.0 client ID */
|
||||
clientId: Scalars["String"]["output"];
|
||||
/** Client name advertised by the client. */
|
||||
clientName?: Maybe<Scalars["String"]["output"]>;
|
||||
/** Client URI advertised by the client. */
|
||||
clientUri?: Maybe<Scalars["Url"]["output"]>;
|
||||
/** List of contacts advertised by the client. */
|
||||
contacts: Array<Scalars["String"]["output"]>;
|
||||
/** ID of the object. */
|
||||
id: Scalars["ID"]["output"];
|
||||
/** Privacy policy URI advertised by the client. */
|
||||
|
@ -1046,6 +1046,14 @@ export default {
|
||||
kind: "OBJECT",
|
||||
name: "Oauth2Client",
|
||||
fields: [
|
||||
{
|
||||
name: "applicationType",
|
||||
type: {
|
||||
kind: "SCALAR",
|
||||
name: "Any",
|
||||
},
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
name: "clientId",
|
||||
type: {
|
||||
@ -1073,6 +1081,23 @@ export default {
|
||||
},
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
name: "contacts",
|
||||
type: {
|
||||
kind: "NON_NULL",
|
||||
ofType: {
|
||||
kind: "LIST",
|
||||
ofType: {
|
||||
kind: "NON_NULL",
|
||||
ofType: {
|
||||
kind: "SCALAR",
|
||||
name: "Any",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
name: "id",
|
||||
type: {
|
||||
|
Reference in New Issue
Block a user