refactor: Update permissions handling to filter out None values and ensure safe access
This commit is contained in:
@@ -27,7 +27,7 @@ impl<'a> AuthRepository<'a> {
|
|||||||
let table = ResourceEnum::UsersCache.to_string();
|
let table = ResourceEnum::UsersCache.to_string();
|
||||||
let user_id = user.email.clone();
|
let user_id = user.email.clone();
|
||||||
let permissions: Vec<String> =
|
let permissions: Vec<String> =
|
||||||
user.role.permissions.as_ref().unwrap_or(&vec![]).iter().map(|p| p.name.clone()).collect();
|
user.role.permissions.as_ref().unwrap_or(&vec![]).iter().filter_map(|p| p.as_ref().and_then(|pp| pp.name.clone())).collect();
|
||||||
let user_cache = UserCacheSchema {
|
let user_cache = UserCacheSchema {
|
||||||
email: user_id.clone(),
|
email: user_id.clone(),
|
||||||
permissions,
|
permissions,
|
||||||
@@ -72,11 +72,11 @@ impl<'a> AuthRepository<'a> {
|
|||||||
.permissions
|
.permissions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|name| PermissionsQueryDto {
|
.map(|name| PermissionsQueryDto {
|
||||||
id: Thing::from((
|
id: Some(Thing::from((
|
||||||
"app_permissions".to_string(),
|
"app_permissions".to_string(),
|
||||||
surrealdb::sql::Id::rand(),
|
surrealdb::sql::Id::rand(),
|
||||||
)),
|
))),
|
||||||
name,
|
name: Some(name),
|
||||||
created_at: None,
|
created_at: None,
|
||||||
updated_at: None,
|
updated_at: None,
|
||||||
})
|
})
|
||||||
@@ -85,7 +85,7 @@ impl<'a> AuthRepository<'a> {
|
|||||||
let role_detail_query_dto = RolesDetailQueryDto {
|
let role_detail_query_dto = RolesDetailQueryDto {
|
||||||
id: Thing::from(("app_roles".to_string(), surrealdb::sql::Id::rand())),
|
id: Thing::from(("app_roles".to_string(), surrealdb::sql::Id::rand())),
|
||||||
name: "CachedRole".to_string(),
|
name: "CachedRole".to_string(),
|
||||||
permissions: Some(permissions_query_dto),
|
permissions: Some(permissions_query_dto.into_iter().map(Some).collect()),
|
||||||
is_deleted: false,
|
is_deleted: false,
|
||||||
created_at: None,
|
created_at: None,
|
||||||
updated_at: None,
|
updated_at: None,
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ pub struct PermissionsItemDto {
|
|||||||
impl PermissionsItemDto {
|
impl PermissionsItemDto {
|
||||||
pub fn from(dto: &PermissionsQueryDto) -> Self {
|
pub fn from(dto: &PermissionsQueryDto) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: dto.id.id.to_raw(),
|
id: dto.id.as_ref().map(|id| id.id.to_raw()).unwrap_or_default(),
|
||||||
name: dto.name.clone(),
|
name: dto.name.clone().unwrap_or_default(),
|
||||||
created_at: dto.created_at.clone(),
|
created_at: dto.created_at.clone(),
|
||||||
updated_at: dto.updated_at.clone(),
|
updated_at: dto.updated_at.clone(),
|
||||||
}
|
}
|
||||||
@@ -37,8 +37,8 @@ impl PermissionsItemDto {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct PermissionsQueryDto {
|
pub struct PermissionsQueryDto {
|
||||||
pub id: Thing,
|
pub id: Option<Thing>,
|
||||||
pub name: String,
|
pub name: Option<String>,
|
||||||
pub created_at: Option<String>,
|
pub created_at: Option<String>,
|
||||||
pub updated_at: Option<String>,
|
pub updated_at: Option<String>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub async fn permissions_guard(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check permissions from database
|
// Check permissions from database
|
||||||
let user_permissions: Vec<String> = user.role.permissions.as_ref().unwrap_or(&vec![]).iter().map(|p| p.name.clone()).collect();
|
let user_permissions: Vec<String> = user.role.permissions.as_ref().unwrap_or(&vec![]).iter().filter_map(|p| p.as_ref().and_then(|pp| pp.name.clone())).collect();
|
||||||
for required in &required_permissions {
|
for required in &required_permissions {
|
||||||
let required_str = required.to_string();
|
let required_str = required.to_string();
|
||||||
if !user_permissions.contains(&required_str) {
|
if !user_permissions.contains(&required_str) {
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ impl PermissionsSchema {
|
|||||||
|
|
||||||
pub fn from(dto: PermissionsQueryDto) -> Self {
|
pub fn from(dto: PermissionsQueryDto) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: dto.id,
|
id: dto.id.unwrap_or_else(|| make_thing_from_enum(ResourceEnum::Permissions, "unknown")),
|
||||||
name: dto.name,
|
name: dto.name.unwrap_or_default(),
|
||||||
is_deleted: false,
|
is_deleted: false,
|
||||||
created_at: dto.created_at,
|
created_at: dto.created_at,
|
||||||
updated_at: dto.updated_at,
|
updated_at: dto.updated_at,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ impl RolesDetailItemDto {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&vec![])
|
.unwrap_or(&vec![])
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter_map(|p| p.as_ref())
|
||||||
.map(PermissionsItemDto::from)
|
.map(PermissionsItemDto::from)
|
||||||
.collect(),
|
.collect(),
|
||||||
created_at: dto.created_at.clone(),
|
created_at: dto.created_at.clone(),
|
||||||
@@ -61,7 +62,7 @@ impl RolesDetailItemDto {
|
|||||||
pub struct RolesDetailQueryDto {
|
pub struct RolesDetailQueryDto {
|
||||||
pub id: Thing,
|
pub id: Thing,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub permissions: Option<Vec<PermissionsQueryDto>>,
|
pub permissions: Option<Vec<Option<PermissionsQueryDto>>>,
|
||||||
pub is_deleted: bool,
|
pub is_deleted: bool,
|
||||||
pub created_at: Option<String>,
|
pub created_at: Option<String>,
|
||||||
pub updated_at: Option<String>,
|
pub updated_at: Option<String>,
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ impl RolesSchema {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(&vec![])
|
.unwrap_or(&vec![])
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|perm| {
|
.filter_map(|perm| {
|
||||||
make_thing_from_enum(ResourceEnum::Permissions, &perm.id.id.to_raw())
|
perm.as_ref().and_then(|p| p.id.as_ref().map(|id| make_thing_from_enum(ResourceEnum::Permissions, &id.id.to_raw())))
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
is_deleted: dto.is_deleted,
|
is_deleted: dto.is_deleted,
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let user_permissions: Vec<String> =
|
let user_permissions: Vec<String> =
|
||||||
user.role.permissions.as_ref().unwrap_or(&vec![]).iter().map(|p| p.name.clone()).collect();
|
user.role.permissions.as_ref().unwrap_or(&vec![]).iter().filter_map(|p| p.as_ref().and_then(|pp| pp.name.clone())).collect();
|
||||||
|
|
||||||
// Check if user has Administrator permission - if yes, allow access to everything
|
// Check if user has Administrator permission - if yes, allow access to everything
|
||||||
let has_administrator_permission = user_permissions.contains(&PermissionsEnum::Administrator.to_string());
|
let has_administrator_permission = user_permissions.contains(&PermissionsEnum::Administrator.to_string());
|
||||||
|
|||||||
Reference in New Issue
Block a user