diff --git a/crates/diesel_models/src/query/user_role.rs b/crates/diesel_models/src/query/user_role.rs index 2496d22447eb..ed018cc2381e 100644 --- a/crates/diesel_models/src/query/user_role.rs +++ b/crates/diesel_models/src/query/user_role.rs @@ -87,7 +87,7 @@ impl UserRole { user_id: String, org_id: id_type::OrganizationId, merchant_id: id_type::MerchantId, - profile_id: Option, + profile_id: id_type::ProfileId, version: UserRoleVersion, ) -> StorageResult { // Checking in user roles, for a user in token hierarchy, only one of the relation will be true, either org level, merchant level or profile level @@ -103,7 +103,6 @@ impl UserRole { .or(dsl::org_id.eq(org_id).and( dsl::merchant_id .eq(merchant_id) - //TODO: In case of None, profile_id = NULL its unexpected behaviour, after V1 profile id will not be option .and(dsl::profile_id.eq(profile_id)), )); @@ -137,7 +136,6 @@ impl UserRole { .or(dsl::org_id.eq(org_id).and( dsl::merchant_id .eq(merchant_id) - //TODO: In case of None, profile_id = NULL its unexpected behaviour, after V1 profile id will not be option .and(dsl::profile_id.eq(profile_id)), )); @@ -160,7 +158,7 @@ impl UserRole { user_id: String, org_id: id_type::OrganizationId, merchant_id: id_type::MerchantId, - profile_id: Option, + profile_id: id_type::ProfileId, version: UserRoleVersion, ) -> StorageResult { // Checking in user roles, for a user in token hierarchy, only one of the relation will be true, either org level, merchant level or profile level @@ -176,7 +174,6 @@ impl UserRole { .or(dsl::org_id.eq(org_id).and( dsl::merchant_id .eq(merchant_id) - //TODO: In case of None, profile_id = NULL its unexpected behaviour, after V1 profile id will not be option .and(dsl::profile_id.eq(profile_id)), )); diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index e0ae1c531a9f..bff6205f5db8 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -119,9 +119,7 @@ pub async fn get_user_details( org_id: user_from_token.org_id, is_two_factor_auth_setup: user.get_totp_status() == TotpStatus::Set, recovery_codes_left: user.get_recovery_codes().map(|codes| codes.len()), - profile_id: user_from_token - .profile_id - .ok_or(UserErrors::JwtProfileIdMissing)?, + profile_id: user_from_token.profile_id, entity_type: role_info.get_entity_type(), }, )) @@ -603,7 +601,7 @@ async fn handle_existing_user_invitation( invitee_user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V1, ) .await @@ -619,7 +617,7 @@ async fn handle_existing_user_invitation( invitee_user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V2, ) .await @@ -673,10 +671,6 @@ async fn handle_existing_user_invitation( .await? } EntityType::Profile => { - let profile_id = user_from_token - .profile_id - .clone() - .ok_or(UserErrors::InternalServerError)?; user_role .add_entity(domain::ProfileLevel { tenant_id: user_from_token @@ -685,7 +679,7 @@ async fn handle_existing_user_invitation( .unwrap_or(state.tenant.tenant_id.clone()), org_id: user_from_token.org_id.clone(), merchant_id: user_from_token.merchant_id.clone(), - profile_id: profile_id.clone(), + profile_id: user_from_token.profile_id.clone(), }) .insert_in_v2(state) .await? @@ -705,16 +699,10 @@ async fn handle_existing_user_invitation( entity_id: user_from_token.merchant_id.get_string_repr().to_owned(), entity_type: EntityType::Merchant, }, - EntityType::Profile => { - let profile_id = user_from_token - .profile_id - .clone() - .ok_or(UserErrors::InternalServerError)?; - email_types::Entity { - entity_id: profile_id.get_string_repr().to_owned(), - entity_type: EntityType::Profile, - } - } + EntityType::Profile => email_types::Entity { + entity_id: user_from_token.profile_id.get_string_repr().to_owned(), + entity_type: EntityType::Profile, + }, }; let email_contents = email_types::InviteUser { @@ -812,10 +800,6 @@ async fn handle_new_user_invitation( .await? } EntityType::Profile => { - let profile_id = user_from_token - .profile_id - .clone() - .ok_or(UserErrors::InternalServerError)?; user_role .add_entity(domain::ProfileLevel { tenant_id: user_from_token @@ -824,7 +808,7 @@ async fn handle_new_user_invitation( .unwrap_or(state.tenant.tenant_id.clone()), org_id: user_from_token.org_id.clone(), merchant_id: user_from_token.merchant_id.clone(), - profile_id: profile_id.clone(), + profile_id: user_from_token.profile_id.clone(), }) .insert_in_v2(state) .await? @@ -848,16 +832,10 @@ async fn handle_new_user_invitation( entity_id: user_from_token.merchant_id.get_string_repr().to_owned(), entity_type: EntityType::Merchant, }, - EntityType::Profile => { - let profile_id = user_from_token - .profile_id - .clone() - .ok_or(UserErrors::InternalServerError)?; - email_types::Entity { - entity_id: profile_id.get_string_repr().to_owned(), - entity_type: EntityType::Profile, - } - } + EntityType::Profile => email_types::Entity { + entity_id: user_from_token.profile_id.get_string_repr().to_owned(), + entity_type: EntityType::Profile, + }, }; let email_contents = email_types::InviteUser { @@ -887,7 +865,7 @@ async fn handle_new_user_invitation( merchant_id: user_from_token.merchant_id.clone(), org_id: user_from_token.org_id.clone(), role_id: request.role_id.clone(), - profile_id: None, + profile_id: user_from_token.profile_id.clone(), tenant_id: user_from_token.tenant_id.clone(), }; @@ -939,7 +917,7 @@ pub async fn resend_invite( user.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V2, ) .await @@ -962,7 +940,7 @@ pub async fn resend_invite( user.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V1, ) .await @@ -1235,10 +1213,7 @@ pub async fn list_user_roles_details( merchant_id: (requestor_role_info.get_entity_type() <= EntityType::Merchant) .then_some(&user_from_token.merchant_id), profile_id: (requestor_role_info.get_entity_type() <= EntityType::Profile) - .then_some(&user_from_token.profile_id) - .cloned() - .flatten() - .as_ref(), + .then_some(&user_from_token.profile_id), entity_id: None, version: None, status: None, @@ -2865,7 +2840,7 @@ pub async fn switch_profile_for_user_in_org_and_merchant( request: user_api::SwitchProfileRequest, user_from_token: auth::UserFromToken, ) -> UserResponse { - if user_from_token.profile_id == Some(request.profile_id.clone()) { + if user_from_token.profile_id == request.profile_id { return Err(UserErrors::InvalidRoleOperationWithMessage( "User switching to same profile".to_string(), ) diff --git a/crates/router/src/core/user_role.rs b/crates/router/src/core/user_role.rs index 95a8b7d51d1d..6641e553fd80 100644 --- a/crates/router/src/core/user_role.rs +++ b/crates/router/src/core/user_role.rs @@ -161,7 +161,7 @@ pub async fn update_user_role( user_to_be_updated.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V2, ) .await @@ -215,7 +215,7 @@ pub async fn update_user_role( user_to_be_updated.get_user_id(), &user_from_token.org_id, Some(&user_from_token.merchant_id), - user_from_token.profile_id.as_ref(), + Some(&user_from_token.profile_id), UserRoleUpdate::UpdateRole { role_id: req.role_id.clone(), modified_by: user_from_token.user_id.clone(), @@ -234,7 +234,7 @@ pub async fn update_user_role( user_to_be_updated.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V1, ) .await @@ -288,7 +288,7 @@ pub async fn update_user_role( user_to_be_updated.get_user_id(), &user_from_token.org_id, Some(&user_from_token.merchant_id), - user_from_token.profile_id.as_ref(), + Some(&user_from_token.profile_id), UserRoleUpdate::UpdateRole { role_id: req.role_id.clone(), modified_by: user_from_token.user_id, @@ -475,7 +475,7 @@ pub async fn delete_user_role( user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V2, ) .await @@ -522,7 +522,7 @@ pub async fn delete_user_role( user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V2, ) .await @@ -537,7 +537,7 @@ pub async fn delete_user_role( user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V1, ) .await @@ -584,7 +584,7 @@ pub async fn delete_user_role( user_from_db.get_user_id(), &user_from_token.org_id, &user_from_token.merchant_id, - user_from_token.profile_id.as_ref(), + &user_from_token.profile_id, UserRoleVersion::V1, ) .await @@ -676,17 +676,13 @@ pub async fn list_users_in_lineage( .await? } EntityType::Profile => { - let Some(profile_id) = user_from_token.profile_id.as_ref() else { - return Err(UserErrors::JwtProfileIdMissing.into()); - }; - utils::user_role::fetch_user_roles_by_payload( &state, ListUserRolesByOrgIdPayload { user_id: None, org_id: &user_from_token.org_id, merchant_id: Some(&user_from_token.merchant_id), - profile_id: Some(profile_id), + profile_id: Some(&user_from_token.profile_id), version: None, limit: None, }, diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index d7d283819e5f..93181c66142f 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -3030,7 +3030,7 @@ impl UserRoleInterface for KafkaStore { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { self.diesel_store @@ -3070,7 +3070,7 @@ impl UserRoleInterface for KafkaStore { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { self.diesel_store diff --git a/crates/router/src/db/user_role.rs b/crates/router/src/db/user_role.rs index 2d9a949879aa..e4e564dc9a40 100644 --- a/crates/router/src/db/user_role.rs +++ b/crates/router/src/db/user_role.rs @@ -45,7 +45,7 @@ pub trait UserRoleInterface { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult; @@ -64,7 +64,7 @@ pub trait UserRoleInterface { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult; @@ -100,7 +100,7 @@ impl UserRoleInterface for Store { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { let conn = connection::pg_connection_read(self).await?; @@ -109,7 +109,7 @@ impl UserRoleInterface for Store { user_id.to_owned(), org_id.to_owned(), merchant_id.to_owned(), - profile_id.cloned(), + profile_id.to_owned(), version, ) .await @@ -146,7 +146,7 @@ impl UserRoleInterface for Store { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; @@ -155,7 +155,7 @@ impl UserRoleInterface for Store { user_id.to_owned(), org_id.to_owned(), merchant_id.to_owned(), - profile_id.cloned(), + profile_id.to_owned(), version, ) .await @@ -245,7 +245,7 @@ impl UserRoleInterface for MockDb { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { let user_roles = self.user_roles.lock().await; @@ -261,7 +261,7 @@ impl UserRoleInterface for MockDb { let profile_level_check = user_role.org_id.as_ref() == Some(org_id) && user_role.merchant_id.as_ref() == Some(merchant_id) - && user_role.profile_id.as_ref() == profile_id; + && user_role.profile_id.as_ref() == Some(profile_id); // Check if any condition matches and the version matches if user_role.user_id == user_id @@ -338,7 +338,7 @@ impl UserRoleInterface for MockDb { user_id: &str, org_id: &id_type::OrganizationId, merchant_id: &id_type::MerchantId, - profile_id: Option<&id_type::ProfileId>, + profile_id: &id_type::ProfileId, version: enums::UserRoleVersion, ) -> CustomResult { let mut user_roles = self.user_roles.lock().await; @@ -355,7 +355,7 @@ impl UserRoleInterface for MockDb { let profile_level_check = role.org_id.as_ref() == Some(org_id) && role.merchant_id.as_ref() == Some(merchant_id) - && role.profile_id.as_ref() == profile_id; + && role.profile_id.as_ref() == Some(profile_id); // Check if the user role matches the conditions and the version matches role.user_id == user_id diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index 43f04487416a..d4ac3bc846dd 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -87,7 +87,7 @@ pub struct AuthenticationDataWithUser { pub merchant_account: domain::MerchantAccount, pub key_store: domain::MerchantKeyStore, pub user: storage::User, - pub profile_id: Option, + pub profile_id: id_type::ProfileId, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -231,7 +231,7 @@ pub struct AuthToken { pub role_id: String, pub exp: u64, pub org_id: id_type::OrganizationId, - pub profile_id: Option, + pub profile_id: id_type::ProfileId, pub tenant_id: Option, } @@ -243,7 +243,7 @@ impl AuthToken { role_id: String, settings: &Settings, org_id: id_type::OrganizationId, - profile_id: Option, + profile_id: id_type::ProfileId, tenant_id: Option, ) -> UserResult { let exp_duration = std::time::Duration::from_secs(consts::JWT_TOKEN_TIME_IN_SECS); @@ -267,7 +267,7 @@ pub struct UserFromToken { pub merchant_id: id_type::MerchantId, pub role_id: String, pub org_id: id_type::OrganizationId, - pub profile_id: Option, + pub profile_id: id_type::ProfileId, pub tenant_id: Option, } @@ -1829,7 +1829,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( @@ -2077,7 +2077,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( auth.clone(), @@ -2253,11 +2253,7 @@ where return Err(report!(errors::ApiErrorResponse::InvalidJwtToken)); } - if payload - .profile_id - .as_ref() - .is_some_and(|profile_id| *profile_id != self.profile_id) - { + if payload.profile_id != self.profile_id { return Err(report!(errors::ApiErrorResponse::InvalidJwtToken)); } @@ -2290,7 +2286,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( auth.clone(), @@ -2354,30 +2350,14 @@ where .to_not_found_response(errors::ApiErrorResponse::InvalidJwtToken) .attach_printable("Failed to fetch merchant account for the merchant id")?; - if let Some(ref payload_profile_id) = payload.profile_id { - if *payload_profile_id != self.profile_id { - return Err(report!(errors::ApiErrorResponse::InvalidJwtToken)); - } else { - // if both of them are same then proceed with the profile id present in the request - let auth = AuthenticationData { - merchant_account: merchant, - key_store, - profile_id: Some(self.profile_id.clone()), - }; - Ok(( - auth.clone(), - AuthenticationType::MerchantJwt { - merchant_id: auth.merchant_account.get_id().clone(), - user_id: Some(payload.user_id), - }, - )) - } + if payload.profile_id != self.profile_id { + return Err(report!(errors::ApiErrorResponse::InvalidJwtToken)); } else { - // if profile_id is not present in the auth_layer itself then no change in behaviour + // if both of them are same then proceed with the profile id present in the request let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(self.profile_id.clone()), }; Ok(( auth.clone(), @@ -2527,7 +2507,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( auth, @@ -2663,7 +2643,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( (auth.clone(), payload.user_id.clone()), @@ -2781,7 +2761,7 @@ where let auth = AuthenticationData { merchant_account: merchant, key_store, - profile_id: payload.profile_id, + profile_id: Some(payload.profile_id), }; Ok(( auth.clone(), diff --git a/crates/router/src/types/domain/user/decision_manager.rs b/crates/router/src/types/domain/user/decision_manager.rs index 86f10f1ceb78..634c781da7fc 100644 --- a/crates/router/src/types/domain/user/decision_manager.rs +++ b/crates/router/src/types/domain/user/decision_manager.rs @@ -132,7 +132,7 @@ impl JWTFlow { .clone() .ok_or(report!(UserErrors::InternalServerError)) .attach_printable("org_id not found")?, - Some(profile_id), + profile_id, Some(user_role.tenant_id.clone()), ) .await diff --git a/crates/router/src/utils/user.rs b/crates/router/src/utils/user.rs index c4647907ff9b..8a9daefb2872 100644 --- a/crates/router/src/utils/user.rs +++ b/crates/router/src/utils/user.rs @@ -100,7 +100,7 @@ pub async fn generate_jwt_auth_token_with_attributes( role_id, &state.conf, org_id, - Some(profile_id), + profile_id, tenant_id, ) .await?;