Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/common_utils/src/access_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fmt::Display;
/// Create a key for fetching the access token from redis
pub fn create_access_token_key(
merchant_id: impl Display,
merchant_connector_id: impl Display,
merchant_connector_id_or_connector_name: impl Display,
) -> String {
format!("access_token_{merchant_id}_{merchant_connector_id}")
format!("access_token_{merchant_id}_{merchant_connector_id_or_connector_name}")
}
18 changes: 12 additions & 6 deletions crates/router/src/core/payments/access_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,20 @@ pub async fn add_access_token<
{
let merchant_id = &merchant_account.merchant_id;
let store = &*state.store;
let merchant_connector_id = connector

// `merchant_connector_id` may not be present in the below cases
// - when straight through routing is used without passing the `merchant_connector_id`
// - when creds identifier is passed
//
// In these cases fallback to `connector_name`.
// We cannot use multiple merchant connector account in these cases
let merchant_connector_id_or_connector_name = connector
.merchant_connector_id
.as_ref()
.ok_or(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Missing merchant_connector_id in ConnectorData")?;
.clone()
.unwrap_or(connector.connector_name.to_string());

let old_access_token = store
.get_access_token(merchant_id, merchant_connector_id)
.get_access_token(merchant_id, &merchant_connector_id_or_connector_name)
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("DB error when accessing the access token")?;
Expand Down Expand Up @@ -115,7 +121,7 @@ pub async fn add_access_token<
if let Err(access_token_set_error) = store
.set_access_token(
merchant_id,
merchant_connector_id.as_str(),
&merchant_connector_id_or_connector_name,
access_token.clone(),
)
.await
Expand Down
24 changes: 14 additions & 10 deletions crates/router/src/db/merchant_connector_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ pub trait ConnectorAccessToken {
async fn get_access_token(
&self,
merchant_id: &str,
merchant_connector_id: &str,
merchant_connector_id_or_connector_name: &str,
) -> CustomResult<Option<types::AccessToken>, errors::StorageError>;

async fn set_access_token(
&self,
merchant_id: &str,
merchant_connector_id: &str,
merchant_connector_id_or_connector_name: &str,
access_token: types::AccessToken,
) -> CustomResult<(), errors::StorageError>;
}
Expand All @@ -41,13 +41,15 @@ impl ConnectorAccessToken for Store {
async fn get_access_token(
&self,
merchant_id: &str,
merchant_connector_id: &str,
merchant_connector_id_or_connector_name: &str,
) -> CustomResult<Option<types::AccessToken>, errors::StorageError> {
//TODO: Handle race condition
// This function should acquire a global lock on some resource, if access token is already
// being refreshed by other request then wait till it finishes and use the same access token
let key =
common_utils::access_token::create_access_token_key(merchant_id, merchant_connector_id);
let key = common_utils::access_token::create_access_token_key(
merchant_id,
merchant_connector_id_or_connector_name,
);

let maybe_token = self
.get_redis_conn()
Expand All @@ -69,11 +71,13 @@ impl ConnectorAccessToken for Store {
async fn set_access_token(
&self,
merchant_id: &str,
merchant_connector_id: &str,
merchant_connector_id_or_connector_name: &str,
access_token: types::AccessToken,
) -> CustomResult<(), errors::StorageError> {
let key =
common_utils::access_token::create_access_token_key(merchant_id, merchant_connector_id);
let key = common_utils::access_token::create_access_token_key(
merchant_id,
merchant_connector_id_or_connector_name,
);
let serialized_access_token = access_token
.encode_to_string_of_json()
.change_context(errors::StorageError::SerializationFailed)?;
Expand All @@ -90,15 +94,15 @@ impl ConnectorAccessToken for MockDb {
async fn get_access_token(
&self,
_merchant_id: &str,
_merchant_connector_id: &str,
_merchant_connector_id_or_connector_name: &str,
) -> CustomResult<Option<types::AccessToken>, errors::StorageError> {
Ok(None)
}

async fn set_access_token(
&self,
_merchant_id: &str,
_merchant_connector_id: &str,
_merchant_connector_id_or_connector_name: &str,
_access_token: types::AccessToken,
) -> CustomResult<(), errors::StorageError> {
Ok(())
Expand Down