mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat: use admin_api_key auth along with merchant_id for connector list, retrieve and update apis (#5613)
This commit is contained in:
@ -434,7 +434,7 @@ pub async fn connector_retrieve(
|
||||
)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::HeaderAuth(auth::ApiKeyAuth),
|
||||
&auth::AdminApiAuthWithMerchantId::default(),
|
||||
&auth::JWTAuthMerchantFromRoute {
|
||||
merchant_id,
|
||||
required_permission: Permission::MerchantConnectorAccountRead,
|
||||
@ -533,7 +533,7 @@ pub async fn payment_connector_list(
|
||||
merchant_id.to_owned(),
|
||||
|state, _auth, merchant_id, _| list_payment_connectors(state, merchant_id, None),
|
||||
auth::auth_type(
|
||||
&auth::HeaderAuth(auth::ApiKeyAuth),
|
||||
&auth::AdminApiAuthWithMerchantId::default(),
|
||||
&auth::JWTAuthMerchantFromRoute {
|
||||
merchant_id,
|
||||
required_permission: Permission::MerchantConnectorAccountRead,
|
||||
@ -593,7 +593,7 @@ pub async fn connector_update(
|
||||
)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::HeaderAuth(auth::ApiKeyAuth),
|
||||
&auth::AdminApiAuthWithMerchantId::default(),
|
||||
&auth::JWTAuthMerchantFromRoute {
|
||||
merchant_id: merchant_id.clone(),
|
||||
required_permission: Permission::MerchantConnectorAccountWrite,
|
||||
|
||||
@ -37,6 +37,7 @@ use crate::{
|
||||
api_keys,
|
||||
errors::{self, utils::StorageErrorExt, RouterResult},
|
||||
},
|
||||
headers,
|
||||
routes::app::SessionStateInfo,
|
||||
services::api,
|
||||
types::domain,
|
||||
@ -76,6 +77,9 @@ pub enum AuthenticationType {
|
||||
key_id: String,
|
||||
},
|
||||
AdminApiKey,
|
||||
AdminApiAuthWithMerchantId {
|
||||
merchant_id: id_type::MerchantId,
|
||||
},
|
||||
MerchantJwt {
|
||||
merchant_id: id_type::MerchantId,
|
||||
user_id: Option<String>,
|
||||
@ -122,6 +126,7 @@ impl AuthenticationType {
|
||||
merchant_id,
|
||||
key_id: _,
|
||||
}
|
||||
| Self::AdminApiAuthWithMerchantId { merchant_id }
|
||||
| Self::MerchantId { merchant_id }
|
||||
| Self::PublishableKey { merchant_id }
|
||||
| Self::MerchantJwt {
|
||||
@ -655,7 +660,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct AdminApiAuth;
|
||||
|
||||
#[async_trait]
|
||||
@ -683,6 +688,81 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct AdminApiAuthWithMerchantId(AdminApiAuth);
|
||||
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationData, A> for AdminApiAuthWithMerchantId
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationData, AuthenticationType)> {
|
||||
self.0
|
||||
.authenticate_and_fetch(request_headers, state)
|
||||
.await?;
|
||||
let merchant_id =
|
||||
get_header_value_by_key(headers::X_MERCHANT_ID.to_string(), request_headers)?
|
||||
.get_required_value(headers::X_MERCHANT_ID)
|
||||
.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||
message: format!("`{}` header is missing", headers::X_MERCHANT_ID),
|
||||
})
|
||||
.and_then(|merchant_id_str| {
|
||||
id_type::MerchantId::try_from(std::borrow::Cow::from(
|
||||
merchant_id_str.to_string(),
|
||||
))
|
||||
.change_context(
|
||||
errors::ApiErrorResponse::InvalidRequestData {
|
||||
message: format!("`{}` header is invalid", headers::X_MERCHANT_ID),
|
||||
},
|
||||
)
|
||||
})?;
|
||||
let key_manager_state = &(&state.session_state()).into();
|
||||
let key_store = state
|
||||
.store()
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
&merchant_id,
|
||||
&state.store().get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_not_found() {
|
||||
e.change_context(errors::ApiErrorResponse::Unauthorized)
|
||||
} else {
|
||||
e.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.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, &merchant_id, &key_store)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.current_context().is_db_not_found() {
|
||||
e.change_context(errors::ApiErrorResponse::Unauthorized)
|
||||
} else {
|
||||
e.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to fetch merchant account for the merchant id")
|
||||
}
|
||||
})?;
|
||||
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
profile_id: None,
|
||||
};
|
||||
Ok((
|
||||
auth,
|
||||
AuthenticationType::AdminApiAuthWithMerchantId { merchant_id },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EphemeralKeyAuth;
|
||||
|
||||
@ -1425,7 +1505,7 @@ pub fn is_ephemeral_auth<A: SessionStateInfo + Sync + Send>(
|
||||
}
|
||||
|
||||
pub fn is_jwt_auth(headers: &HeaderMap) -> bool {
|
||||
headers.get(crate::headers::AUTHORIZATION).is_some()
|
||||
headers.get(headers::AUTHORIZATION).is_some()
|
||||
|| get_cookie_from_header(headers)
|
||||
.and_then(cookies::parse_cookie)
|
||||
.is_ok()
|
||||
@ -1465,8 +1545,8 @@ pub fn get_header_value_by_key(key: String, headers: &HeaderMap) -> RouterResult
|
||||
|
||||
pub fn get_jwt_from_authorization_header(headers: &HeaderMap) -> RouterResult<&str> {
|
||||
headers
|
||||
.get(crate::headers::AUTHORIZATION)
|
||||
.get_required_value(crate::headers::AUTHORIZATION)?
|
||||
.get(headers::AUTHORIZATION)
|
||||
.get_required_value(headers::AUTHORIZATION)?
|
||||
.to_str()
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to convert JWT token to string")?
|
||||
|
||||
Reference in New Issue
Block a user