diff --git a/config.example.toml b/config.example.toml new file mode 100644 index 0000000..e6ca5a9 --- /dev/null +++ b/config.example.toml @@ -0,0 +1,28 @@ +[instance] +base_uri = "http://localhost:8085" +name = "Example org" +logo_uri = "https://example.org/logo.png" + +[[applications]] +slug = "demo_app" +name = "Demo app" +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:9876/callback" +] +authorize_flow = "implicit" + +[[roles]] +slug = "basic" +name = "Basic" +description = "Basic user" +default = true + +[[roles]] +slug = "admin" +name = "Administrator" +description = "Full power on organization instance" + diff --git a/config.toml b/config.toml index 1f57055..2a1a117 100644 --- a/config.toml +++ b/config.toml @@ -13,6 +13,7 @@ allowed_redirect_uris = [ "http://localhost:9090/authorize", "http://localhost:9876/callback" ] +authorize_flow = "Implicit" [[roles]] slug = "basic" diff --git a/src/controllers/ui/authorize.rs b/src/controllers/ui/authorize.rs index e434a6c..0bcb1e5 100644 --- a/src/controllers/ui/authorize.rs +++ b/src/controllers/ui/authorize.rs @@ -8,7 +8,7 @@ use url::Url; use uuid::Uuid; use crate::{ - models::{authorization::Authorization, token_claims::UserTokenClaims}, + models::{authorization::Authorization, config::AppAuthorizeFlow, token_claims::UserTokenClaims}, renderer::TemplateRenderer, server::AppState, services::oauth2::{parse_scope, verify_redirect_uri}, utils::get_random_alphanumerical @@ -97,6 +97,7 @@ pub async fn authorize_form( ).into_response(); } }; + // 2. Check if the app is already authorized let authorizations_res = sqlx::query_as::<_, Authorization>( "SELECT * FROM authorizations WHERE user_id = $1 AND client_id = $2 AND scopes = $3" @@ -139,7 +140,19 @@ pub async fn authorize_form( } } + // 3. Check for implicit/explicit flow + if app.authorize_flow == AppAuthorizeFlow::Implicit { + debug!("Performing Implicit authorization flow."); + // Authorization already given, just redirect to the app + return perform_authorize( + State(app_state), + Extension(token_claims), + Form(authorization_params) + ).await.into_response() + } + // 4. Show form that POST to authorize + debug!("Performing explicit authorization flow."); renderer .render( "pages/authorize", diff --git a/src/models/config.rs b/src/models/config.rs index 2c09da5..1b7f2d9 100644 --- a/src/models/config.rs +++ b/src/models/config.rs @@ -12,6 +12,15 @@ struct InstanceConfig { logo_uri: Option } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[fully_pub] +enum AppAuthorizeFlow { + /// user must grant the app + Explicit, + /// authorized by default for all scopes + Implicit +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[fully_pub] struct Application { @@ -20,7 +29,8 @@ struct Application { description: String, client_id: String, client_secret: String, - allowed_redirect_uris: Vec + allowed_redirect_uris: Vec, + authorize_flow: AppAuthorizeFlow } #[derive(Debug, Clone, Serialize, Deserialize)]