mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(users): add endpoint for terminate auth select (#5135)
This commit is contained in:
@ -2312,3 +2312,41 @@ pub async fn sso_sign(
|
||||
|
||||
auth::cookies::set_cookie_response(response, token)
|
||||
}
|
||||
|
||||
pub async fn terminate_auth_select(
|
||||
state: SessionState,
|
||||
user_token: auth::UserFromSinglePurposeToken,
|
||||
req: user_api::AuthSelectRequest,
|
||||
) -> UserResponse<user_api::TokenResponse> {
|
||||
let user_from_db: domain::UserFromStorage = state
|
||||
.global_store
|
||||
.find_user_by_id(&user_token.user_id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
let user_authentication_method = state
|
||||
.store
|
||||
.get_user_authentication_method_by_id(&req.id)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
let current_flow = domain::CurrentFlow::new(user_token, domain::SPTFlow::AuthSelect.into())?;
|
||||
let mut next_flow = current_flow.next(user_from_db.clone(), &state).await?;
|
||||
|
||||
// Skip SSO if continue with password(TOTP)
|
||||
if next_flow.get_flow() == domain::UserFlow::SPTFlow(domain::SPTFlow::SSO)
|
||||
&& user_authentication_method.auth_type != common_enums::UserAuthType::OpenIdConnect
|
||||
{
|
||||
next_flow = next_flow.skip(user_from_db, &state).await?;
|
||||
}
|
||||
let token = next_flow.get_token(&state).await?;
|
||||
|
||||
auth::cookies::set_cookie_response(
|
||||
user_api::TokenResponse {
|
||||
token: token.clone(),
|
||||
token_type: next_flow.get_flow().into(),
|
||||
},
|
||||
token,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1417,7 +1417,8 @@ impl User {
|
||||
.service(
|
||||
web::resource("/list").route(web::get().to(list_user_authentication_methods)),
|
||||
)
|
||||
.service(web::resource("/url").route(web::get().to(get_sso_auth_url))),
|
||||
.service(web::resource("/url").route(web::get().to(get_sso_auth_url)))
|
||||
.service(web::resource("/select").route(web::post().to(terminate_auth_select))),
|
||||
);
|
||||
|
||||
#[cfg(feature = "email")]
|
||||
|
||||
@ -232,7 +232,8 @@ impl From<Flow> for ApiIdentifier {
|
||||
| Flow::UpdateUserAuthenticationMethod
|
||||
| Flow::ListUserAuthenticationMethods
|
||||
| Flow::GetSsoAuthUrl
|
||||
| Flow::SignInWithSso => Self::User,
|
||||
| Flow::SignInWithSso
|
||||
| Flow::AuthSelect => Self::User,
|
||||
|
||||
Flow::ListRoles
|
||||
| Flow::GetRole
|
||||
|
||||
@ -876,3 +876,22 @@ pub async fn list_user_authentication_methods(
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn terminate_auth_select(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
json_payload: web::Json<user_api::AuthSelectRequest>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::AuthSelect;
|
||||
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state.clone(),
|
||||
&req,
|
||||
json_payload.into_inner(),
|
||||
|state, user, req, _| user_core::terminate_auth_select(state, user, req),
|
||||
&auth::SinglePurposeJWTAuth(TokenPurpose::AuthSelect),
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
@ -51,9 +51,8 @@ impl SPTFlow {
|
||||
) -> UserResult<bool> {
|
||||
match self {
|
||||
// Auth
|
||||
// AuthSelect and SSO flow are not enabled, once the terminate SSO API is ready, we can enable these flows
|
||||
Self::AuthSelect => Ok(false),
|
||||
Self::SSO => Ok(false),
|
||||
Self::AuthSelect => Ok(true),
|
||||
Self::SSO => Ok(true),
|
||||
// TOTP
|
||||
Self::TOTP => Ok(!path.contains(&TokenPurpose::SSO)),
|
||||
// Main email APIs
|
||||
@ -311,6 +310,26 @@ impl NextFlow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn skip(self, user: UserFromStorage, state: &SessionState) -> UserResult<Self> {
|
||||
let flows = self.origin.get_flows();
|
||||
let index = flows
|
||||
.iter()
|
||||
.position(|flow| flow == &self.get_flow())
|
||||
.ok_or(UserErrors::InternalServerError)?;
|
||||
let remaining_flows = flows.iter().skip(index + 1);
|
||||
for flow in remaining_flows {
|
||||
if flow.is_required(&user, &self.path, state).await? {
|
||||
return Ok(Self {
|
||||
origin: self.origin.clone(),
|
||||
next_flow: *flow,
|
||||
user,
|
||||
path: self.path,
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(UserErrors::InternalServerError.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UserFlow> for TokenPurpose {
|
||||
|
||||
Reference in New Issue
Block a user