Skip to content

Commit

Permalink
feat(users): Create config for TOTP Issuer (#4776)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisIsMani authored Jun 3, 2024
1 parent 15d6c3e commit 0cbb292
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 8 deletions.
5 changes: 3 additions & 2 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,9 @@ email_role_arn = "" # The amazon resource name ( arn ) of the role which
sts_role_session_name = "" # An identifier for the assumed role session, used to uniquely identify a session.

[user]
password_validity_in_days = 90 # Number of days after which password should be updated
two_factor_auth_expiry_in_secs = 300 # Number of seconds after which 2FA should be done again if doing update/change from inside
password_validity_in_days = 90 # Number of days after which password should be updated
two_factor_auth_expiry_in_secs = 300 # Number of seconds after which 2FA should be done again if doing update/change from inside
totp_issuer_name = "Hyperswitch" # Name of the issuer for TOTP

#tokenization configuration which describe token lifetime and payment method for specific connector
[tokenization]
Expand Down
1 change: 1 addition & 0 deletions config/deployments/integration_test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ slack_invite_url = "https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2aw
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Integ"

[frm]
enabled = true
Expand Down
1 change: 1 addition & 0 deletions config/deployments/production.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ slack_invite_url = "https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2aw
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Production"

[frm]
enabled = false
Expand Down
1 change: 1 addition & 0 deletions config/deployments/sandbox.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ slack_invite_url = "https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2aw
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Sandbox"

[frm]
enabled = true
Expand Down
1 change: 1 addition & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ sts_role_session_name = ""
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch Dev"

[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" }
Expand Down
1 change: 1 addition & 0 deletions config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ recon_admin_api_key = "recon_test_admin"
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch"

[locker]
host = ""
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/configs/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ pub struct Secrets {
pub struct UserSettings {
pub password_validity_in_days: u16,
pub two_factor_auth_expiry_in_secs: i64,
pub totp_issuer_name: String,
}

#[derive(Debug, Deserialize, Clone)]
Expand Down
4 changes: 3 additions & 1 deletion crates/router/src/consts/user.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
pub const MAX_NAME_LENGTH: usize = 70;
pub const MAX_COMPANY_NAME_LENGTH: usize = 70;
pub const BUSINESS_EMAIL: &str = "[email protected]";

pub const RECOVERY_CODES_COUNT: usize = 8;
pub const RECOVERY_CODE_LENGTH: usize = 8; // This is without counting the hyphen in between
pub const TOTP_ISSUER_NAME: &str = "Hyperswitch";

/// The number of digits composing the auth code.
pub const TOTP_DIGITS: usize = 6;
/// Duration in seconds of a step.
pub const TOTP_VALIDITY_DURATION_IN_SECONDS: u64 = 30;
/// Number of totps allowed as network delay. 1 would mean one totp before current totp and one totp after are valids.
pub const TOTP_TOLERANCE: u8 = 1;

pub const MAX_PASSWORD_LENGTH: usize = 70;
pub const MIN_PASSWORD_LENGTH: usize = 8;

Expand Down
25 changes: 21 additions & 4 deletions crates/router/src/core/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1635,7 +1635,11 @@ pub async fn begin_totp(
}));
}

let totp = tfa_utils::generate_default_totp(user_from_db.get_email(), None)?;
let totp = tfa_utils::generate_default_totp(
user_from_db.get_email(),
None,
state.conf.user.totp_issuer_name.clone(),
)?;
let secret = totp.get_secret_base32().into();
tfa_utils::insert_totp_secret_in_redis(&state, &user_token.user_id, &secret).await?;

Expand Down Expand Up @@ -1668,7 +1672,12 @@ pub async fn reset_totp(
return Err(UserErrors::TwoFactorAuthRequired.into());
}

let totp = tfa_utils::generate_default_totp(user_from_db.get_email(), None)?;
let totp = tfa_utils::generate_default_totp(
user_from_db.get_email(),
None,
state.conf.user.totp_issuer_name.clone(),
)?;

let secret = totp.get_secret_base32().into();
tfa_utils::insert_totp_secret_in_redis(&state, &user_token.user_id, &secret).await?;

Expand Down Expand Up @@ -1701,7 +1710,11 @@ pub async fn verify_totp(
.await?
.ok_or(UserErrors::InternalServerError)?;

let totp = tfa_utils::generate_default_totp(user_from_db.get_email(), Some(user_totp_secret))?;
let totp = tfa_utils::generate_default_totp(
user_from_db.get_email(),
Some(user_totp_secret),
state.conf.user.totp_issuer_name.clone(),
)?;

if totp
.generate_current()
Expand Down Expand Up @@ -1732,7 +1745,11 @@ pub async fn update_totp(
.await?
.ok_or(UserErrors::TotpSecretNotFound)?;

let totp = tfa_utils::generate_default_totp(user_from_db.get_email(), Some(new_totp_secret))?;
let totp = tfa_utils::generate_default_totp(
user_from_db.get_email(),
Some(new_totp_secret),
state.conf.user.totp_issuer_name.clone(),
)?;

if totp
.generate_current()
Expand Down
3 changes: 2 additions & 1 deletion crates/router/src/utils/user/two_factor_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
pub fn generate_default_totp(
email: pii::Email,
secret: Option<masking::Secret<String>>,
issuer: String,
) -> UserResult<TOTP> {
let secret = secret
.map(|sec| totp_rs::Secret::Encoded(sec.expose()))
Expand All @@ -25,7 +26,7 @@ pub fn generate_default_totp(
consts::user::TOTP_TOLERANCE,
consts::user::TOTP_VALIDITY_DURATION_IN_SECONDS,
secret,
Some(consts::user::TOTP_ISSUER_NAME.to_string()),
Some(issuer),
email.expose().expose(),
)
.change_context(UserErrors::InternalServerError)
Expand Down
1 change: 1 addition & 0 deletions loadtest/config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jwt_secret = "secret"
[user]
password_validity_in_days = 90
two_factor_auth_expiry_in_secs = 300
totp_issuer_name = "Hyperswitch"

[locker]
host = ""
Expand Down

0 comments on commit 0cbb292

Please sign in to comment.