mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(openapi): add payment get to openapi (#6539)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: hrithikesh026 <hrithikesh.vm@juspay.in>
This commit is contained in:
@ -51,8 +51,8 @@ pub mod routes {
|
||||
|
||||
impl Analytics {
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(_state: AppState) -> Scope {
|
||||
todo!()
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
web::scope("/analytics").app_data(web::Data::new(state))
|
||||
}
|
||||
#[cfg(feature = "v1")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
|
||||
@ -2969,19 +2969,11 @@ pub async fn retrieve_connector(
|
||||
#[cfg(all(feature = "olap", feature = "v2"))]
|
||||
pub async fn list_connectors_for_a_profile(
|
||||
state: SessionState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
key_store: domain::MerchantKeyStore,
|
||||
profile_id: id_type::ProfileId,
|
||||
) -> RouterResponse<Vec<api_models::admin::MerchantConnectorListResponse>> {
|
||||
let store = state.store.as_ref();
|
||||
let key_manager_state = &(&state).into();
|
||||
let key_store = store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
key_manager_state,
|
||||
merchant_account.get_id(),
|
||||
&store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
||||
|
||||
let merchant_connector_accounts = store
|
||||
.list_connector_account_by_profile_id(key_manager_state, &profile_id, &key_store)
|
||||
|
||||
@ -125,15 +125,19 @@ pub fn mk_app(
|
||||
{
|
||||
// This is a more specific route as compared to `MerchantConnectorAccount`
|
||||
// so it is registered before `MerchantConnectorAccount`.
|
||||
server_app = server_app
|
||||
.service(routes::ProfileNew::server(state.clone()))
|
||||
.service(routes::Profile::server(state.clone()))
|
||||
#[cfg(feature = "v1")]
|
||||
{
|
||||
server_app = server_app
|
||||
.service(routes::ProfileNew::server(state.clone()))
|
||||
.service(routes::Forex::server(state.clone()));
|
||||
}
|
||||
|
||||
server_app = server_app.service(routes::Profile::server(state.clone()))
|
||||
}
|
||||
server_app = server_app
|
||||
.service(routes::Payments::server(state.clone()))
|
||||
.service(routes::Customers::server(state.clone()))
|
||||
.service(routes::Configs::server(state.clone()))
|
||||
.service(routes::Forex::server(state.clone()))
|
||||
.service(routes::MerchantConnectorAccount::server(state.clone()));
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
@ -163,7 +167,6 @@ pub fn mk_app(
|
||||
.service(routes::Organization::server(state.clone()))
|
||||
.service(routes::MerchantAccount::server(state.clone()))
|
||||
.service(routes::ApiKeys::server(state.clone()))
|
||||
.service(routes::Analytics::server(state.clone()))
|
||||
.service(routes::Routing::server(state.clone()));
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
@ -178,11 +181,12 @@ pub fn mk_app(
|
||||
.service(routes::User::server(state.clone()))
|
||||
.service(routes::ConnectorOnboarding::server(state.clone()))
|
||||
.service(routes::Verify::server(state.clone()))
|
||||
.service(routes::Analytics::server(state.clone()))
|
||||
.service(routes::WebhookEvents::server(state.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
#[cfg(all(feature = "payouts", feature = "v1"))]
|
||||
{
|
||||
server_app = server_app
|
||||
.service(routes::Payouts::server(state.clone()))
|
||||
@ -195,7 +199,9 @@ pub fn mk_app(
|
||||
not(feature = "customer_v2")
|
||||
))]
|
||||
{
|
||||
server_app = server_app.service(routes::StripeApis::server(state.clone()));
|
||||
server_app = server_app
|
||||
.service(routes::StripeApis::server(state.clone()))
|
||||
.service(routes::Cards::server(state.clone()));
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "recon", feature = "v1"))]
|
||||
@ -203,7 +209,6 @@ pub fn mk_app(
|
||||
server_app = server_app.service(routes::Recon::server(state.clone()));
|
||||
}
|
||||
|
||||
server_app = server_app.service(routes::Cards::server(state.clone()));
|
||||
server_app = server_app.service(routes::Cache::server(state.clone()));
|
||||
server_app = server_app.service(routes::Health::server(state.clone()));
|
||||
|
||||
|
||||
@ -61,13 +61,11 @@ pub mod webhooks;
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
pub use self::app::DummyConnector;
|
||||
#[cfg(any(feature = "olap", feature = "oltp"))]
|
||||
pub use self::app::Forex;
|
||||
#[cfg(all(feature = "olap", feature = "recon", feature = "v1"))]
|
||||
pub use self::app::Recon;
|
||||
pub use self::app::{
|
||||
ApiKeys, AppState, ApplePayCertificatesMigration, Cache, Cards, Configs, ConnectorOnboarding,
|
||||
Customers, Disputes, EphemeralKey, Files, Gsm, Health, Mandates, MerchantAccount,
|
||||
Customers, Disputes, EphemeralKey, Files, Forex, Gsm, Health, Mandates, MerchantAccount,
|
||||
MerchantConnectorAccount, PaymentLink, PaymentMethods, Payments, Poll, Profile, ProfileNew,
|
||||
Refunds, SessionState, User, Webhooks,
|
||||
};
|
||||
|
||||
@ -458,14 +458,14 @@ pub async fn connector_retrieve(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, auth_data, req, _| {
|
||||
retrieve_connector(
|
||||
state,
|
||||
auth_data.merchant_account,
|
||||
auth_data.key_store,
|
||||
req.id.clone(),
|
||||
)
|
||||
},
|
||||
|state,
|
||||
auth::AuthenticationData {
|
||||
merchant_account,
|
||||
key_store,
|
||||
..
|
||||
},
|
||||
req,
|
||||
_| { retrieve_connector(state, merchant_account, key_store, req.id.clone()) },
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::JWTAuthMerchantFromHeader {
|
||||
@ -493,8 +493,8 @@ pub async fn connector_list(
|
||||
state,
|
||||
&req,
|
||||
profile_id.to_owned(),
|
||||
|state, auth, _, _| {
|
||||
list_connectors_for_a_profile(state, auth.merchant_account.clone(), profile_id.clone())
|
||||
|state, auth::AuthenticationData { key_store, .. }, _, _| {
|
||||
list_connectors_for_a_profile(state, key_store, profile_id.clone())
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
@ -793,14 +793,14 @@ pub async fn connector_delete(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, auth_data, req, _| {
|
||||
delete_connector(
|
||||
state,
|
||||
auth_data.merchant_account,
|
||||
auth_data.key_store,
|
||||
req.id,
|
||||
)
|
||||
},
|
||||
|state,
|
||||
auth::AuthenticationData {
|
||||
merchant_account,
|
||||
key_store,
|
||||
..
|
||||
},
|
||||
req,
|
||||
_| { delete_connector(state, merchant_account, key_store, req.id) },
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::JWTAuthMerchantFromHeader {
|
||||
|
||||
@ -56,8 +56,8 @@ pub async fn api_key_create(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, auth_data, payload, _| async {
|
||||
api_keys::create_api_key(state, payload, auth_data.key_store).await
|
||||
|state, auth::AuthenticationDataWithoutProfile { key_store, .. }, payload, _| async {
|
||||
api_keys::create_api_key(state, payload, key_store).await
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
@ -86,10 +86,15 @@ pub async fn api_key_retrieve(
|
||||
state,
|
||||
&req,
|
||||
&key_id,
|
||||
|state, auth_data, key_id, _| {
|
||||
|state,
|
||||
auth::AuthenticationDataWithoutProfile {
|
||||
merchant_account, ..
|
||||
},
|
||||
key_id,
|
||||
_| {
|
||||
api_keys::retrieve_api_key(
|
||||
state,
|
||||
auth_data.merchant_account.get_id().to_owned(),
|
||||
merchant_account.get_id().to_owned(),
|
||||
key_id.to_owned(),
|
||||
)
|
||||
},
|
||||
@ -190,8 +195,13 @@ pub async fn api_key_update(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, authentication_data, mut payload, _| {
|
||||
payload.merchant_id = authentication_data.merchant_account.get_id().to_owned();
|
||||
|state,
|
||||
auth::AuthenticationDataWithoutProfile {
|
||||
merchant_account, ..
|
||||
},
|
||||
mut payload,
|
||||
_| {
|
||||
payload.merchant_id = merchant_account.get_id().to_owned();
|
||||
api_keys::update_api_key(state, payload)
|
||||
},
|
||||
auth::auth_type(
|
||||
@ -319,8 +329,13 @@ pub async fn api_key_list(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, authentication_data, payload, _| async move {
|
||||
let merchant_id = authentication_data.merchant_account.get_id().to_owned();
|
||||
|state,
|
||||
auth::AuthenticationDataWithoutProfile {
|
||||
merchant_account, ..
|
||||
},
|
||||
payload,
|
||||
_| async move {
|
||||
let merchant_id = merchant_account.get_id().to_owned();
|
||||
api_keys::list_api_keys(state, merchant_id, payload.limit, payload.skip).await
|
||||
},
|
||||
auth::auth_type(
|
||||
|
||||
@ -674,9 +674,8 @@ impl Payments {
|
||||
#[cfg(any(feature = "olap", feature = "oltp"))]
|
||||
pub struct Forex;
|
||||
|
||||
#[cfg(any(feature = "olap", feature = "oltp"))]
|
||||
#[cfg(all(any(feature = "olap", feature = "oltp"), feature = "v1"))]
|
||||
impl Forex {
|
||||
#[cfg(feature = "v1")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
web::scope("/forex")
|
||||
.app_data(web::Data::new(state.clone()))
|
||||
@ -686,10 +685,6 @@ impl Forex {
|
||||
web::resource("/convert_from_minor").route(web::get().to(currency::convert_forex)),
|
||||
)
|
||||
}
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "olap")]
|
||||
@ -1064,13 +1059,8 @@ impl Refunds {
|
||||
#[cfg(feature = "payouts")]
|
||||
pub struct Payouts;
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
#[cfg(all(feature = "payouts", feature = "v1"))]
|
||||
impl Payouts {
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
todo!()
|
||||
}
|
||||
#[cfg(feature = "v1")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
let mut route = web::scope("/payouts").app_data(web::Data::new(state));
|
||||
route = route.service(web::resource("/create").route(web::post().to(payouts_create)));
|
||||
@ -1578,17 +1568,13 @@ impl Disputes {
|
||||
|
||||
pub struct Cards;
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
impl Cards {
|
||||
#[cfg(feature = "v1")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
web::scope("/cards")
|
||||
.app_data(web::Data::new(state))
|
||||
.service(web::resource("/{bin}").route(web::get().to(card_iin_info)))
|
||||
}
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Files;
|
||||
@ -1647,9 +1633,8 @@ impl PaymentLink {
|
||||
#[cfg(feature = "payouts")]
|
||||
pub struct PayoutLink;
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
#[cfg(all(feature = "payouts", feature = "v1"))]
|
||||
impl PayoutLink {
|
||||
#[cfg(feature = "v1")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
let mut route = web::scope("/payout_link").app_data(web::Data::new(state));
|
||||
route = route.service(
|
||||
@ -1657,10 +1642,6 @@ impl PayoutLink {
|
||||
);
|
||||
route
|
||||
}
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Profile;
|
||||
@ -1789,7 +1770,7 @@ impl ProfileNew {
|
||||
}
|
||||
#[cfg(feature = "v2")]
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
todo!()
|
||||
web::scope("/account/{account_id}/profile").app_data(web::Data::new(state))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -56,9 +56,13 @@ pub async fn profile_create(
|
||||
state,
|
||||
&req,
|
||||
payload,
|
||||
|state, auth_data, req, _| {
|
||||
create_profile(state, req, auth_data.merchant_account, auth_data.key_store)
|
||||
},
|
||||
|state,
|
||||
auth::AuthenticationDataWithoutProfile {
|
||||
merchant_account,
|
||||
key_store,
|
||||
},
|
||||
req,
|
||||
_| { create_profile(state, req, merchant_account, key_store) },
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::JWTAuthMerchantFromHeader {
|
||||
@ -118,7 +122,9 @@ pub async fn profile_retrieve(
|
||||
state,
|
||||
&req,
|
||||
profile_id,
|
||||
|state, auth_data, profile_id, _| retrieve_profile(state, profile_id, auth_data.key_store),
|
||||
|state, auth::AuthenticationDataWithoutProfile { key_store, .. }, profile_id, _| {
|
||||
retrieve_profile(state, profile_id, key_store)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::JWTAuthMerchantFromHeader {
|
||||
@ -181,7 +187,9 @@ pub async fn profile_update(
|
||||
state,
|
||||
&req,
|
||||
json_payload.into_inner(),
|
||||
|state, auth_data, req, _| update_profile(state, &profile_id, auth_data.key_store, req),
|
||||
|state, auth::AuthenticationDataWithoutProfile { key_store, .. }, req, _| {
|
||||
update_profile(state, &profile_id, key_store, req)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::JWTAuthMerchantFromHeader {
|
||||
@ -217,6 +225,8 @@ pub async fn profile_delete(
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
#[instrument(skip_all, fields(flow = ?Flow::ProfileList))]
|
||||
pub async fn profiles_list(
|
||||
state: web::Data<AppState>,
|
||||
@ -233,7 +243,38 @@ pub async fn profiles_list(
|
||||
merchant_id.clone(),
|
||||
|state, _auth, merchant_id, _| list_profile(state, merchant_id, None),
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
||||
&auth::JWTAuthMerchantFromRoute {
|
||||
merchant_id,
|
||||
required_permission: permissions::Permission::MerchantAccountRead,
|
||||
},
|
||||
req.headers(),
|
||||
),
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[instrument(skip_all, fields(flow = ?Flow::ProfileList))]
|
||||
pub async fn profiles_list(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<common_utils::id_type::MerchantId>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::ProfileList;
|
||||
let merchant_id = path.into_inner();
|
||||
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
merchant_id.clone(),
|
||||
|state, auth::AuthenticationDataWithoutProfile { .. }, merchant_id, _| {
|
||||
list_profile(state, merchant_id, None)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
||||
&auth::JWTAuthMerchantFromRoute {
|
||||
merchant_id,
|
||||
required_permission: permissions::Permission::MerchantAccountRead,
|
||||
|
||||
@ -69,6 +69,12 @@ pub struct AuthenticationData {
|
||||
pub profile: domain::Profile,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthenticationDataWithoutProfile {
|
||||
pub merchant_account: domain::MerchantAccount,
|
||||
pub key_store: domain::MerchantKeyStore,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthenticationDataWithMultipleProfiles {
|
||||
pub merchant_account: domain::MerchantAccount,
|
||||
@ -437,17 +443,6 @@ where
|
||||
.change_context(errors::ApiErrorResponse::Unauthorized)
|
||||
.attach_printable("Failed to fetch merchant key store for the merchant id")?;
|
||||
|
||||
let profile = state
|
||||
.store()
|
||||
.find_business_profile_by_merchant_id_profile_id(
|
||||
key_manager_state,
|
||||
&key_store,
|
||||
&stored_api_key.merchant_id,
|
||||
&profile_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let merchant = state
|
||||
.store()
|
||||
.find_merchant_account_by_merchant_id(
|
||||
@ -458,6 +453,12 @@ where
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let profile = state
|
||||
.store()
|
||||
.find_business_profile_by_profile_id(key_manager_state, &key_store, &profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let auth = AuthenticationData {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
@ -683,14 +684,14 @@ where
|
||||
let key_manager_state = &(&state.session_state()).into();
|
||||
let profile = state
|
||||
.store()
|
||||
.find_business_profile_by_merchant_id_profile_id(
|
||||
.find_business_profile_by_profile_id(
|
||||
key_manager_state,
|
||||
&auth_data.key_store,
|
||||
auth_data.merchant_account.get_id(),
|
||||
&profile_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let auth_data_v2 = AuthenticationData {
|
||||
merchant_account: auth_data.merchant_account,
|
||||
key_store: auth_data.key_store,
|
||||
@ -1006,6 +1007,53 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationDataWithoutProfile, A>
|
||||
for AdminApiAuthWithMerchantIdFromRoute
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationDataWithoutProfile, AuthenticationType)> {
|
||||
AdminApiAuth
|
||||
.authenticate_and_fetch(request_headers, state)
|
||||
.await?;
|
||||
|
||||
let merchant_id = self.0.clone();
|
||||
|
||||
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
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let merchant = state
|
||||
.store()
|
||||
.find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let auth = AuthenticationDataWithoutProfile {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
};
|
||||
|
||||
Ok((
|
||||
auth,
|
||||
AuthenticationType::AdminApiAuthWithMerchantId { merchant_id },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper struct to extract headers from the request
|
||||
pub(crate) struct HeaderMapStruct<'a> {
|
||||
headers: &'a HeaderMap,
|
||||
@ -1181,6 +1229,53 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationDataWithoutProfile, A>
|
||||
for AdminApiAuthWithMerchantIdFromHeader
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationDataWithoutProfile, AuthenticationType)> {
|
||||
AdminApiAuth
|
||||
.authenticate_and_fetch(request_headers, state)
|
||||
.await?;
|
||||
|
||||
let merchant_id = HeaderMapStruct::new(request_headers)
|
||||
.get_id_type_from_header::<id_type::MerchantId>(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
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
||||
|
||||
let merchant = state
|
||||
.store()
|
||||
.find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||
|
||||
let auth = AuthenticationDataWithoutProfile {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
};
|
||||
Ok((
|
||||
auth,
|
||||
AuthenticationType::AdminApiAuthWithMerchantId { merchant_id },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EphemeralKeyAuth;
|
||||
|
||||
@ -1827,6 +1922,72 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationDataWithoutProfile, A> for JWTAuthMerchantFromHeader
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationDataWithoutProfile, 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 role_info = authorization::get_role_info(state, &payload).await?;
|
||||
authorization::check_permission(&self.required_permission, &role_info)?;
|
||||
|
||||
let merchant_id_from_header = HeaderMapStruct::new(request_headers)
|
||||
.get_id_type_from_header::<id_type::MerchantId>(headers::X_MERCHANT_ID)?;
|
||||
|
||||
// Check if token has access to MerchantId that has been requested through headers
|
||||
if payload.merchant_id != merchant_id_from_header {
|
||||
return Err(report!(errors::ApiErrorResponse::InvalidJwtToken));
|
||||
}
|
||||
|
||||
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
|
||||
.to_not_found_response(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
|
||||
.to_not_found_response(errors::ApiErrorResponse::InvalidJwtToken)
|
||||
.attach_printable("Failed to fetch merchant account for the merchant id")?;
|
||||
|
||||
let auth = AuthenticationDataWithoutProfile {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
};
|
||||
|
||||
Ok((
|
||||
auth,
|
||||
AuthenticationType::MerchantJwt {
|
||||
merchant_id: payload.merchant_id,
|
||||
user_id: Some(payload.user_id),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<(), A> for JWTAuthMerchantFromRoute
|
||||
where
|
||||
@ -2000,6 +2161,68 @@ where
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[async_trait]
|
||||
impl<A> AuthenticateAndFetch<AuthenticationDataWithoutProfile, A> for JWTAuthMerchantFromRoute
|
||||
where
|
||||
A: SessionStateInfo + Sync,
|
||||
{
|
||||
async fn authenticate_and_fetch(
|
||||
&self,
|
||||
request_headers: &HeaderMap,
|
||||
state: &A,
|
||||
) -> RouterResult<(AuthenticationDataWithoutProfile, 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());
|
||||
}
|
||||
|
||||
if payload.merchant_id != self.merchant_id {
|
||||
return Err(report!(errors::ApiErrorResponse::InvalidJwtToken));
|
||||
}
|
||||
|
||||
let role_info = authorization::get_role_info(state, &payload).await?;
|
||||
authorization::check_permission(&self.required_permission, &role_info)?;
|
||||
|
||||
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
|
||||
.to_not_found_response(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
|
||||
.to_not_found_response(errors::ApiErrorResponse::InvalidJwtToken)
|
||||
.attach_printable("Failed to fetch merchant account for the merchant id")?;
|
||||
|
||||
let auth = AuthenticationDataWithoutProfile {
|
||||
merchant_account: merchant,
|
||||
key_store,
|
||||
};
|
||||
Ok((
|
||||
auth.clone(),
|
||||
AuthenticationType::MerchantJwt {
|
||||
merchant_id: auth.merchant_account.get_id().clone(),
|
||||
user_id: Some(payload.user_id),
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct JWTAuthMerchantAndProfileFromRoute {
|
||||
pub merchant_id: id_type::MerchantId,
|
||||
pub profile_id: id_type::ProfileId,
|
||||
|
||||
Reference in New Issue
Block a user