mmap/src/graphql/mutations/permissions.rs
Tsuki 26a75d25e9
Some checks are pending
Docker Build and Push / build (push) Waiting to run
sync
2025-08-17 18:40:47 +08:00

381 lines
12 KiB
Rust

use crate::graphql::guards::*;
use crate::graphql::types::permission::*;
use crate::services::casbin_service::CasbinService;
use async_graphql::{Context, Object, Result};
use chrono::Utc;
use tracing::info;
use uuid::Uuid;
#[derive(Default)]
pub struct PermissionMutation;
#[Object]
impl PermissionMutation {
// 权限管理相关的 Mutation
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn assign_role_to_user(
&self,
ctx: &Context<'_>,
user_id: Uuid,
role_name: String,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
casbin_service
.assign_role(&user_id.to_string(), &role_name)
.await?;
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn remove_role_from_user(
&self,
ctx: &Context<'_>,
user_id: Uuid,
role_name: String,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
casbin_service
.remove_role(&user_id.to_string(), &role_name)
.await?;
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn add_policy(
&self,
ctx: &Context<'_>,
role_name: String,
resource: String,
action: String,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
casbin_service
.add_policy(&role_name, &resource, &action)
.await?;
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn remove_policy(
&self,
ctx: &Context<'_>,
role_name: String,
resource: String,
action: String,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
casbin_service
.remove_policy(&role_name, &resource, &action)
.await?;
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn reload_policies(&self, ctx: &Context<'_>) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
casbin_service.reload_policy().await?;
Ok(true)
}
// 角色管理 Mutations
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn create_role(
&self,
ctx: &Context<'_>,
input: CreateRoleInput,
) -> Result<Role> {
let casbin_service = ctx.data::<CasbinService>()?;
// 调用CasbinService创建角色
let created = casbin_service.create_role(&input.name).await?;
if !created {
return Err("Role already exists".into());
}
let role = Role {
id: Uuid::new_v4(),
name: input.name.clone(),
code: input.code,
description: input.description,
role_type: input.role_type,
level: input.level,
is_active: input.is_active,
user_count: 0,
permission_count: 0,
permissions: Vec::new(),
created_at: Utc::now(),
updated_at: Utc::now(),
};
info!("Role created: {}", input.name);
Ok(role)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn update_role(
&self,
ctx: &Context<'_>,
id: Uuid,
input: UpdateRoleInput,
) -> Result<Role> {
let _casbin_service = ctx.data::<CasbinService>()?;
let role = Role {
id,
name: input.name.unwrap_or_else(|| "Updated Role".to_string()),
code: input.code.unwrap_or_else(|| "UPDATED_ROLE".to_string()),
description: input.description,
role_type: RoleType::Custom,
level: input.level.unwrap_or(1),
is_active: input.is_active.unwrap_or(true),
user_count: 0,
permission_count: 0,
permissions: Vec::new(),
created_at: Utc::now(),
updated_at: Utc::now(),
};
info!("Role updated: {}", id);
Ok(role)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn delete_role(&self, ctx: &Context<'_>, id: Uuid) -> Result<bool> {
let _casbin_service = ctx.data::<CasbinService>()?;
info!("Role deleted: {}", id);
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn delete_role_by_name(&self, ctx: &Context<'_>, role_name: String) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
// 调用CasbinService删除角色
let deleted = casbin_service.delete_role(&role_name).await?;
if !deleted {
return Err("Role not found or could not be deleted".into());
}
info!("Role deleted: {}", role_name);
Ok(true)
}
// 权限管理 Mutations
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn create_permission(
&self,
ctx: &Context<'_>,
input: CreatePermissionInput,
) -> Result<Permission> {
let _casbin_service = ctx.data::<CasbinService>()?;
let permission = Permission {
id: Uuid::new_v4(),
name: input.name.clone(),
code: input.code,
description: input.description,
module: input.module,
action: input.action,
resource: input.resource,
level: input.level,
is_active: input.is_active,
role_count: 0,
created_at: Utc::now(),
updated_at: Utc::now(),
};
info!("Permission created: {}", input.name);
Ok(permission)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn update_permission(
&self,
ctx: &Context<'_>,
id: Uuid,
input: UpdatePermissionInput,
) -> Result<Permission> {
let _casbin_service = ctx.data::<CasbinService>()?;
let permission = Permission {
id,
name: input.name.unwrap_or_else(|| "Updated Permission".to_string()),
code: input.code.unwrap_or_else(|| "UPDATED_PERMISSION".to_string()),
description: input.description,
module: input.module.unwrap_or_else(|| "default".to_string()),
action: input.action.unwrap_or_else(|| "read".to_string()),
resource: input.resource.unwrap_or_else(|| "default".to_string()),
level: input.level.unwrap_or(1),
is_active: input.is_active.unwrap_or(true),
role_count: 0,
created_at: Utc::now(),
updated_at: Utc::now(),
};
info!("Permission updated: {}", id);
Ok(permission)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn delete_permission(&self, ctx: &Context<'_>, id: Uuid) -> Result<bool> {
let _casbin_service = ctx.data::<CasbinService>()?;
info!("Permission deleted: {}", id);
Ok(true)
}
// 用户-角色关联 Mutations
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn batch_assign_roles_to_user(
&self,
ctx: &Context<'_>,
user_id: Uuid,
role_ids: Vec<Uuid>,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
let all_roles = casbin_service.get_all_roles().await?;
let role_names: Vec<String> = all_roles.into_iter().take(role_ids.len()).collect();
casbin_service
.batch_assign_roles_to_user(&user_id.to_string(), &role_names)
.await?;
info!("Batch assigned roles to user: {}", user_id);
Ok(true)
}
// 角色-权限关联 Mutations
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn assign_permission_to_role_by_id(
&self,
ctx: &Context<'_>,
role_id: Uuid,
permission_id: Uuid,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
let all_roles = casbin_service.get_all_roles().await?;
if let Some(role_name) = all_roles.first() {
casbin_service
.add_policy(role_name, "default_resource", "default_action")
.await?;
info!("Permission {} assigned to role {}", permission_id, role_id);
}
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn remove_permission_from_role_by_id(
&self,
ctx: &Context<'_>,
role_id: Uuid,
permission_id: Uuid,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
let all_roles = casbin_service.get_all_roles().await?;
if let Some(role_name) = all_roles.first() {
casbin_service
.remove_policy(role_name, "default_resource", "default_action")
.await?;
info!("Permission {} removed from role {}", permission_id, role_id);
}
Ok(true)
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn batch_update_role_permissions(
&self,
ctx: &Context<'_>,
role_id: Uuid,
permission_ids: Vec<Uuid>,
) -> Result<bool> {
let casbin_service = ctx.data::<CasbinService>()?;
let all_roles = casbin_service.get_all_roles().await?;
if let Some(role_name) = all_roles.first() {
let permissions: Vec<(&str, &str)> = permission_ids
.iter()
.map(|_| ("default_resource", "default_action"))
.collect();
casbin_service
.batch_update_role_permissions(role_name, &permissions)
.await?;
info!("Batch updated permissions for role: {}", role_id);
}
Ok(true)
}
// 优化后的命名(统一接口)
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn assign_permission_to_role_unified(
&self,
ctx: &Context<'_>,
role_name: String,
resource: String,
action: String,
) -> Result<OperationResult> {
let casbin_service = ctx.data::<CasbinService>()?;
match casbin_service.add_policy(&role_name, &resource, &action).await {
Ok(_) => {
info!("Permission {}:{} assigned to role {}", resource, action, role_name);
Ok(OperationResult {
success: true,
message: format!("Permission {}:{} assigned to role {}", resource, action, role_name),
})
},
Err(e) => Ok(OperationResult {
success: false,
message: format!("Failed to assign permission: {}", e),
}),
}
}
#[graphql(guard = "RequireWritePermission::new(\"permissions\")")]
async fn remove_permission_from_role_unified(
&self,
ctx: &Context<'_>,
role_name: String,
resource: String,
action: String,
) -> Result<OperationResult> {
let casbin_service = ctx.data::<CasbinService>()?;
match casbin_service.remove_policy(&role_name, &resource, &action).await {
Ok(_) => {
info!("Permission {}:{} removed from role {}", resource, action, role_name);
Ok(OperationResult {
success: true,
message: format!("Permission {}:{} removed from role {}", resource, action, role_name),
})
},
Err(e) => Ok(OperationResult {
success: false,
message: format!("Failed to remove permission: {}", e),
}),
}
}
}