-
Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(users): add support for profile user delete #5541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
0aee7a6
5aa44b5
a1fcd39
d4c670d
0a528e4
a70447a
00574de
e2c8f10
df3035a
91cb0d6
908ee8f
820b02d
977252e
a87358c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -342,68 +342,163 @@ pub async fn delete_user_role( | |
.attach_printable("User deleting himself"); | ||
} | ||
|
||
let user_roles = state | ||
let deletion_requestor_role_info = roles::RoleInfo::from_role_id( | ||
&state, | ||
&user_from_token.role_id, | ||
&user_from_token.merchant_id, | ||
&user_from_token.org_id, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError)?; | ||
|
||
let mut user_role_deleted_flag = false; | ||
|
||
// Find in V2 | ||
let user_role_v2 = match state | ||
.store | ||
.list_user_roles_by_user_id(user_from_db.get_user_id(), UserRoleVersion::V1) | ||
.find_user_role_by_user_id_and_lineage( | ||
user_from_db.get_user_id(), | ||
&user_from_token.org_id, | ||
&user_from_token.merchant_id, | ||
user_from_token.profile_id.as_ref(), | ||
UserRoleVersion::V2, | ||
) | ||
.await | ||
{ | ||
Ok(user_role) => Some(user_role), | ||
Err(e) => { | ||
if e.current_context().is_db_not_found() { | ||
None | ||
} else { | ||
return Err(UserErrors::InternalServerError.into()); | ||
} | ||
} | ||
}; | ||
|
||
if let Some(role_to_be_deleted) = user_role_v2 { | ||
let target_role_info = roles::RoleInfo::from_role_id( | ||
&state, | ||
&role_to_be_deleted.role_id, | ||
&user_from_token.merchant_id, | ||
&user_from_token.org_id, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError)?; | ||
|
||
for user_role in user_roles.iter() { | ||
let Some(merchant_id) = user_role.merchant_id.as_ref() else { | ||
return Err(report!(UserErrors::InternalServerError)) | ||
.attach_printable("merchant_id not found for user_role"); | ||
}; | ||
if !target_role_info.is_deletable() { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)).attach_printable(format!( | ||
"Invalid operation, role_id = {} is not deletable", | ||
role_to_be_deleted.role_id | ||
)); | ||
} | ||
|
||
if merchant_id == &user_from_token.merchant_id { | ||
let role_info = roles::RoleInfo::from_role_id( | ||
&state, | ||
&user_role.role_id, | ||
&user_from_token.merchant_id, | ||
if deletion_requestor_role_info.get_entity_type() < target_role_info.get_entity_type() { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)).attach_printable(format!( | ||
"Invalid operation, deletion requestor = {} cannot delete target = {}", | ||
deletion_requestor_role_info.get_entity_type(), | ||
target_role_info.get_entity_type() | ||
)); | ||
} | ||
|
||
user_role_deleted_flag = true; | ||
state | ||
.store | ||
.delete_user_role_by_user_id_and_lineage( | ||
user_from_db.get_user_id(), | ||
&user_from_token.org_id, | ||
&user_from_token.merchant_id, | ||
user_from_token.profile_id.as_ref(), | ||
UserRoleVersion::V2, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError)?; | ||
if !role_info.is_deletable() { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)) | ||
.attach_printable(format!("role_id = {} is not deletable", user_role.role_id)); | ||
.change_context(UserErrors::InternalServerError) | ||
.attach_printable("Error while deleting user role")?; | ||
} | ||
|
||
// Find in V1 | ||
let user_role_v1 = match state | ||
.store | ||
.find_user_role_by_user_id_and_lineage( | ||
user_from_db.get_user_id(), | ||
&user_from_token.org_id, | ||
&user_from_token.merchant_id, | ||
user_from_token.profile_id.as_ref(), | ||
UserRoleVersion::V1, | ||
) | ||
.await | ||
{ | ||
Ok(user_role) => Some(user_role), | ||
Err(e) => { | ||
if e.current_context().is_db_not_found() { | ||
None | ||
} else { | ||
return Err(UserErrors::InternalServerError.into()); | ||
} | ||
} else { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)) | ||
.attach_printable("User is not associated with the merchant"); | ||
} | ||
} | ||
}; | ||
|
||
if let Some(role_to_be_deleted) = user_role_v1 { | ||
let target_role_info = roles::RoleInfo::from_role_id( | ||
&state, | ||
&role_to_be_deleted.role_id, | ||
&user_from_token.merchant_id, | ||
&user_from_token.org_id, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError)?; | ||
|
||
let deleted_user_role = if user_roles.len() > 1 { | ||
if !target_role_info.is_deletable() { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)).attach_printable(format!( | ||
"Invalid operation, role_id = {} is not deletable", | ||
role_to_be_deleted.role_id | ||
)); | ||
} | ||
|
||
if deletion_requestor_role_info.get_entity_type() < target_role_info.get_entity_type() { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)).attach_printable(format!( | ||
"Invalid operation, deletion requestor = {} cannot delete target = {}", | ||
deletion_requestor_role_info.get_entity_type(), | ||
target_role_info.get_entity_type() | ||
)); | ||
} | ||
|
||
user_role_deleted_flag = true; | ||
state | ||
.store | ||
.delete_user_role_by_user_id_merchant_id( | ||
.delete_user_role_by_user_id_and_lineage( | ||
user_from_db.get_user_id(), | ||
&user_from_token.org_id, | ||
&user_from_token.merchant_id, | ||
user_from_token.profile_id.as_ref(), | ||
UserRoleVersion::V1, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError) | ||
.attach_printable("Error while deleting user role")? | ||
} else { | ||
.attach_printable("Error while deleting user role")?; | ||
} | ||
|
||
if !user_role_deleted_flag { | ||
return Err(report!(UserErrors::InvalidDeleteOperation)) | ||
.attach_printable("User is not associated with the merchant"); | ||
} | ||
|
||
// Check if user has any more role associations | ||
let user_roles = state | ||
.store | ||
.list_user_roles_by_user_id(user_from_db.get_user_id(), UserRoleVersion::V1) | ||
.await | ||
.change_context(UserErrors::InternalServerError)?; | ||
|
||
// If user has no more role associated with him then deleting user | ||
if user_roles.is_empty() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can check if v2 roles are also empty. |
||
state | ||
.global_store | ||
.delete_user_by_user_id(user_from_db.get_user_id()) | ||
.await | ||
.change_context(UserErrors::InternalServerError) | ||
.attach_printable("Error while deleting user entry")?; | ||
} | ||
|
||
state | ||
.store | ||
.delete_user_role_by_user_id_merchant_id( | ||
user_from_db.get_user_id(), | ||
&user_from_token.merchant_id, | ||
UserRoleVersion::V1, | ||
) | ||
.await | ||
.change_context(UserErrors::InternalServerError) | ||
.attach_printable("Error while deleting user role")? | ||
}; | ||
|
||
auth::blacklist::insert_user_in_blacklist(&state, &deleted_user_role.user_id).await?; | ||
auth::blacklist::insert_user_in_blacklist(&state, user_from_db.get_user_id()).await?; | ||
Ok(ApplicationResponse::StatusOk) | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2666,6 +2666,42 @@ impl UserRoleInterface for KafkaStore { | |||||
.await | ||||||
} | ||||||
|
||||||
async fn find_user_role_by_user_id_and_lineage( | ||||||
&self, | ||||||
user_id: &str, | ||||||
org_id: &id_type::OrganizationId, | ||||||
merchant_id: &id_type::MerchantId, | ||||||
profile_id: Option<&String>, | ||||||
version: enums::UserRoleVersion, | ||||||
) -> CustomResult<storage::UserRole, errors::StorageError> { | ||||||
self.find_user_role_by_user_id_and_lineage( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In kakfaStore if we can self.functions will causes stack_overflow. So avoid following that. |
||||||
user_id, | ||||||
org_id, | ||||||
merchant_id, | ||||||
profile_id, | ||||||
version, | ||||||
) | ||||||
.await | ||||||
} | ||||||
|
||||||
async fn delete_user_role_by_user_id_and_lineage( | ||||||
&self, | ||||||
user_id: &str, | ||||||
org_id: &id_type::OrganizationId, | ||||||
merchant_id: &id_type::MerchantId, | ||||||
profile_id: Option<&String>, | ||||||
version: enums::UserRoleVersion, | ||||||
) -> CustomResult<storage::UserRole, errors::StorageError> { | ||||||
self.delete_user_role_by_user_id_and_lineage( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In kakfaStore if we can self.functions will causes stack_overflow. So avoid following that. |
||||||
user_id, | ||||||
org_id, | ||||||
merchant_id, | ||||||
profile_id, | ||||||
version, | ||||||
) | ||||||
.await | ||||||
} | ||||||
|
||||||
async fn transfer_org_ownership_between_users( | ||||||
&self, | ||||||
from_user_id: &str, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
500
is not handled.