diff --git a/crates/router/src/routes/disputes.rs b/crates/router/src/routes/disputes.rs index 3eed0591db..a6670414f6 100644 --- a/crates/router/src/routes/disputes.rs +++ b/crates/router/src/routes/disputes.rs @@ -43,7 +43,9 @@ pub async fn retrieve_dispute( state, &req, dispute_id, - |state, auth, req, _| disputes::retrieve_dispute(state, auth.merchant_account, None, req), + |state, auth, req, _| { + disputes::retrieve_dispute(state, auth.merchant_account, auth.profile_id, req) + }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), &auth::JWTAuth(Permission::DisputeRead), @@ -133,7 +135,13 @@ pub async fn accept_dispute( &req, dispute_id, |state, auth, req, _| { - disputes::accept_dispute(state, auth.merchant_account, None, auth.key_store, req) + disputes::accept_dispute( + state, + auth.merchant_account, + auth.profile_id, + auth.key_store, + req, + ) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), @@ -170,7 +178,13 @@ pub async fn submit_dispute_evidence( &req, json_payload.into_inner(), |state, auth, req, _| { - disputes::submit_evidence(state, auth.merchant_account, None, auth.key_store, req) + disputes::submit_evidence( + state, + auth.merchant_account, + auth.profile_id, + auth.key_store, + req, + ) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), @@ -215,7 +229,13 @@ pub async fn attach_dispute_evidence( &req, attach_evidence_request, |state, auth, req, _| { - disputes::attach_evidence(state, auth.merchant_account, None, auth.key_store, req) + disputes::attach_evidence( + state, + auth.merchant_account, + auth.profile_id, + auth.key_store, + req, + ) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), @@ -258,7 +278,7 @@ pub async fn retrieve_dispute_evidence( &req, dispute_id, |state, auth, req, _| { - disputes::retrieve_dispute_evidence(state, auth.merchant_account, None, req) + disputes::retrieve_dispute_evidence(state, auth.merchant_account, auth.profile_id, req) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index 58d331d0fe..e226f3f07a 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -200,7 +200,7 @@ pub async fn payments_start( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::operations::PaymentStart, req, @@ -276,7 +276,7 @@ pub async fn payments_retrieve( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentStatus, req, @@ -350,7 +350,7 @@ pub async fn payments_retrieve_with_gateway_creds( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentStatus, req, @@ -558,7 +558,7 @@ pub async fn payments_capture( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentCapture, payload, @@ -628,7 +628,7 @@ pub async fn payments_connector_session( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentSession, payload, @@ -861,7 +861,7 @@ pub async fn payments_complete_authorize( state.clone(), req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::operations::payment_complete_authorize::CompleteAuthorize, payment_confirm_req.clone(), @@ -921,7 +921,7 @@ pub async fn payments_cancel( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentCancel, req, @@ -1088,7 +1088,7 @@ pub async fn payments_approve( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentApprove, payment_types::PaymentsCaptureRequest { @@ -1143,7 +1143,7 @@ pub async fn payments_reject( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentReject, payment_types::PaymentsCancelRequest { @@ -1295,7 +1295,7 @@ pub async fn payments_incremental_authorization( state, req_state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, payments::PaymentIncrementalAuthorization, req, diff --git a/crates/router/src/routes/payouts.rs b/crates/router/src/routes/payouts.rs index 18ba815551..02e67e66c8 100644 --- a/crates/router/src/routes/payouts.rs +++ b/crates/router/src/routes/payouts.rs @@ -80,7 +80,13 @@ pub async fn payouts_retrieve( &req, payout_retrieve_request, |state, auth, req, _| { - payouts_retrieve_core(state, auth.merchant_account, None, auth.key_store, req) + payouts_retrieve_core( + state, + auth.merchant_account, + auth.profile_id, + auth.key_store, + req, + ) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), diff --git a/crates/router/src/routes/refunds.rs b/crates/router/src/routes/refunds.rs index e0b1e0786f..2a0d619e38 100644 --- a/crates/router/src/routes/refunds.rs +++ b/crates/router/src/routes/refunds.rs @@ -37,7 +37,13 @@ pub async fn refunds_create( &req, json_payload.into_inner(), |state, auth, req, _| { - refund_create_core(state, auth.merchant_account, None, auth.key_store, req) + refund_create_core( + state, + auth.merchant_account, + auth.profile_id, + auth.key_store, + req, + ) }, auth::auth_type( &auth::HeaderAuth(auth::ApiKeyAuth), @@ -94,7 +100,7 @@ pub async fn refunds_retrieve( refund_response_wrapper( state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, refund_request, refund_retrieve_core, @@ -146,7 +152,7 @@ pub async fn refunds_retrieve_with_body( refund_response_wrapper( state, auth.merchant_account, - None, + auth.profile_id, auth.key_store, req, refund_retrieve_core, diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index 0b2066fdb1..a82306fd13 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -57,7 +57,7 @@ pub struct AuthenticationData { pub profile_id: Option, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct AuthenticationDataWithMultipleProfiles { pub merchant_account: domain::MerchantAccount, pub key_store: domain::MerchantKeyStore, @@ -251,6 +251,12 @@ impl AuthInfo for AuthenticationData { } } +impl AuthInfo for AuthenticationDataWithMultipleProfiles { + fn get_merchant_id(&self) -> Option<&id_type::MerchantId> { + Some(self.merchant_account.get_id()) + } +} + #[async_trait] pub trait AuthenticateAndFetch where @@ -968,6 +974,65 @@ where } } +#[async_trait] +impl AuthenticateAndFetch for JWTAuthMerchantFromRoute +where + A: SessionStateInfo + Sync, +{ + async fn authenticate_and_fetch( + &self, + request_headers: &HeaderMap, + state: &A, + ) -> RouterResult<(AuthenticationData, AuthenticationType)> { + let payload = parse_jwt_payload::(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 permissions = authorization::get_permissions(state, &payload).await?; + authorization::check_authorization(&self.required_permission, &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 + .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 = AuthenticationData { + merchant_account: merchant, + key_store, + profile_id: payload.profile_id, + }; + Ok(( + auth.clone(), + AuthenticationType::MerchantJwt { + merchant_id: auth.merchant_account.get_id().clone(), + user_id: Some(payload.user_id), + }, + )) + } +} + pub struct JWTAuthMerchantOrProfileFromRoute { pub merchant_id_or_profile_id: String, pub required_permission: Permission, @@ -1074,7 +1139,7 @@ where &state.store().get_master_key().to_vec().into(), ) .await - .change_context(errors::ApiErrorResponse::InvalidJwtToken) + .to_not_found_response(errors::ApiErrorResponse::InvalidJwtToken) .attach_printable("Failed to fetch merchant key store for the merchant id")?; let merchant = state @@ -1085,7 +1150,8 @@ where &key_store, ) .await - .change_context(errors::ApiErrorResponse::InvalidJwtToken)?; + .to_not_found_response(errors::ApiErrorResponse::InvalidJwtToken) + .attach_printable("Failed to fetch merchant account for the merchant id")?; let auth = AuthenticationData { merchant_account: merchant, @@ -1096,7 +1162,7 @@ where auth.clone(), AuthenticationType::MerchantJwt { merchant_id: auth.merchant_account.get_id().clone(), - user_id: None, + user_id: Some(payload.user_id), }, )) }