refactor: AppState trait for utility functions (#499)

This commit is contained in:
Sangamesh Kulkarni
2023-02-06 16:34:29 +05:30
committed by GitHub
parent a2921ff835
commit 9381a37f8f
17 changed files with 147 additions and 92 deletions

View File

@ -35,10 +35,11 @@ pub async fn customer_create(
_,
_,
_,
_,
types::CreateCustomerResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
create_cust_req,
|state, merchant_account, req| {
@ -66,10 +67,11 @@ pub async fn customer_retrieve(
_,
_,
_,
_,
types::CustomerRetrieveResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -106,10 +108,11 @@ pub async fn customer_update(
_,
_,
_,
_,
types::CustomerUpdateResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
cust_update_req,
|state, merchant_account, req| {
@ -137,10 +140,11 @@ pub async fn customer_delete(
_,
_,
_,
_,
types::CustomerDeleteResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
customers::delete_customer,
@ -164,10 +168,11 @@ pub async fn list_customer_payment_method_api(
_,
_,
_,
_,
types::CustomerPaymentMethodListResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
customer_id.as_ref(),
cards::list_customer_payment_method,

View File

@ -40,10 +40,11 @@ pub async fn payment_intents_create(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
create_payment_req,
|state, merchant_account, req| {
@ -87,10 +88,11 @@ pub async fn payment_intents_retrieve(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, payload| {
@ -145,10 +147,11 @@ pub async fn payment_intents_update(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -205,10 +208,11 @@ pub async fn payment_intents_confirm(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -254,10 +258,11 @@ pub async fn payment_intents_capture(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
capture_payload,
|state, merchant_account, payload| {
@ -308,10 +313,11 @@ pub async fn payment_intents_cancel(
_,
_,
_,
_,
types::StripePaymentIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -347,10 +353,11 @@ pub async fn payment_intent_list(
_,
_,
_,
_,
types::StripePaymentIntentListResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {

View File

@ -27,10 +27,11 @@ pub async fn refund_create(
_,
_,
_,
_,
types::StripeCreateRefundResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
create_refund_req,
refunds::refund_create_core,
@ -53,10 +54,11 @@ pub async fn refund_retrieve(
_,
_,
_,
_,
types::StripeCreateRefundResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
refund_id,
|state, merchant_account, refund_id| {
@ -90,10 +92,11 @@ pub async fn refund_update(
_,
_,
_,
_,
types::StripeCreateRefundResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
create_refund_update_req,
|state, merchant_account, req| {

View File

@ -37,10 +37,11 @@ pub async fn setup_intents_create(
_,
_,
_,
_,
types::StripeSetupIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
create_payment_req,
|state, merchant_account, req| {
@ -84,10 +85,11 @@ pub async fn setup_intents_retrieve(
_,
_,
_,
_,
types::StripeSetupIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, payload| {
@ -139,10 +141,11 @@ pub async fn setup_intents_update(
_,
_,
_,
_,
types::StripeSetupIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -195,10 +198,11 @@ pub async fn setup_intents_confirm(
_,
_,
_,
_,
types::StripeSetupIntentResponse,
errors::StripeErrorCode,
>(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {

View File

@ -7,25 +7,26 @@ use serde::Serialize;
use crate::{
core::errors::{self, RouterResult},
routes,
routes::app::AppStateInfo,
services::{api, authentication as auth, logger},
};
#[instrument(skip(request, payload, state, func, api_authentication))]
pub async fn compatibility_api_wrap<'a, 'b, U, T, Q, F, Fut, S, E>(
state: &'b routes::AppState,
pub async fn compatibility_api_wrap<'a, 'b, A, U, T, Q, F, Fut, S, E>(
state: &'b A,
request: &'a HttpRequest,
payload: T,
func: F,
api_authentication: &dyn auth::AuthenticateAndFetch<U>,
api_authentication: &dyn auth::AuthenticateAndFetch<U, A>,
) -> HttpResponse
where
F: Fn(&'b routes::AppState, U, T) -> Fut,
F: Fn(&'b A, U, T) -> Fut,
Fut: Future<Output = RouterResult<api::ApplicationResponse<Q>>>,
Q: Serialize + std::fmt::Debug + 'a,
S: From<Q> + Serialize,
E: From<errors::ApiErrorResponse> + Serialize + error_stack::Context + actix_web::ResponseError,
T: std::fmt::Debug,
A: AppStateInfo,
{
let resp = api::server_wrap_util(state, request, payload, func, api_authentication).await;
match resp {

View File

@ -30,7 +30,7 @@ pub async fn merchant_account_create(
json_payload: web::Json<admin::CreateMerchantAccount>,
) -> HttpResponse {
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, _, req| create_merchant_account(&*state.store, req),
@ -65,7 +65,7 @@ pub async fn retrieve_merchant_account(
})
.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, _, req| get_merchant_account(&*state.store, req),
@ -99,7 +99,7 @@ pub async fn update_merchant_account(
) -> HttpResponse {
let merchant_id = mid.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, _, req| merchant_account_update(&*state.store, &merchant_id, req),
@ -135,7 +135,7 @@ pub async fn delete_merchant_account(
})
.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, _, req| merchant_account_delete(&*state.store, req.merchant_id),
@ -168,7 +168,7 @@ pub async fn payment_connector_create(
) -> HttpResponse {
let merchant_id = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, _, req| create_payment_connector(&*state.store, req, &merchant_id),
@ -209,7 +209,7 @@ pub async fn payment_connector_retrieve(
})
.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, _, req| {
@ -246,7 +246,7 @@ pub async fn payment_connector_list(
) -> HttpResponse {
let merchant_id = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
merchant_id,
|state, _, merchant_id| list_payment_connectors(&*state.store, merchant_id),
@ -284,7 +284,7 @@ pub async fn payment_connector_update(
) -> HttpResponse {
let (merchant_id, merchant_connector_id) = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, _, req| {
@ -327,7 +327,7 @@ pub async fn payment_connector_delete(
})
.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, _, req| {

View File

@ -20,6 +20,24 @@ pub struct AppState {
pub conf: Settings,
}
pub trait AppStateInfo {
fn conf(&self) -> Settings;
fn flow_name(&self) -> String;
fn store(&self) -> Box<dyn StorageInterface>;
}
impl AppStateInfo for AppState {
fn conf(&self) -> Settings {
self.conf.to_owned()
}
fn flow_name(&self) -> String {
self.flow_name.to_owned()
}
fn store(&self) -> Box<dyn StorageInterface> {
self.store.to_owned()
}
}
impl AppState {
pub async fn with_storage(conf: Settings, storage_impl: StorageImpl) -> Self {
let testable = storage_impl == StorageImpl::PostgresqlTest;

View File

@ -17,7 +17,7 @@ pub async fn config_key_retrieve(
let key = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
&key,
|state, _, key| configs::read_config(&*state.store, key),
@ -38,7 +38,7 @@ pub async fn config_key_update(
payload.key = key;
api::server_wrap(
&state,
state.get_ref(),
&req,
&payload,
|state, _, payload| configs::update_config(&*state.store, payload),

View File

@ -30,7 +30,7 @@ pub async fn customers_create(
json_payload: web::Json<customers::CustomerRequest>,
) -> HttpResponse {
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, req| create_customer(&*state.store, merchant_account, req),
@ -72,7 +72,7 @@ pub async fn customers_retrieve(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| retrieve_customer(&*state.store, merchant_account, req),
@ -107,7 +107,7 @@ pub async fn customers_update(
let customer_id = path.into_inner();
json_payload.customer_id = customer_id;
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, req| update_customer(&*state.store, merchant_account, req),
@ -141,7 +141,14 @@ pub async fn customers_delete(
customer_id: path.into_inner(),
})
.into_inner();
api::server_wrap(&state, &req, payload, delete_customer, &auth::ApiKeyAuth).await
api::server_wrap(
state.get_ref(),
&req,
payload,
delete_customer,
&auth::ApiKeyAuth,
)
.await
}
#[instrument(skip_all, fields(flow = ?Flow::CustomersGetMandates))]
@ -155,7 +162,7 @@ pub async fn get_customer_mandates(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
customer_id,
|state, merchant_account, req| {

View File

@ -16,7 +16,7 @@ pub async fn ephemeral_key_create(
) -> HttpResponse {
let payload = json_payload.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -35,7 +35,7 @@ pub async fn ephemeral_key_delete(
) -> HttpResponse {
let payload = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, _, req| helpers::delete_ephemeral_key(&*state.store, req),

View File

@ -36,7 +36,7 @@ pub async fn get_mandate(
mandate_id: path.into_inner(),
};
api::server_wrap(
&state,
state.get_ref(),
&req,
mandate_id,
mandate::get_mandate,
@ -73,7 +73,7 @@ pub async fn revoke_mandate(
mandate_id: path.into_inner(),
};
api::server_wrap(
&state,
state.get_ref(),
&req,
mandate_id,
|state, merchant_account, req| {

View File

@ -30,7 +30,7 @@ pub async fn create_payment_method_api(
json_payload: web::Json<payment_methods::CreatePaymentMethod>,
) -> HttpResponse {
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, req| async move {
@ -79,7 +79,7 @@ pub async fn list_payment_method_api(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -130,7 +130,7 @@ pub async fn list_customer_payment_method_api(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, _| {
@ -170,7 +170,7 @@ pub async fn payment_method_retrieve_api(
.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, pm| cards::retrieve_payment_method(state, pm, merchant_account),
@ -207,7 +207,7 @@ pub async fn payment_method_update_api(
let payment_method_id = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, payload| {
@ -250,7 +250,7 @@ pub async fn payment_method_delete_api(
payment_method_id: payment_method_id.into_inner().0,
};
api::server_wrap(
&state,
state.get_ref(),
&req,
pm,
cards::delete_payment_method,

View File

@ -38,7 +38,7 @@ pub async fn payments_create(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -86,7 +86,7 @@ pub async fn payments_start(
attempt_id: attempt_id.clone(),
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -143,7 +143,7 @@ pub async fn payments_retrieve(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -203,7 +203,7 @@ pub async fn payments_update(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -263,7 +263,7 @@ pub async fn payments_confirm(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -312,7 +312,7 @@ pub async fn payments_capture(
};
api::server_wrap(
&state,
state.get_ref(),
&req,
capture_payload,
|state, merchant_account, payload| {
@ -354,7 +354,7 @@ pub async fn payments_connector_session(
let sessions_payload = json_payload.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
sessions_payload,
|state, merchant_account, payload| {
@ -413,7 +413,7 @@ pub async fn payments_redirect_response(
connector: Some(connector),
};
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -459,7 +459,7 @@ pub async fn payments_cancel(
payload.payment_id = payment_id;
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {
@ -512,7 +512,7 @@ pub async fn payments_list(
) -> impl Responder {
let payload = payload.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
payload,
|state, merchant_account, req| {

View File

@ -31,7 +31,7 @@ pub async fn refunds_create(
json_payload: web::Json<refunds::RefundRequest>,
) -> HttpResponse {
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
refund_create_core,
@ -67,7 +67,7 @@ pub async fn refunds_retrieve(
let refund_id = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
refund_id,
|state, merchant_account, refund_id| {
@ -106,7 +106,7 @@ pub async fn refunds_update(
) -> HttpResponse {
let refund_id = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
json_payload.into_inner(),
|state, merchant_account, req| {
@ -149,7 +149,7 @@ pub async fn refunds_list(
payload: web::Query<api_models::refunds::RefundListRequest>,
) -> HttpResponse {
api::server_wrap(
&state,
state.get_ref(),
&req,
payload.into_inner(),
|state, merchant_account, req| refund_list(&*state.store, merchant_account, req),

View File

@ -17,7 +17,7 @@ pub async fn receive_incoming_webhook(
let (merchant_id, connector_name) = path.into_inner();
api::server_wrap(
&state,
state.get_ref(),
&req,
body,
|state, merchant_account, body| {

View File

@ -25,7 +25,7 @@ use crate::{
},
db::StorageInterface,
logger,
routes::AppState,
routes::{app::AppStateInfo, AppState},
services::authentication as auth,
types::{
self, api,
@ -384,18 +384,19 @@ pub enum AuthFlow {
}
#[instrument(skip(request, payload, state, func, api_auth))]
pub async fn server_wrap_util<'a, 'b, U, T, Q, F, Fut>(
state: &'b AppState,
pub async fn server_wrap_util<'a, 'b, A, U, T, Q, F, Fut>(
state: &'b A,
request: &'a HttpRequest,
payload: T,
func: F,
api_auth: &dyn auth::AuthenticateAndFetch<U>,
api_auth: &dyn auth::AuthenticateAndFetch<U, A>,
) -> RouterResult<ApplicationResponse<Q>>
where
F: Fn(&'b AppState, U, T) -> Fut,
F: Fn(&'b A, U, T) -> Fut,
Fut: Future<Output = RouterResponse<Q>>,
Q: Serialize + Debug + 'a,
T: Debug,
A: AppStateInfo,
{
let auth_out = api_auth
.authenticate_and_fetch(request.headers(), state)
@ -407,18 +408,19 @@ where
skip(request, payload, state, func, api_auth),
fields(request_method, request_url_path)
)]
pub async fn server_wrap<'a, 'b, T, U, Q, F, Fut>(
state: &'b AppState,
pub async fn server_wrap<'a, 'b, A, T, U, Q, F, Fut>(
state: &'b A,
request: &'a HttpRequest,
payload: T,
func: F,
api_auth: &dyn auth::AuthenticateAndFetch<U>,
api_auth: &dyn auth::AuthenticateAndFetch<U, A>,
) -> HttpResponse
where
F: Fn(&'b AppState, U, T) -> Fut,
F: Fn(&'b A, U, T) -> Fut,
Fut: Future<Output = RouterResult<ApplicationResponse<Q>>>,
Q: Serialize + Debug + 'a,
T: Debug,
A: AppStateInfo,
{
let request_method = request.method().as_str();
let url_path = request.path();

View File

@ -7,18 +7,21 @@ use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use crate::{
core::errors::{self, RouterResult, StorageErrorExt},
db::StorageInterface,
routes::AppState,
routes::{app::AppStateInfo, AppState},
services::api,
types::storage,
utils::OptionExt,
};
#[async_trait]
pub trait AuthenticateAndFetch<T> {
pub trait AuthenticateAndFetch<T, A>
where
A: AppStateInfo,
{
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
state: &AppState,
state: &A,
) -> RouterResult<T>;
}
@ -26,7 +29,7 @@ pub trait AuthenticateAndFetch<T> {
pub struct ApiKeyAuth;
#[async_trait]
impl AuthenticateAndFetch<storage::MerchantAccount> for ApiKeyAuth {
impl AuthenticateAndFetch<storage::MerchantAccount, AppState> for ApiKeyAuth {
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
@ -47,7 +50,7 @@ impl AuthenticateAndFetch<storage::MerchantAccount> for ApiKeyAuth {
pub struct AdminApiAuth;
#[async_trait]
impl AuthenticateAndFetch<()> for AdminApiAuth {
impl AuthenticateAndFetch<(), AppState> for AdminApiAuth {
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
@ -67,7 +70,7 @@ impl AuthenticateAndFetch<()> for AdminApiAuth {
pub struct MerchantIdAuth(pub String);
#[async_trait]
impl AuthenticateAndFetch<storage::MerchantAccount> for MerchantIdAuth {
impl AuthenticateAndFetch<storage::MerchantAccount, AppState> for MerchantIdAuth {
async fn authenticate_and_fetch(
&self,
_request_headers: &HeaderMap,
@ -85,7 +88,7 @@ impl AuthenticateAndFetch<storage::MerchantAccount> for MerchantIdAuth {
pub struct PublishableKeyAuth;
#[async_trait]
impl AuthenticateAndFetch<storage::MerchantAccount> for PublishableKeyAuth {
impl AuthenticateAndFetch<storage::MerchantAccount, AppState> for PublishableKeyAuth {
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
@ -112,7 +115,7 @@ struct JwtAuthPayloadFetchUnit {
}
#[async_trait]
impl AuthenticateAndFetch<()> for JWTAuth {
impl AuthenticateAndFetch<(), AppState> for JWTAuth {
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
@ -130,7 +133,7 @@ struct JwtAuthPayloadFetchMerchantAccount {
}
#[async_trait]
impl AuthenticateAndFetch<storage::MerchantAccount> for JWTAuth {
impl AuthenticateAndFetch<storage::MerchantAccount, AppState> for JWTAuth {
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
@ -163,12 +166,12 @@ impl ClientSecretFetch for ListPaymentMethodRequest {
}
}
pub fn jwt_auth_or<'a, T>(
default_auth: &'a dyn AuthenticateAndFetch<T>,
pub fn jwt_auth_or<'a, T, A: AppStateInfo>(
default_auth: &'a dyn AuthenticateAndFetch<T, A>,
headers: &HeaderMap,
) -> Box<&'a dyn AuthenticateAndFetch<T>>
) -> Box<&'a dyn AuthenticateAndFetch<T, A>>
where
JWTAuth: AuthenticateAndFetch<T>,
JWTAuth: AuthenticateAndFetch<T, A>,
{
if is_jwt_auth(headers) {
return Box::new(&JWTAuth);
@ -179,7 +182,7 @@ where
pub fn get_auth_type_and_flow(
headers: &HeaderMap,
) -> RouterResult<(
Box<dyn AuthenticateAndFetch<storage::MerchantAccount>>,
Box<dyn AuthenticateAndFetch<storage::MerchantAccount, AppState>>,
api::AuthFlow,
)> {
let api_key = get_api_key(headers)?;
@ -190,13 +193,18 @@ pub fn get_auth_type_and_flow(
Ok((Box::new(ApiKeyAuth), api::AuthFlow::Merchant))
}
pub fn check_client_secret_and_get_auth(
pub fn check_client_secret_and_get_auth<T>(
headers: &HeaderMap,
payload: &impl ClientSecretFetch,
) -> RouterResult<(
Box<dyn AuthenticateAndFetch<storage::MerchantAccount>>,
Box<dyn AuthenticateAndFetch<storage::MerchantAccount, T>>,
api::AuthFlow,
)> {
)>
where
T: AppStateInfo,
ApiKeyAuth: AuthenticateAndFetch<storage::MerchantAccount, T>,
PublishableKeyAuth: AuthenticateAndFetch<storage::MerchantAccount, T>,
{
let api_key = get_api_key(headers)?;
if api_key.starts_with("pk_") {
@ -223,7 +231,7 @@ pub async fn is_ephemeral_auth(
headers: &HeaderMap,
db: &dyn StorageInterface,
customer_id: &str,
) -> RouterResult<Box<dyn AuthenticateAndFetch<storage::MerchantAccount>>> {
) -> RouterResult<Box<dyn AuthenticateAndFetch<storage::MerchantAccount, AppState>>> {
let api_key = get_api_key(headers)?;
if !api_key.starts_with("epk") {