refactor(authn): Enable cookies in Integ (#6599)

This commit is contained in:
Mani Chandra
2024-11-26 17:46:32 +05:30
committed by GitHub
parent 29a0885a8f
commit 02479a12b1
11 changed files with 71 additions and 12 deletions

View File

@ -403,6 +403,7 @@ two_factor_auth_expiry_in_secs = 300 # Number of seconds after which 2FA should
totp_issuer_name = "Hyperswitch" # Name of the issuer for TOTP totp_issuer_name = "Hyperswitch" # Name of the issuer for TOTP
base_url = "" # Base url used for user specific redirects and emails base_url = "" # Base url used for user specific redirects and emails
force_two_factor_auth = false # Whether to force two factor authentication for all users force_two_factor_auth = false # Whether to force two factor authentication for all users
force_cookies = true # Whether to use only cookies for JWT extraction and authentication
#tokenization configuration which describe token lifetime and payment method for specific connector #tokenization configuration which describe token lifetime and payment method for specific connector
[tokenization] [tokenization]

View File

@ -145,6 +145,7 @@ two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Integ" totp_issuer_name = "Hyperswitch Integ"
base_url = "https://integ.hyperswitch.io" base_url = "https://integ.hyperswitch.io"
force_two_factor_auth = false force_two_factor_auth = false
force_cookies = true
[frm] [frm]
enabled = true enabled = true

View File

@ -152,6 +152,7 @@ two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Production" totp_issuer_name = "Hyperswitch Production"
base_url = "https://live.hyperswitch.io" base_url = "https://live.hyperswitch.io"
force_two_factor_auth = true force_two_factor_auth = true
force_cookies = false
[frm] [frm]
enabled = false enabled = false

View File

@ -152,6 +152,7 @@ two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Sandbox" totp_issuer_name = "Hyperswitch Sandbox"
base_url = "https://app.hyperswitch.io" base_url = "https://app.hyperswitch.io"
force_two_factor_auth = false force_two_factor_auth = false
force_cookies = false
[frm] [frm]
enabled = true enabled = true

View File

@ -329,6 +329,7 @@ two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Dev" totp_issuer_name = "Hyperswitch Dev"
base_url = "http://localhost:8080" base_url = "http://localhost:8080"
force_two_factor_auth = false force_two_factor_auth = false
force_cookies = true
[bank_config.eps] [bank_config.eps]
stripe = { banks = "arzte_und_apotheker_bank,austrian_anadi_bank_ag,bank_austria,bankhaus_carl_spangler,bankhaus_schelhammer_und_schattera_ag,bawag_psk_ag,bks_bank_ag,brull_kallmus_bank_ag,btv_vier_lander_bank,capital_bank_grawe_gruppe_ag,dolomitenbank,easybank_ag,erste_bank_und_sparkassen,hypo_alpeadriabank_international_ag,hypo_noe_lb_fur_niederosterreich_u_wien,hypo_oberosterreich_salzburg_steiermark,hypo_tirol_bank_ag,hypo_vorarlberg_bank_ag,hypo_bank_burgenland_aktiengesellschaft,marchfelder_bank,oberbank_ag,raiffeisen_bankengruppe_osterreich,schoellerbank_ag,sparda_bank_wien,volksbank_gruppe,volkskreditbank_ag,vr_bank_braunau" } stripe = { banks = "arzte_und_apotheker_bank,austrian_anadi_bank_ag,bank_austria,bankhaus_carl_spangler,bankhaus_schelhammer_und_schattera_ag,bawag_psk_ag,bks_bank_ag,brull_kallmus_bank_ag,btv_vier_lander_bank,capital_bank_grawe_gruppe_ag,dolomitenbank,easybank_ag,erste_bank_und_sparkassen,hypo_alpeadriabank_international_ag,hypo_noe_lb_fur_niederosterreich_u_wien,hypo_oberosterreich_salzburg_steiermark,hypo_tirol_bank_ag,hypo_vorarlberg_bank_ag,hypo_bank_burgenland_aktiengesellschaft,marchfelder_bank,oberbank_ag,raiffeisen_bankengruppe_osterreich,schoellerbank_ag,sparda_bank_wien,volksbank_gruppe,volkskreditbank_ag,vr_bank_braunau" }

View File

@ -57,6 +57,7 @@ two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch" totp_issuer_name = "Hyperswitch"
base_url = "http://localhost:8080" base_url = "http://localhost:8080"
force_two_factor_auth = false force_two_factor_auth = false
force_cookies = true
[locker] [locker]
host = "" host = ""

View File

@ -557,6 +557,7 @@ pub struct UserSettings {
pub totp_issuer_name: String, pub totp_issuer_name: String,
pub base_url: String, pub base_url: String,
pub force_two_factor_auth: bool, pub force_two_factor_auth: bool,
pub force_cookies: bool,
} }
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]

View File

@ -294,7 +294,7 @@ pub async fn connect_account(
pub async fn signout( pub async fn signout(
state: SessionState, state: SessionState,
user_from_token: auth::UserFromToken, user_from_token: auth::UserIdFromAuth,
) -> UserResponse<()> { ) -> UserResponse<()> {
tfa_utils::delete_totp_from_redis(&state, &user_from_token.user_id).await?; tfa_utils::delete_totp_from_redis(&state, &user_from_token.user_id).await?;
tfa_utils::delete_recovery_code_from_redis(&state, &user_from_token.user_id).await?; tfa_utils::delete_recovery_code_from_redis(&state, &user_from_token.user_id).await?;

View File

@ -130,7 +130,7 @@ pub async fn signout(state: web::Data<AppState>, http_req: HttpRequest) -> HttpR
&http_req, &http_req,
(), (),
|state, user, _, _| user_core::signout(state, user), |state, user, _, _| user_core::signout(state, user),
&auth::DashboardNoPermissionAuth, &auth::AnyPurposeOrLoginTokenAuth,
api_locking::LockAction::NotApplicable, api_locking::LockAction::NotApplicable,
)) ))
.await .await

View File

@ -871,6 +871,47 @@ where
} }
} }
#[cfg(feature = "olap")]
#[derive(Debug)]
pub struct AnyPurposeOrLoginTokenAuth;
#[cfg(feature = "olap")]
#[async_trait]
impl<A> AuthenticateAndFetch<UserIdFromAuth, A> for AnyPurposeOrLoginTokenAuth
where
A: SessionStateInfo + Sync,
{
async fn authenticate_and_fetch(
&self,
request_headers: &HeaderMap,
state: &A,
) -> RouterResult<(UserIdFromAuth, AuthenticationType)> {
let payload =
parse_jwt_payload::<A, SinglePurposeOrLoginToken>(request_headers, state).await?;
if payload.check_in_blacklist(state).await? {
return Err(errors::ApiErrorResponse::InvalidJwtToken.into());
}
let purpose_exists = payload.purpose.is_some();
let role_id_exists = payload.role_id.is_some();
if purpose_exists ^ role_id_exists {
Ok((
UserIdFromAuth {
user_id: payload.user_id.clone(),
},
AuthenticationType::SinglePurposeOrLoginJwt {
user_id: payload.user_id,
purpose: payload.purpose,
role_id: payload.role_id,
},
))
} else {
Err(errors::ApiErrorResponse::InvalidJwtToken.into())
}
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct AdminApiAuth; pub struct AdminApiAuth;
@ -2504,17 +2545,27 @@ where
T: serde::de::DeserializeOwned, T: serde::de::DeserializeOwned,
A: SessionStateInfo + Sync, A: SessionStateInfo + Sync,
{ {
let token = match get_cookie_from_header(headers).and_then(cookies::parse_cookie) { let cookie_token_result = get_cookie_from_header(headers).and_then(cookies::parse_cookie);
Ok(cookies) => cookies, let auth_header_token_result = get_jwt_from_authorization_header(headers);
Err(error) => { let force_cookie = state.conf().user.force_cookies;
let token = get_jwt_from_authorization_header(headers);
if token.is_err() { logger::info!(
logger::error!(?error); user_agent = ?headers.get(headers::USER_AGENT),
} header_names = ?headers.keys().collect::<Vec<_>>(),
token?.to_owned() is_token_equal =
} auth_header_token_result.as_deref().ok() == cookie_token_result.as_deref().ok(),
cookie_error = ?cookie_token_result.as_ref().err(),
token_error = ?auth_header_token_result.as_ref().err(),
force_cookie,
);
let final_token = if force_cookie {
cookie_token_result?
} else {
auth_header_token_result?.to_owned()
}; };
decode_jwt(&token, state).await
decode_jwt(&final_token, state).await
} }
#[cfg(feature = "v1")] #[cfg(feature = "v1")]

View File

@ -36,6 +36,7 @@ password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300 two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch" totp_issuer_name = "Hyperswitch"
force_two_factor_auth = false force_two_factor_auth = false
force_cookies = true
[locker] [locker]
host = "" host = ""