diff --git a/src/api/client/oidc/register.rs b/src/api/client/oidc/register.rs index f920bf63..75461287 100644 --- a/src/api/client/oidc/register.rs +++ b/src/api/client/oidc/register.rs @@ -6,6 +6,9 @@ use ruma::{DeviceId, identifiers_validation}; use conduwuit_service::oidc::registrar::normalize_redirect; /// The required parameters to register a new client for OAuth2 application. +/// See the required metadata in OAuth2 authorization grant flow in [MSC2966]. +/// +/// [MSC2966]: https://github.com/matrix-org/matrix-spec-proposals/pull/2966 #[derive(serde::Deserialize, Clone, Debug)] pub(crate) struct ClientQuery { /// Human-readable name. @@ -15,12 +18,12 @@ pub(crate) struct ClientQuery { client_uri: Url, /// Redirect URIs declared by the client. At least one. redirect_uris: Vec, - /// Must be `["code"]`. + /// Must include the literal "code". response_types: Vec, - /// Must include "authorization_type" and "refresh_token". + /// Must include the literals "authorization_code" and "refresh_token". grant_types: Vec, - //contacts: Vec, - /// Can be "none". + /// How the client intends to authenticate its requests. Can be "none", meaning + /// that the client will negotiate its token with the "authorization code" flow. token_endpoint_auth_method: String, /// Link to the logo. logo_uri: Option, @@ -28,6 +31,7 @@ pub(crate) struct ClientQuery { policy_uri: Option, /// Link to the terms of service. tos_uri: Option, + /// Can be "native", implying localhost or reserved redirect pages. /// Defaults to "web" if not present. application_type: Option, } @@ -36,13 +40,21 @@ pub(crate) struct ClientQuery { #[derive(serde::Serialize, Debug)] pub(crate) struct ClientResponse { client_id: String, + /// If the client is private, the secret it authenticates itself with. client_secret: Option, + /// If there's a `client_secret`, its expiration date in seconds since 1970-01-01T00:00. + /// Some(0) means no expiration date. client_secret_expires_at: Option, client_name: String, + /// Points to the "about" page of the client. client_uri: Url, logo_uri: Option, tos_uri: Option, policy_uri: Option, + /// Registered redirect uris, which will be matched against when authenticating. + /// If a localhost address, must contain instances of oxide-auth's + /// `RegisteredUrl::IgnorePortOnLocalhost` to let authorization flow through any port over + /// localhost. redirect_uris: Vec, token_endpoint_auth_method: String, response_types: Vec, @@ -83,7 +95,7 @@ pub(crate) async fn register_client( //services.users.update_device_metadata(); // If the client cannot authenticate itself at the token endpoint, then - // it's a public client. + // it's a public client. This is usually the case in Matrix. let is_private = client.token_endpoint_auth_method != "none"; // TODO generate a device secret. let secret = "cacestdubonsecretmonlouou=--".to_string(); diff --git a/src/service/oidc/registrar.rs b/src/service/oidc/registrar.rs index 2c4c98a1..6b70bed4 100644 --- a/src/service/oidc/registrar.rs +++ b/src/service/oidc/registrar.rs @@ -8,8 +8,8 @@ use oxide_auth::primitives::prelude::{Client, ClientUrl}; use oxide_auth::primitives::registrar::{Argon2, BoundClient, EncodedClient, PasswordPolicy, RegisteredClient, RegisteredUrl, Registrar, RegistrarError}; use once_cell::sync::Lazy; -/// oxide-auth can only ignore ports on localhost if it's spelled "localhost", -/// not "127.0.0.1" or "[::1]". This function does that replacement. +/// Substitute "127.0.0.1" and "[::1]" for "localhost" to let oxide-auth compare them +/// ignoring their port. pub fn normalize_redirect_hostname(url: Url) -> Url { let mut new_url = url.clone(); let new_host = url.host_str().map(|h|