131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
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)
|
|
}
|