@ -13,8 +13,6 @@ import (
"strings"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/libs/cache"
"github.com/veypi/vbase/libs/jwt"
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
pub "github.com/veypi/vigo/contrib/auth"
@ -38,15 +36,18 @@ const (
// PermFunc 权限检查函数类型
type PermFunc = pub . PermFunc
// Provider 是 auth.Provider 的别名,用于实现端
type Provider = pub . Provider
// Factory 全局 Auth 工厂
var Factory = & authFactory {
apps : make ( map [ string ] * appAuth ) ,
apps : make ( map [ string ] Provider ) ,
}
// VBase Auth vbase 自身的权限管理 实例
var VBase Auth = Factory . New ( "vb" )
// VBase Provider vbase 自身的权限 Provider 实例
var VBase Provider Provider
var _ pub . Auth = & appAuth { }
var _ pub . Provider = & vbaseProvider { }
func init ( ) {
// 注册权限初始化回调
@ -54,28 +55,30 @@ func init() {
}
type authFactory struct {
apps map [ string ] * appAuth
apps map [ string ] Provider
}
// New 创建权限 管理 实例
func ( f * authFactory ) New ( scope string ) pub. Auth {
if auth , exists := f . apps [ scope ] ; exists {
return auth
// New 创建权限 Provider 实例
func ( f * authFactory ) New ( scope string ) Provider {
if p , exists := f . apps [ scope ] ; exists {
return p
}
auth := & appAuth {
p := & vbaseProvider {
scope : scope ,
roleDefs : make ( map [ string ] roleDefinition ) ,
}
f . apps [ scope ] = auth
return auth
f . apps [ scope ] = p
return p
}
func ( f * authFactory ) init ( ) error {
for appKey , auth := range f . apps {
if err := auth . init ( ) ; err != nil {
for appKey , p := range f . apps {
if vp , ok := p . ( * vbaseProvider ) ; ok {
if err := vp . init ( ) ; err != nil {
return fmt . Errorf ( "failed to init auth for %s: %w" , appKey , err )
}
}
}
return nil
}
@ -86,113 +89,23 @@ type roleDefinition struct {
policies [ ] string // 格式: "permissionID:level"
}
// appAuth 实现 Auth 接口
type appAuth struct {
// vbaseProvider 实现 Provider 接口
type vbaseProvider struct {
scope string
roleDefs map [ string ] roleDefinition
}
// ========== 接口实现 ==========
// ========== Provider 接口实现 ==========
func ( a * appAuth ) UserID ( x * vigo . X ) string {
func ( a * vbaseProvider ) UserID ( x * vigo . X ) string {
if uid , ok := x . Get ( CtxKeyUserID ) . ( string ) ; ok {
return uid
}
return ""
}
// Login 登录检查中间件
func ( a * appAuth ) Login ( ) PermFunc {
return func ( x * vigo . X ) error {
// 1. 提取 token
tokenString := extractToken ( x )
if tokenString == "" {
return vigo . ErrUnauthorized . WithString ( "missing token" )
}
// 2. 解析 token
claims , err := jwt . ParseToken ( tokenString )
if err != nil {
if err == jwt . ErrExpiredToken {
return vigo . ErrTokenExpired
}
return vigo . ErrTokenInvalid
}
// 3. 检查黑名单
if cache . IsEnabled ( ) {
blacklisted , _ := cache . IsTokenBlacklisted ( claims . ID )
if blacklisted {
return vigo . ErrUnauthorized . WithString ( "token has been revoked" )
}
}
// 4. 设置 UserID
x . Set ( CtxKeyUserID , claims . UserID )
return nil
}
}
func ( a * appAuth ) Perm ( code string , level int ) PermFunc {
return func ( x * vigo . X ) error {
userID := a . UserID ( x )
if userID == "" {
// 尝试先运行 Login 逻辑
if err := a . Login ( ) ( x ) ; err != nil {
return err
}
userID = a . UserID ( x )
}
// 解析动态参数
permID , err := parsePermissionID ( x , code )
if err != nil {
return vigo . ErrInvalidArg . WithError ( err )
}
// 检查权限
if err := validatePermission ( permID , level ) ; err != nil {
panic ( err )
}
if ! a . Check ( x . Context ( ) , userID , permID , level ) {
return vigo . ErrNoPermission . WithString ( fmt . Sprintf ( "requires permission: %s (level %d)" , permID , level ) )
}
return nil
}
}
func ( a * appAuth ) PermCreate ( code string ) PermFunc {
if err := validatePermission ( code , LevelCreate ) ; err != nil {
panic ( err )
}
return a . Perm ( code , LevelCreate )
}
func ( a * appAuth ) PermRead ( code string ) PermFunc {
if err := validatePermission ( code , LevelRead ) ; err != nil {
panic ( err )
}
return a . Perm ( code , LevelRead )
}
func ( a * appAuth ) PermWrite ( code string ) PermFunc {
if err := validatePermission ( code , LevelWrite ) ; err != nil {
panic ( err )
}
return a . Perm ( code , LevelWrite )
}
func ( a * appAuth ) PermAdmin ( code string ) PermFunc {
if err := validatePermission ( code , LevelAdmin ) ; err != nil {
panic ( err )
}
return a . Perm ( code , LevelAdmin )
}
// Grant 授予权限
func ( a * appAuth ) Grant ( ctx context . Context , userID , permissionID string , level int ) error {
func ( a * vbaseProvider ) Grant ( ctx context . Context , userID , permissionID string , level int ) error {
if err := validatePermission ( permissionID , level ) ; err != nil {
return err
}
@ -220,13 +133,13 @@ func (a *appAuth) Grant(ctx context.Context, userID, permissionID string, level
}
// Revoke 撤销权限
func ( a * appAuth ) Revoke ( ctx context . Context , userID , permissionID string ) error {
func ( a * vbaseProvider ) Revoke ( ctx context . Context , userID , permissionID string ) error {
return cfg . DB ( ) . Where ( "user_id = ? AND permission_id = ? AND scope = ?" , userID , permissionID , a . scope ) .
Delete ( & models . Permission { } ) . Error
}
// GrantRole 授予角色
func ( a * appAuth ) GrantRole ( ctx context . Context , userID , roleCode string ) error {
func ( a * vbaseProvider ) GrantRole ( ctx context . Context , userID , roleCode string ) error {
var role models . Role
if err := cfg . DB ( ) . Where ( "code = ?" , roleCode ) . First ( & role ) . Error ; err != nil {
return err
@ -248,7 +161,7 @@ func (a *appAuth) GrantRole(ctx context.Context, userID, roleCode string) error
}
// RevokeRole 撤销角色
func ( a * appAuth ) RevokeRole ( ctx context . Context , userID , roleCode string ) error {
func ( a * vbaseProvider ) RevokeRole ( ctx context . Context , userID , roleCode string ) error {
var role models . Role
if err := cfg . DB ( ) . Where ( "code = ?" , roleCode ) . First ( & role ) . Error ; err != nil {
return err
@ -259,7 +172,7 @@ func (a *appAuth) RevokeRole(ctx context.Context, userID, roleCode string) error
}
// Check 检查权限
func ( a * appAuth ) Check ( ctx context . Context , userID , permissionID string , level int ) bool {
func ( a * vbaseProvider ) Check ( ctx context . Context , userID , permissionID string , level int ) bool {
if err := validatePermission ( permissionID , level ) ; err != nil {
panic ( err )
}
@ -274,7 +187,7 @@ func (a *appAuth) Check(ctx context.Context, userID, permissionID string, level
}
// ListResources 查询用户在特定资源类型下的详细权限信息
func ( a * appAuth ) ListResources ( ctx context . Context , userID , resourceType string ) ( map [ string ] int , error ) {
func ( a * vbaseProvider ) ListResources ( ctx context . Context , userID , resourceType string ) ( map [ string ] int , error ) {
perms , err := a . getUserPermissions ( userID )
if err != nil {
return nil , err
@ -309,7 +222,7 @@ func (a *appAuth) ListResources(ctx context.Context, userID, resourceType string
}
// ListUsers 查询特定资源的所有协作者及其权限
func ( a * appAuth ) ListUsers ( ctx context . Context , permissionID string ) ( map [ string ] int , error ) {
func ( a * vbaseProvider ) ListUsers ( ctx context . Context , permissionID string ) ( map [ string ] int , error ) {
parents := getAllParents ( permissionID )
var perms [ ] models . Permission
@ -365,7 +278,7 @@ func getAllParents(permID string) []string {
}
// AddRole 添加角色定义
func ( a * appAuth ) AddRole ( code , name string , policies ... string ) error {
func ( a * vbaseProvider ) AddRole ( code , name string , policies ... string ) error {
a . roleDefs [ code ] = roleDefinition {
code : code ,
name : name ,
@ -375,7 +288,7 @@ func (a *appAuth) AddRole(code, name string, policies ...string) error {
}
// init 初始化角色到数据库
func ( a * appAuth ) init ( ) error {
func ( a * vbaseProvider ) init ( ) error {
db := cfg . DB ( )
for code , def := range a . roleDefs {
// 1. 确保角色存在
@ -462,7 +375,7 @@ func (a *appAuth) init() error {
// ========== 内部辅助方法 ==========
// getUserPermissions 获取用户的所有权限(聚合 Role 和 Direct Permission)
func ( a * appAuth ) getUserPermissions ( userID string ) ( [ ] models . Permission , error ) {
func ( a * vbaseProvider ) getUserPermissions ( userID string ) ( [ ] models . Permission , error ) {
var perms [ ] models . Permission
db := cfg . DB ( )