diff --git a/config.toml b/config.toml index a596b4d..1f57055 100644 --- a/config.toml +++ b/config.toml @@ -1,4 +1,5 @@ [instance] +base_uri = "http://localhost:8085" name = "Example org" logo_uri = "https://example.org/logo.png" @@ -9,7 +10,8 @@ description = "A super application where you can do everything you want." client_id = "a1785786-8be1-443c-9a6f-35feed703609" client_secret = "49c6c16a-0a8a-4981-a60d-5cb96582cc1a" allowed_redirect_uris = [ - "http://localhost:9090/authorize" + "http://localhost:9090/authorize", + "http://localhost:9876/callback" ] [[roles]] diff --git a/http_integration_tests/oauth2c.sh b/http_integration_tests/oauth2c.sh new file mode 100755 index 0000000..d147067 --- /dev/null +++ b/http_integration_tests/oauth2c.sh @@ -0,0 +1,10 @@ +#!/usr/bin/bash + +oauth2c http://localhost:8085 \ + --client-id "a1785786-8be1-443c-9a6f-35feed703609" \ + --client-secret "49c6c16a-0a8a-4981-a60d-5cb96582cc1a" \ + --response-types code \ + --response-mode query \ + --grant-type authorization_code \ + --auth-method client_secret_basic \ + --scopes "read_user_basic" diff --git a/src/controllers/api/mod.rs b/src/controllers/api/mod.rs index d0916d8..36f3a8e 100644 --- a/src/controllers/api/mod.rs +++ b/src/controllers/api/mod.rs @@ -1,2 +1,3 @@ pub mod oauth2; pub mod read_user; +pub mod openid; diff --git a/src/controllers/api/openid/mod.rs b/src/controllers/api/openid/mod.rs new file mode 100644 index 0000000..1ab9853 --- /dev/null +++ b/src/controllers/api/openid/mod.rs @@ -0,0 +1 @@ +pub mod well_known; diff --git a/src/controllers/api/openid/well_known.rs b/src/controllers/api/openid/well_known.rs new file mode 100644 index 0000000..21b9326 --- /dev/null +++ b/src/controllers/api/openid/well_known.rs @@ -0,0 +1,32 @@ +use axum::{extract::State, response::IntoResponse, Json}; +use fully_pub::fully_pub; +use serde::Serialize; + +use crate::server::AppState; + +#[derive(Serialize)] +#[fully_pub] +struct WellKnownOpenIdConfiguration { + issuer: String, + authorization_endpoint: String, + token_endpoint: String, + userinfo_endpoint: String, + scopes_supported: Vec, + response_types_supported: Vec, + token_endpoint_auth_methods_supported: Vec +} + +pub async fn get_well_known_openid_configuration( + State(app_state): State, +) -> impl IntoResponse { + let base_url = app_state.config.instance.base_uri; + Json(WellKnownOpenIdConfiguration { + issuer: base_url.clone(), + authorization_endpoint: format!("{}/authorize", base_url), + token_endpoint: format!("{}/api/token", base_url), + userinfo_endpoint: format!("{}/api/user", base_url), + scopes_supported: vec!["read_user_basic".into()], + response_types_supported: vec!["code".into()], + token_endpoint_auth_methods_supported: vec!["client_secret_basic".into()], + }) +} diff --git a/src/models/config.rs b/src/models/config.rs index a065ec4..c76f54d 100644 --- a/src/models/config.rs +++ b/src/models/config.rs @@ -7,6 +7,7 @@ const fn _default_true() -> bool { true } #[fully_pub] /// Instance branding/customization config struct InstanceConfig { + base_uri: String, name: String, logo_uri: Option } diff --git a/src/router.rs b/src/router.rs index 8487bf3..3cf20ef 100644 --- a/src/router.rs +++ b/src/router.rs @@ -40,11 +40,15 @@ pub fn build_router(server_config: &ServerConfig, app_state: AppState) -> Router .route("/api/user", get(api::read_user::read_user_basic)) .layer(middleware::from_fn_with_state(app_state.clone(), app_auth::enforce_jwt_auth_middleware)); + let well_known_routes = Router::new() + .route("/.well-known/openid-configuration", get(api::openid::well_known::get_well_known_openid_configuration)); + Router::new() .merge(public_routes) .merge(user_routes) .merge(app_routes) .merge(app_user_routes) + .merge(well_known_routes) .layer(middleware::from_fn_with_state(app_state.clone(), renderer_middleware)) .nest_service( "/assets",