mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat(users): Add redis in Begin and Verify TOTP and create a new API that updates TOTP (#4765)
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use api_models::user as user_api;
|
||||
use common_utils::errors::CustomResult;
|
||||
use diesel_models::{enums::UserStatus, user_role::UserRole};
|
||||
use error_stack::ResultExt;
|
||||
use redis_interface::RedisConnectionPool;
|
||||
|
||||
use crate::{
|
||||
core::errors::{StorageError, UserErrors, UserResult},
|
||||
@ -191,3 +192,11 @@ pub fn get_token_from_signin_response(resp: &user_api::SignInResponse) -> maskin
|
||||
user_api::SignInResponse::MerchantSelect(data) => data.token.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_redis_connection(state: &AppState) -> UserResult<Arc<RedisConnectionPool>> {
|
||||
state
|
||||
.store
|
||||
.get_redis_conn()
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to get redis connection")
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use common_utils::pii;
|
||||
use error_stack::ResultExt;
|
||||
use masking::ExposeInterface;
|
||||
use redis_interface::RedisConnectionPool;
|
||||
use masking::{ExposeInterface, PeekInterface};
|
||||
use totp_rs::{Algorithm, TOTP};
|
||||
|
||||
use crate::{
|
||||
@ -35,8 +32,8 @@ pub fn generate_default_totp(
|
||||
}
|
||||
|
||||
pub async fn check_totp_in_redis(state: &AppState, user_id: &str) -> UserResult<bool> {
|
||||
let redis_conn = get_redis_connection(state)?;
|
||||
let key = format!("{}{}", consts::user::TOTP_PREFIX, user_id);
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id);
|
||||
redis_conn
|
||||
.exists::<()>(&key)
|
||||
.await
|
||||
@ -44,7 +41,7 @@ pub async fn check_totp_in_redis(state: &AppState, user_id: &str) -> UserResult<
|
||||
}
|
||||
|
||||
pub async fn check_recovery_code_in_redis(state: &AppState, user_id: &str) -> UserResult<bool> {
|
||||
let redis_conn = get_redis_connection(state)?;
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
let key = format!("{}{}", consts::user::REDIS_RECOVERY_CODE_PREFIX, user_id);
|
||||
redis_conn
|
||||
.exists::<()>(&key)
|
||||
@ -52,16 +49,62 @@ pub async fn check_recovery_code_in_redis(state: &AppState, user_id: &str) -> Us
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
|
||||
fn get_redis_connection(state: &AppState) -> UserResult<Arc<RedisConnectionPool>> {
|
||||
state
|
||||
.store
|
||||
.get_redis_conn()
|
||||
pub async fn insert_totp_in_redis(state: &AppState, user_id: &str) -> UserResult<()> {
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id);
|
||||
redis_conn
|
||||
.set_key_with_expiry(
|
||||
key.as_str(),
|
||||
common_utils::date_time::now_unix_timestamp(),
|
||||
state.conf.user.two_factor_auth_expiry_in_secs,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.attach_printable("Failed to get redis connection")
|
||||
}
|
||||
|
||||
pub async fn insert_totp_secret_in_redis(
|
||||
state: &AppState,
|
||||
user_id: &str,
|
||||
secret: &masking::Secret<String>,
|
||||
) -> UserResult<()> {
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
redis_conn
|
||||
.set_key_with_expiry(
|
||||
&get_totp_secret_key(user_id),
|
||||
secret.peek(),
|
||||
consts::user::REDIS_TOTP_SECRET_TTL_IN_SECS,
|
||||
)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
}
|
||||
|
||||
pub async fn get_totp_secret_from_redis(
|
||||
state: &AppState,
|
||||
user_id: &str,
|
||||
) -> UserResult<Option<masking::Secret<String>>> {
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
redis_conn
|
||||
.get_key::<Option<String>>(&get_totp_secret_key(user_id))
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.map(|secret| secret.map(Into::into))
|
||||
}
|
||||
|
||||
pub async fn delete_totp_secret_from_redis(state: &AppState, user_id: &str) -> UserResult<()> {
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
redis_conn
|
||||
.delete_key(&get_totp_secret_key(user_id))
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn get_totp_secret_key(user_id: &str) -> String {
|
||||
format!("{}{}", consts::user::REDIS_TOTP_SECRET_PREFIX, user_id)
|
||||
}
|
||||
|
||||
pub async fn insert_recovery_code_in_redis(state: &AppState, user_id: &str) -> UserResult<()> {
|
||||
let redis_conn = get_redis_connection(state)?;
|
||||
let redis_conn = super::get_redis_connection(state)?;
|
||||
let key = format!("{}{}", consts::user::REDIS_RECOVERY_CODE_PREFIX, user_id);
|
||||
redis_conn
|
||||
.set_key_with_expiry(
|
||||
|
||||
Reference in New Issue
Block a user