roleDetailLogic.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package role
  2. import (
  3. "context"
  4. "perms-system-server/internal/middleware"
  5. "perms-system-server/internal/response"
  6. "perms-system-server/internal/svc"
  7. "perms-system-server/internal/types"
  8. "github.com/zeromicro/go-zero/core/logx"
  9. )
  10. type RoleDetailLogic struct {
  11. logx.Logger
  12. ctx context.Context
  13. svcCtx *svc.ServiceContext
  14. }
  15. func NewRoleDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RoleDetailLogic {
  16. return &RoleDetailLogic{
  17. Logger: logx.WithContext(ctx),
  18. ctx: ctx,
  19. svcCtx: svcCtx,
  20. }
  21. }
  22. // RoleDetail 角色详情。根据角色 ID 查询角色完整信息及其已绑定的权限 ID 列表。
  23. func (l *RoleDetailLogic) RoleDetail(req *types.RoleDetailReq) (resp *types.RoleItem, err error) {
  24. caller := middleware.GetUserDetails(l.ctx)
  25. if caller == nil {
  26. return nil, response.ErrUnauthorized("未登录")
  27. }
  28. // 审计 M-N3:合并"角色不存在"与"跨产品访问"两种响应,全部走统一 404 "角色不存在"。
  29. // 旧实现先 FindOne 再判 ProductCode 会形成枚举 oracle:
  30. // - req.Id 不存在 → 404
  31. // - req.Id 存在但在别的产品 → 403
  32. // 攻击者遍历 id 即可画出跨产品 roleId 分布图。新实现:
  33. // (1) 先 FindOne 看 id 是否在 DB 里存在;
  34. // (2) 非超管且 ProductCode 不匹配时统一伪装成"不存在",与真正的 NotFound 响应体一致,
  35. // 消除存在性差异;超管仍可跨产品查看。
  36. role, err := l.svcCtx.SysRoleModel.FindOne(l.ctx, req.Id)
  37. if err != nil {
  38. return nil, response.ErrNotFound("角色不存在")
  39. }
  40. if !caller.IsSuperAdmin && caller.ProductCode != role.ProductCode {
  41. return nil, response.ErrNotFound("角色不存在")
  42. }
  43. permIds, err := l.svcCtx.SysRolePermModel.FindPermIdsByRoleId(l.ctx, role.Id)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return &types.RoleItem{
  48. Id: role.Id,
  49. ProductCode: role.ProductCode,
  50. Name: role.Name,
  51. Remark: role.Remark,
  52. Status: role.Status,
  53. PermsLevel: role.PermsLevel,
  54. PermIds: permIds,
  55. CreateTime: role.CreateTime,
  56. }, nil
  57. }