mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(auth): Add profile_id in AuthenticationData (#5492)
This commit is contained in:
@ -138,7 +138,9 @@ pub async fn signup(
|
||||
.await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user_from_db, &user_role)
|
||||
.await?;
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
|
||||
@ -894,6 +896,7 @@ async fn handle_new_user_invitation(
|
||||
merchant_id: user_from_token.merchant_id.clone(),
|
||||
org_id: user_from_token.org_id.clone(),
|
||||
role_id: request.role_id.clone(),
|
||||
profile_id: None,
|
||||
};
|
||||
|
||||
let set_metadata_request = SetMetaDataRequest::IsChangePasswordRequired;
|
||||
@ -1036,8 +1039,12 @@ pub async fn accept_invite_from_email(
|
||||
.change_context(UserErrors::InternalServerError)?
|
||||
.into();
|
||||
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token(&state, &user_from_db, &update_status_result).await?;
|
||||
let token = utils::user::generate_jwt_auth_token_without_profile(
|
||||
&state,
|
||||
&user_from_db,
|
||||
&update_status_result,
|
||||
)
|
||||
.await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &update_status_result)
|
||||
.await;
|
||||
|
||||
@ -1263,6 +1270,7 @@ pub async fn switch_merchant_id(
|
||||
request.merchant_id.clone(),
|
||||
org_id.clone(),
|
||||
user_from_token.role_id.clone(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -1295,7 +1303,8 @@ pub async fn switch_merchant_id(
|
||||
.ok_or(report!(UserErrors::InvalidRoleOperation))
|
||||
.attach_printable("User doesn't have access to switch")?;
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user, user_role).await?;
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user, user_role).await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, user_role).await;
|
||||
|
||||
(token, user_role.role_id.clone())
|
||||
|
||||
@ -169,7 +169,9 @@ pub async fn transfer_org_ownership(
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user_from_db, &user_role)
|
||||
.await?;
|
||||
let response =
|
||||
utils::user::get_dashboard_entry_response(&state, user_from_db, user_role, token.clone())?;
|
||||
|
||||
@ -246,7 +248,9 @@ pub async fn merchant_select(
|
||||
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(&state, &user_role).await;
|
||||
|
||||
let token = utils::user::generate_jwt_auth_token(&state, &user_from_db, &user_role).await?;
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token_without_profile(&state, &user_from_db, &user_role)
|
||||
.await?;
|
||||
let response = utils::user::get_dashboard_entry_response(
|
||||
&state,
|
||||
user_from_db,
|
||||
|
||||
@ -273,6 +273,7 @@ impl MerchantAccountInterface for Store {
|
||||
.change_context(errors::StorageError::DecryptionError)?,
|
||||
|
||||
key_store,
|
||||
profile_id: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,14 @@ mod detached;
|
||||
pub struct AuthenticationData {
|
||||
pub merchant_account: domain::MerchantAccount,
|
||||
pub key_store: domain::MerchantKeyStore,
|
||||
pub profile_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AuthenticationDataWithMultipleProfiles {
|
||||
pub merchant_account: domain::MerchantAccount,
|
||||
pub key_store: domain::MerchantKeyStore,
|
||||
pub profile_id_list: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
@ -178,6 +186,7 @@ pub struct AuthToken {
|
||||
pub role_id: String,
|
||||
pub exp: u64,
|
||||
pub org_id: id_type::OrganizationId,
|
||||
pub profile_id: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "olap")]
|
||||
@ -188,6 +197,7 @@ impl AuthToken {
|
||||
role_id: String,
|
||||
settings: &Settings,
|
||||
org_id: id_type::OrganizationId,
|
||||
profile_id: Option<String>,
|
||||
) -> UserResult<String> {
|
||||
let exp_duration = std::time::Duration::from_secs(consts::JWT_TOKEN_TIME_IN_SECS);
|
||||
let exp = jwt::generate_exp(exp_duration)?.as_secs();
|
||||
@ -197,6 +207,7 @@ impl AuthToken {
|
||||
role_id,
|
||||
exp,
|
||||
org_id,
|
||||
profile_id,
|
||||
};
|
||||
jwt::generate_jwt(&token_payload, settings).await
|
||||
}
|
||||
@ -208,6 +219,7 @@ pub struct UserFromToken {
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub role_id: String,
|
||||
pub org_id: id_type::OrganizationId,
|
||||
pub profile_id: Option<String>,
|
||||
}
|
||||
|
||||
pub struct UserIdFromAuth {
|
||||
@ -376,6 +388,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: None,
|
||||
};
|
||||
Ok((
|
||||
auth.clone(),
|
||||
@ -512,6 +525,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: None,
|
||||
};
|
||||
|
||||
Ok(auth)
|
||||
@ -735,6 +749,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: None,
|
||||
};
|
||||
Ok((
|
||||
auth.clone(),
|
||||
@ -852,6 +867,61 @@ where
|
||||
merchant_id: payload.merchant_id.clone(),
|
||||
org_id: payload.org_id,
|
||||
role_id: payload.role_id,
|
||||
profile_id: payload.profile_id,
|
||||
},
|
||||
AuthenticationType::MerchantJwt {
|
||||
merchant_id: payload.merchant_id,
|
||||
user_id: Some(payload.user_id),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "olap")]
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationDataWithMultipleProfiles, A> for JWTAuth
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationDataWithMultipleProfiles, AuthenticationType)> {
|
||||
let payload = parse_jwt_payload::<A, AuthToken>(request_headers, state).await?;
|
||||
if payload.check_in_blacklist(state).await? {
|
||||
return Err(errors::ApiErrorResponse::InvalidJwtToken.into());
|
||||
}
|
||||
|
||||
let permissions = authorization::get_permissions(state, &payload).await?;
|
||||
authorization::check_authorization(&self.0, &permissions)?;
|
||||
let key_manager_state = &(&state.session_state()).into();
|
||||
let key_store = state
|
||||
.store()
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
&payload.merchant_id,
|
||||
&state.store().get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InvalidJwtToken)
|
||||
.attach_printable("Failed to fetch merchant key store for the merchant id")?;
|
||||
|
||||
let merchant = state
|
||||
.store()
|
||||
.find_merchant_account_by_merchant_id(
|
||||
key_manager_state,
|
||||
&payload.merchant_id,
|
||||
&key_store,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InvalidJwtToken)?;
|
||||
|
||||
Ok((
|
||||
AuthenticationDataWithMultipleProfiles {
|
||||
key_store,
|
||||
merchant_account: merchant,
|
||||
profile_id_list: None,
|
||||
},
|
||||
AuthenticationType::MerchantJwt {
|
||||
merchant_id: payload.merchant_id,
|
||||
@ -1020,6 +1090,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: payload.profile_id,
|
||||
};
|
||||
Ok((
|
||||
auth.clone(),
|
||||
@ -1075,6 +1146,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: payload.profile_id,
|
||||
};
|
||||
Ok((
|
||||
(auth.clone(), payload.user_id.clone()),
|
||||
@ -1110,6 +1182,7 @@ where
|
||||
merchant_id: payload.merchant_id.clone(),
|
||||
org_id: payload.org_id,
|
||||
role_id: payload.role_id,
|
||||
profile_id: payload.profile_id,
|
||||
},
|
||||
AuthenticationType::MerchantJwt {
|
||||
merchant_id: payload.merchant_id,
|
||||
@ -1175,6 +1248,7 @@ where
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: payload.profile_id,
|
||||
};
|
||||
Ok((
|
||||
auth.clone(),
|
||||
|
||||
@ -1144,8 +1144,12 @@ impl SignInWithSingleRoleStrategy {
|
||||
self,
|
||||
state: &SessionState,
|
||||
) -> UserResult<user_api::SignInResponse> {
|
||||
let token =
|
||||
utils::user::generate_jwt_auth_token(state, &self.user, &self.user_role).await?;
|
||||
let token = utils::user::generate_jwt_auth_token_without_profile(
|
||||
state,
|
||||
&self.user,
|
||||
&self.user_role,
|
||||
)
|
||||
.await?;
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(state, &self.user_role).await;
|
||||
|
||||
let dashboard_entry_response =
|
||||
|
||||
@ -101,7 +101,7 @@ impl JWTFlow {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub async fn generate_jwt(
|
||||
pub async fn generate_jwt_without_profile(
|
||||
self,
|
||||
state: &SessionState,
|
||||
next_flow: &NextFlow,
|
||||
@ -119,6 +119,7 @@ impl JWTFlow {
|
||||
.org_id
|
||||
.clone()
|
||||
.ok_or(report!(UserErrors::InternalServerError))?,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map(|token| token.into())
|
||||
@ -293,7 +294,9 @@ impl NextFlow {
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(state, &user_role)
|
||||
.await;
|
||||
|
||||
jwt_flow.generate_jwt(state, self, &user_role).await
|
||||
jwt_flow
|
||||
.generate_jwt_without_profile(state, self, &user_role)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -313,7 +316,9 @@ impl NextFlow {
|
||||
utils::user_role::set_role_permissions_in_cache_by_user_role(state, user_role)
|
||||
.await;
|
||||
|
||||
jwt_flow.generate_jwt(state, self, user_role).await
|
||||
jwt_flow
|
||||
.generate_jwt_without_profile(state, self, user_role)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ impl UserFromToken {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn generate_jwt_auth_token(
|
||||
pub async fn generate_jwt_auth_token_without_profile(
|
||||
state: &SessionState,
|
||||
user: &UserFromStorage,
|
||||
user_role: &UserRole,
|
||||
@ -102,6 +102,7 @@ pub async fn generate_jwt_auth_token(
|
||||
.ok_or(report!(UserErrors::InternalServerError))
|
||||
.attach_printable("org_id not found for user_role")?
|
||||
.clone(),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
Ok(Secret::new(token))
|
||||
@ -113,6 +114,7 @@ pub async fn generate_jwt_auth_token_with_custom_role_attributes(
|
||||
merchant_id: id_type::MerchantId,
|
||||
org_id: id_type::OrganizationId,
|
||||
role_id: String,
|
||||
profile_id: Option<String>,
|
||||
) -> UserResult<Secret<String>> {
|
||||
let token = AuthToken::new_token(
|
||||
user.get_user_id().to_string(),
|
||||
@ -120,6 +122,7 @@ pub async fn generate_jwt_auth_token_with_custom_role_attributes(
|
||||
role_id,
|
||||
&state.conf,
|
||||
org_id,
|
||||
profile_id,
|
||||
)
|
||||
.await?;
|
||||
Ok(Secret::new(token))
|
||||
|
||||
Reference in New Issue
Block a user