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 { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; casbin_service .remove_policy(&role_name, &resource, &action) .await?; Ok(true) } #[graphql(guard = "RequireWritePermission::new(\"permissions\")")] async fn reload_policies(&self, ctx: &Context<'_>) -> Result { let casbin_service = ctx.data::()?; casbin_service.reload_policy().await?; Ok(true) } // 角色管理 Mutations #[graphql(guard = "RequireWritePermission::new(\"permissions\")")] async fn create_role( &self, ctx: &Context<'_>, input: CreateRoleInput, ) -> Result { let casbin_service = ctx.data::()?; // 调用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 { let _casbin_service = ctx.data::()?; 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 { let _casbin_service = ctx.data::()?; info!("Role deleted: {}", id); Ok(true) } #[graphql(guard = "RequireWritePermission::new(\"permissions\")")] async fn delete_role_by_name(&self, ctx: &Context<'_>, role_name: String) -> Result { let casbin_service = ctx.data::()?; // 调用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 { let _casbin_service = ctx.data::()?; 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 { let _casbin_service = ctx.data::()?; 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 { let _casbin_service = ctx.data::()?; 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, ) -> Result { let casbin_service = ctx.data::()?; let all_roles = casbin_service.get_all_roles().await?; let role_names: Vec = 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 { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; 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, ) -> Result { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; 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 { let casbin_service = ctx.data::()?; 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), }), } } }