125 lines
2.9 KiB
Go
125 lines
2.9 KiB
Go
package auth
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
|
||
"github.com/casbin/casbin/v2"
|
||
gormadapter "github.com/casbin/gorm-adapter/v3"
|
||
"go.uber.org/zap"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// CasbinService Casbin权限服务
|
||
type CasbinService struct {
|
||
enforcer *casbin.Enforcer
|
||
logger *zap.Logger
|
||
mu sync.RWMutex
|
||
}
|
||
|
||
// NewCasbinService 创建Casbin服务
|
||
func NewCasbinService(db *gorm.DB, modelPath string, logger *zap.Logger) (*CasbinService, error) {
|
||
// 使用Gorm适配器,自动使用casbin_rule表
|
||
adapter, err := gormadapter.NewAdapterByDBUseTableName(db, "", "casbin_rule")
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建Casbin适配器失败: %w", err)
|
||
}
|
||
|
||
// 创建Enforcer
|
||
enforcer, err := casbin.NewEnforcer(modelPath, adapter)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建Casbin执行器失败: %w", err)
|
||
}
|
||
|
||
// 加载策略
|
||
if err := enforcer.LoadPolicy(); err != nil {
|
||
return nil, fmt.Errorf("加载Casbin策略失败: %w", err)
|
||
}
|
||
|
||
logger.Info("Casbin权限服务初始化成功")
|
||
|
||
return &CasbinService{
|
||
enforcer: enforcer,
|
||
logger: logger,
|
||
}, nil
|
||
}
|
||
|
||
// Enforce 检查权限
|
||
// sub: 主体(用户角色), obj: 资源, act: 操作
|
||
func (s *CasbinService) Enforce(sub, obj, act string) (bool, error) {
|
||
s.mu.RLock()
|
||
defer s.mu.RUnlock()
|
||
|
||
return s.enforcer.Enforce(sub, obj, act)
|
||
}
|
||
|
||
// CheckPermission 检查用户权限(便捷方法)
|
||
func (s *CasbinService) CheckPermission(role, resource, action string) bool {
|
||
allowed, err := s.Enforce(role, resource, action)
|
||
if err != nil {
|
||
s.logger.Error("权限检查失败",
|
||
zap.String("role", role),
|
||
zap.String("resource", resource),
|
||
zap.String("action", action),
|
||
zap.Error(err),
|
||
)
|
||
return false
|
||
}
|
||
return allowed
|
||
}
|
||
|
||
// AddPolicy 添加策略
|
||
func (s *CasbinService) AddPolicy(sub, obj, act string) (bool, error) {
|
||
s.mu.Lock()
|
||
defer s.mu.Unlock()
|
||
|
||
return s.enforcer.AddPolicy(sub, obj, act)
|
||
}
|
||
|
||
// RemovePolicy 移除策略
|
||
func (s *CasbinService) RemovePolicy(sub, obj, act string) (bool, error) {
|
||
s.mu.Lock()
|
||
defer s.mu.Unlock()
|
||
|
||
return s.enforcer.RemovePolicy(sub, obj, act)
|
||
}
|
||
|
||
// AddRoleForUser 为用户添加角色
|
||
func (s *CasbinService) AddRoleForUser(user, role string) (bool, error) {
|
||
s.mu.Lock()
|
||
defer s.mu.Unlock()
|
||
|
||
return s.enforcer.AddRoleForUser(user, role)
|
||
}
|
||
|
||
// GetRolesForUser 获取用户的角色
|
||
func (s *CasbinService) GetRolesForUser(user string) []string {
|
||
s.mu.RLock()
|
||
defer s.mu.RUnlock()
|
||
|
||
roles, _ := s.enforcer.GetRolesForUser(user)
|
||
return roles
|
||
}
|
||
|
||
// GetPermissionsForRole 获取角色的所有权限
|
||
func (s *CasbinService) GetPermissionsForRole(role string) [][]string {
|
||
s.mu.RLock()
|
||
defer s.mu.RUnlock()
|
||
|
||
perms, _ := s.enforcer.GetPermissionsForUser(role)
|
||
return perms
|
||
}
|
||
|
||
// ReloadPolicy 重新加载策略
|
||
func (s *CasbinService) ReloadPolicy() error {
|
||
s.mu.Lock()
|
||
defer s.mu.Unlock()
|
||
|
||
return s.enforcer.LoadPolicy()
|
||
}
|
||
|
||
// GetEnforcer 获取原始Enforcer(用于高级操作)
|
||
func (s *CasbinService) GetEnforcer() *casbin.Enforcer {
|
||
return s.enforcer
|
||
}
|