381 lines
12 KiB
Rust
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),
|
|
}),
|
|
}
|
|
}
|
|
}
|