From 8e9bda654fac76ae8617d8b828e835d063ceba68 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Mon, 14 Mar 2022 16:33:24 +0100 Subject: [PATCH] Support prompt=create Allows RPs to ask for account creation See https://openid.net/specs/openid-connect-prompt-create-1_0.html --- crates/handlers/src/oauth2/authorization.rs | 13 ++++++++++++- crates/handlers/src/oauth2/discovery.rs | 11 ++++++++++- crates/oauth2-types/src/oidc.rs | 5 ++++- crates/oauth2-types/src/requests.rs | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/crates/handlers/src/oauth2/authorization.rs b/crates/handlers/src/oauth2/authorization.rs index 9d8b7a07..ced27600 100644 --- a/crates/handlers/src/oauth2/authorization.rs +++ b/crates/handlers/src/oauth2/authorization.rs @@ -73,7 +73,7 @@ use warp::{ Filter, Rejection, Reply, }; -use crate::views::{LoginRequest, PostAuthAction, ReauthRequest}; +use crate::views::{LoginRequest, PostAuthAction, ReauthRequest, RegisterRequest}; #[derive(Deserialize)] struct PartialParams { @@ -310,6 +310,7 @@ async fn actually_reply( .wrap_error() } +#[allow(clippy::too_many_lines)] async fn get( params: Params, maybe_session: Option>, @@ -427,6 +428,16 @@ async fn get( // Other cases where we already have a session step(next, user_session, txn).await } + (None, Some(Prompt::Create)) => { + // Client asked for a registration, show the registration prompt + txn.commit().await.wrap_error()?; + + let next: PostAuthAction = next.into(); + let next: RegisterRequest = next.into(); + let next = next.build_uri().wrap_error()?; + + Ok(ReplyOrBackToClient::Reply(Box::new(see_other(next)))) + } (None, _) => { // Other cases where we don't have a session, ask for a login txn.commit().await.wrap_error()?; diff --git a/crates/handlers/src/oauth2/discovery.rs b/crates/handlers/src/oauth2/discovery.rs index 838b2cc1..e15cb0a9 100644 --- a/crates/handlers/src/oauth2/discovery.rs +++ b/crates/handlers/src/oauth2/discovery.rs @@ -26,7 +26,7 @@ use mas_jose::SigningKeystore; use mas_warp_utils::filters::{self, url_builder::UrlBuilder}; use oauth2_types::{ oidc::{ClaimType, Metadata, SubjectType}, - requests::{Display, GrantType, ResponseMode}, + requests::{Display, GrantType, Prompt, ResponseMode}, scope, }; use warp::{filters::BoxedFilter, Filter, Reply}; @@ -158,6 +158,14 @@ pub(super) fn filter( let request_parameter_supported = Some(false); let request_uri_parameter_supported = Some(false); + let prompt_values_supported = Some({ + let mut s = HashSet::new(); + s.insert(Prompt::None); + s.insert(Prompt::Login); + s.insert(Prompt::Create); + s + }); + let metadata = Metadata { issuer, authorization_endpoint, @@ -182,6 +190,7 @@ pub(super) fn filter( claims_parameter_supported, request_parameter_supported, request_uri_parameter_supported, + prompt_values_supported, ..Metadata::default() }; diff --git a/crates/oauth2-types/src/oidc.rs b/crates/oauth2-types/src/oidc.rs index e6c74fef..2f225c95 100644 --- a/crates/oauth2-types/src/oidc.rs +++ b/crates/oauth2-types/src/oidc.rs @@ -25,7 +25,7 @@ use serde::Serialize; use serde_with::skip_serializing_none; use url::Url; -use crate::requests::{Display, GrantType, ResponseMode}; +use crate::requests::{Display, GrantType, Prompt, ResponseMode}; #[derive(Serialize, Clone, Copy, PartialEq, Eq, Hash, Debug)] #[serde(rename_all = "lowercase")] @@ -234,4 +234,7 @@ pub struct Metadata { /// Indicates whether the authorization server accepts authorization /// requests only via PAR. pub require_pushed_authorization_requests: Option, + + /// Array containing the list of prompt values that this OP supports. + pub prompt_values_supported: Option>, } diff --git a/crates/oauth2-types/src/requests.rs b/crates/oauth2-types/src/requests.rs index e9251303..4c7508df 100644 --- a/crates/oauth2-types/src/requests.rs +++ b/crates/oauth2-types/src/requests.rs @@ -95,6 +95,7 @@ pub enum Prompt { Login, Consent, SelectAccount, + Create, } #[serde_as]