app-cloudep-permission-server/pkg/usecase/casbin_redis_rbac.go

175 lines
4.4 KiB
Go
Raw Normal View History

2025-02-24 01:04:06 +00:00
package usecase
import (
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/usecase"
"code.30cm.net/digimon/library-go/errs"
"context"
"fmt"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/zeromicro/go-zero/core/logx"
"log"
"time"
)
type RBACUseCaseParam struct {
ModulePath string
permissionRepo repository.PermissionRepository
RBACRedisAdapter repository.RBACAdapter
// role permission 之類的
}
type RBACUseCase struct {
permissionRepo repository.PermissionRepository
adapter repository.RBACAdapter
instance *casbin.Enforcer
}
func NewUseCase(param RBACUseCaseParam) usecase.RBACUseCase {
result := &RBACUseCase{
adapter: param.RBACRedisAdapter,
permissionRepo: param.permissionRepo,
}
// 1. 讀取 RBAC 模型 ->
m, err := model.NewModelFromFile(param.ModulePath)
if err != nil {
log.Fatalf("failed to load model: %v", err)
}
// 3. 創建 Casbin Enforcer
enforcer, err := casbin.NewEnforcer(m, result.adapter)
if err != nil {
log.Fatalf("failed to init Enforcer: %v", err)
}
result.instance = enforcer
return result
}
func (use *RBACUseCase) Check(ctx context.Context, role, path, method string) (usecase.CheckRolePermissionStatus, error) {
ok, p, err := use.instance.EnforceEx(role, path, method)
if err != nil {
e := errs.ForbiddenL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: fmt.Sprintf("role: %s, path: %s, method: %s", role, path, method)},
{Key: "func", Value: "casbin.EnforceEx"},
{Key: "err", Value: err.Error()},
},
"failed to get permission")
return usecase.CheckRolePermissionStatus{}, e
}
status := usecase.CheckRolePermissionStatus{
Allow: ok,
}
fmt.Println(p)
//// 檢查是否有明碼查詢權限
//if role == domain.AdminRoleUID {
// status.Select.PlainCode = true
//} else if ok && method == http.MethodGet {
// status.Select.PlainCode = use.rbac.GetModel().HasPolicy("p", "p", []string{
// role, path, method, p[3] + ".plain_code",
// })
//}
//
//limit := 4
//if len(p) >= limit {
// status.Select.PermissionName = p[3]
//}
return status, nil
}
func (use *RBACUseCase) LoadPolicy(ctx context.Context) error {
status := permission.Open
// 取得所有permission -> permission tree 拿到有開啟的節點,如果付節點關閉,子節點也就不顯示了
permissions, err := use.permissionRepo.GetAll(ctx, &status)
if err != nil {
return fmt.Errorf("permissionRepo.AllStatus error: %w", err)
}
fmt.Println(permissions)
// 全部permission
//permissionMap := make(map[int64]entity.Permission, len(permissions))
//for _, v := range permissions {
// permissionMap[v.ID] = v
//}
// 全部角色
//roles, err := r.roleRepo.All(ctx, 1)
//if err != nil {
// return fmt.Errorf("roleRepo.AllStatus error: %w", err)
//}
//
//roleMap := make(map[int64]entity.Role, len(roles))
//for _, v := range roles {
// roleMap[v.ID] = v
//}
// 根據角色組合權限表
//for _, v := range roles {
// rolePermissions, err := r.rolePermissionRepo.Get(ctx, v.ID)
// if err != nil {
// return fmt.Errorf("rolePermissionRepo.Get ID: %d error: %w", v.ID, err)
// }
//
// for _, rp := range rolePermissions {
// role, ok := roleMap[rp.RoleID]
// if !ok {
// logrus.WithFields(logrus.Fields{
// "role_id": rp.RoleID,
// }).Error("role not found")
//
// continue
// }
//
// permission, ok := permissionMap[rp.PermissionID]
// if !ok {
// logrus.WithFields(logrus.Fields{
// "permission_id": rp.PermissionID,
// }).Error("permission not found")
//
// continue
// }
//
// if permission.HTTPPath == "" || permission.HTTPMethod == "" {
// continue
// }
//
// // 根據策略model configs/rbac_model.conf填入policy_definition對應參數
// err := persist.LoadPolicyArray([]string{"p", role.UID, permission.HTTPPath, permission.HTTPMethod, permission.Name}, model)
// if err != nil {
// return fmt.Errorf("persist.LoadPolicyArray error: %w", err)
// }
// }
//}
return nil
}
func (use *RBACUseCase) SyncPolicy(ctx context.Context, cron time.Duration) {
t := time.NewTicker(cron)
for {
select {
case <-t.C:
if err := use.LoadPolicy(ctx); err == nil {
logx.Info("LoadPolicy success")
}
case <-ctx.Done():
t.Stop()
logx.Info("exit Policy success")
return
}
}
}