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
|
|||
|
|
}
|