AdoS8ConfigActionPermissionController.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using Admin.NET.Plugin.AiDOP.Const.S8;
  2. using Admin.NET.Plugin.AiDOP.Infrastructure;
  3. using Admin.NET.Plugin.AiDOP.Infrastructure.S8;
  4. using Admin.NET.Plugin.AiDOP.Service.S8;
  5. using Microsoft.AspNetCore.Mvc;
  6. namespace Admin.NET.Plugin.AiDOP.Controllers.S8;
  7. /// <summary>
  8. /// S8-ACTION-PERMISSION-1:「异常操作权限」配置。
  9. ///
  10. /// <para>这是 <b>S8 全局</b>配置,<b>不属于某一条规则</b> —— 它回答的是
  11. /// 「哪些角色能对异常单做哪些动作」,与「这条规则由谁负责」(Rule Handler Pool)
  12. /// 是两个正交问题。刻意不放进规则弹窗:混在一起会让管理员以为改的是这条规则的权限,
  13. /// 实际改的是全租户。</para>
  14. /// </summary>
  15. [ApiController]
  16. [Route("api/aidop/s8/config/action-permissions")]
  17. [NonUnify]
  18. public class AdoS8ConfigActionPermissionController : ControllerBase
  19. {
  20. private readonly S8ExceptionActionRoleService _svc;
  21. private readonly S8TrustedScopeResolver _scope;
  22. private readonly IS8ExceptionActionAuthorizer _authorizer;
  23. public AdoS8ConfigActionPermissionController(
  24. S8ExceptionActionRoleService svc,
  25. S8TrustedScopeResolver scope,
  26. IS8ExceptionActionAuthorizer authorizer)
  27. {
  28. _svc = svc;
  29. _scope = scope;
  30. _authorizer = authorizer;
  31. }
  32. /// <summary>权限矩阵(目录内每个动作一行,未配置的也返回,前端要能显示"未配置")。</summary>
  33. [HttpGet]
  34. [S8Permission(S8PermissionCatalog.ConfigRead)]
  35. public async Task<IActionResult> MatrixAsync()
  36. {
  37. try { return Ok(await _svc.GetMatrixAsync(await _scope.ResolveAsync())); }
  38. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  39. }
  40. /// <summary>可授权角色(只列与 S8 相关的本租户角色,不机械返回全部)。</summary>
  41. [HttpGet("roles")]
  42. [S8Permission(S8PermissionCatalog.ConfigRead)]
  43. public async Task<IActionResult> RolesAsync()
  44. {
  45. try { return Ok(await _svc.GetAssignableRolesAsync(await _scope.ResolveAsync())); }
  46. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  47. }
  48. /// <summary>当前账号被允许的动作码 —— 前端据此控制按钮可见性,避免点了才 403。</summary>
  49. [HttpGet("mine")]
  50. [S8ExceptionAction(S8ExceptionActionCode.View)]
  51. public async Task<IActionResult> MineAsync()
  52. {
  53. try
  54. {
  55. var allowed = await _svc.GetMyAllowedActionsAsync(await _scope.ResolveAsync(), _authorizer);
  56. return Ok(allowed.ToList());
  57. }
  58. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  59. }
  60. /// <summary>覆盖某动作的授权角色(全量替换)。角色必须属于当前租户。</summary>
  61. [HttpPut("{actionCode}")]
  62. [S8Permission(S8PermissionCatalog.ConfigRoleWrite)]
  63. public async Task<IActionResult> SetAsync(string actionCode, [FromBody] AdoS8ActionRoleSetDto? body)
  64. {
  65. try
  66. {
  67. await _svc.SetActionRolesAsync(await _scope.ResolveAsync(), actionCode, body?.RoleIds);
  68. return Ok(new { actionCode, roleCount = body?.RoleIds?.Count ?? 0 });
  69. }
  70. catch (S8BizException ex) { return BadRequest(new { message = ex.Message }); }
  71. }
  72. }
  73. public class AdoS8ActionRoleSetDto
  74. {
  75. /// <summary>该动作的完整授权角色集合。传空数组 = 关闭该动作(fail closed)。</summary>
  76. public List<long>? RoleIds { get; set; }
  77. }