package system import ( "errors" "strconv" "kra/internal/biz/system" "kra/internal/conf" "kra/internal/server/middleware" kerrors "github.com/go-kratos/kratos/v2/errors" "github.com/go-kratos/kratos/v2/transport/http" ) // CasbinService Casbin服务 type CasbinService struct { casbinRepo system.CasbinRepo authUc *system.AuthorityUsecase apiUc *system.ApiUsecase useStrictAuth bool } // NewCasbinService 创建Casbin服务 func NewCasbinService(casbinRepo system.CasbinRepo, authUc *system.AuthorityUsecase, apiUc *system.ApiUsecase, useStrictAuth conf.UseStrictAuth) *CasbinService { return &CasbinService{ casbinRepo: casbinRepo, authUc: authUc, apiUc: apiUc, useStrictAuth: bool(useStrictAuth), } } // UpdateCasbinRequest 更新Casbin请求 type UpdateCasbinRequest struct { AuthorityId uint `json:"authorityId"` CasbinInfos []system.CasbinRule `json:"casbinInfos"` } // PolicyPathResponse 权限路径响应 type PolicyPathResponse struct { Paths []system.CasbinRule `json:"paths"` } // GetPolicyPathRequest 获取权限路径请求 type GetPolicyPathRequest struct { AuthorityId uint `json:"authorityId"` } // UpdateCasbin 更新Casbin权限 func (s *CasbinService) UpdateCasbin(ctx http.Context, adminAuthorityID uint, req *UpdateCasbinRequest) error { // 检查权限 if err := s.authUc.CheckAuthorityIDAuth(ctx, adminAuthorityID, req.AuthorityId); err != nil { return err } // 严格模式下检查API权限 if s.useStrictAuth { apis, err := s.apiUc.GetAllApis(ctx, adminAuthorityID) if err != nil { return err } for _, info := range req.CasbinInfos { hasApi := false for _, api := range apis { if api.Path == info.Path && api.Method == info.Method { hasApi = true break } } if !hasApi { return errors.New("存在api不在权限列表中") } } } return s.casbinRepo.UpdateCasbin(adminAuthorityID, req.AuthorityId, req.CasbinInfos) } // GetPolicyPathByAuthorityId 获取权限列表 func (s *CasbinService) GetPolicyPathByAuthorityId(authorityId uint) []system.CasbinRule { return s.casbinRepo.GetPolicyPathByAuthorityId(authorityId) } // RegisterRoutes 注册路由 func (s *CasbinService) RegisterRoutes(rg *RouterGroup) { // 私有路由 + 操作记录(写操作) rg.PrivateWithRecord.POST("/casbin/updateCasbin", s.handleUpdateCasbin) // 私有路由(读操作,不记录) rg.Private.POST("/casbin/getPolicyPathByAuthorityId", s.handleGetPolicyPath) } func (s *CasbinService) handleUpdateCasbin(ctx http.Context) error { var req UpdateCasbinRequest if err := ctx.Bind(&req); err != nil { return err } if req.AuthorityId == 0 { return kerrors.BadRequest("INVALID_AUTHORITY", "角色ID不能为空") } adminAuthorityID := middleware.GetAuthorityID(ctx) if adminAuthorityID == 0 { return kerrors.Unauthorized("UNAUTHORIZED", "请先登录") } if err := s.UpdateCasbin(ctx, adminAuthorityID, &req); err != nil { return kerrors.InternalServer("UPDATE_ERROR", err.Error()) } return ctx.Result(200, map[string]any{"code": 0, "msg": "更新成功"}) } func (s *CasbinService) handleGetPolicyPath(ctx http.Context) error { var req GetPolicyPathRequest if err := ctx.Bind(&req); err != nil { return err } if req.AuthorityId == 0 { return kerrors.BadRequest("INVALID_AUTHORITY", "角色ID不能为空") } paths := s.GetPolicyPathByAuthorityId(req.AuthorityId) return ctx.Result(200, map[string]any{ "code": 0, "msg": "获取成功", "data": PolicyPathResponse{Paths: paths}, }) } // 辅助函数 func uintToStr(n uint) string { return strconv.FormatUint(uint64(n), 10) }