@ -228,7 +228,7 @@ func (a *appAuth) Revoke(ctx context.Context, userID, permissionID string) error
// GrantRole 授予角色
func ( a * appAuth ) GrantRole ( ctx context . Context , userID , roleCode string ) error {
var role models . Role
if err := cfg . DB ( ) . Where ( "code = ? AND scope = ? ", roleCod e, a . scop e) . First ( & role ) . Error ; err != nil {
if err := cfg . DB ( ) . Where ( "code = ? ", roleCod e) . First ( & role ) . Error ; err != nil {
return err
}
@ -250,7 +250,7 @@ func (a *appAuth) GrantRole(ctx context.Context, userID, roleCode string) error
// RevokeRole 撤销角色
func ( a * appAuth ) RevokeRole ( ctx context . Context , userID , roleCode string ) error {
var role models . Role
if err := cfg . DB ( ) . Where ( "code = ? AND scope = ? ", roleCod e, a . scop e) . First ( & role ) . Error ; err != nil {
if err := cfg . DB ( ) . Where ( "code = ? ", roleCod e) . First ( & role ) . Error ; err != nil {
return err
}
@ -380,11 +380,10 @@ func (a *appAuth) init() error {
for code , def := range a . roleDefs {
// 1. 确保角色存在
var role models . Role
err := db . Where ( "code = ? AND scope = ? ", cod e, a . scop e) . First ( & role ) . Error
err := db . Where ( "code = ? ", cod e) . First ( & role ) . Error
if err != nil {
if errors . Is ( err , gorm . ErrRecordNotFound ) {
role = models . Role {
Scope : a . scope ,
Code : code ,
Name : def . name ,
IsSystem : true ,
@ -398,13 +397,19 @@ func (a *appAuth) init() error {
}
}
// 2. 同步角色权限
// 简单起见,先清除旧的,再插入新的(生产环境可能需要更精细的 diff)
// 但 Permission 表是 mixed 的,不能随便删。
// 这里我们需要根据 RoleID 删除该角色的所有权限
if err := db . Where ( "role_id = ?" , role . ID ) . Delete ( & models . Permission { } ) . Error ; err != nil {
// 2. 同步角色权限 (Diff Sync)
// ID格式: scope:roleCode:permissionID:level
var targetIDs [ ] string
// 获取该角色当前scope下的所有权限ID, 用于快速比对
var existingIDs [ ] string
if err := db . Model ( & models . Permission { } ) . Where ( "role_id = ? AND scope = ?" , role . ID , a . scope ) . Pluck ( "id" , & existingIDs ) . Error ; err != nil {
return err
}
existingMap := make ( map [ string ] bool )
for _ , id := range existingIDs {
existingMap [ id ] = true
}
for _ , policy := range def . policies {
// policy 格式: "permissionID:level"
@ -412,19 +417,41 @@ func (a *appAuth) init() error {
if len ( parts ) < 2 {
continue
}
// 最后一个部分是 level, 前面是 permissionID
levelStr := parts [ len ( parts ) - 1 ]
permID := strings . Join ( parts [ : len ( parts ) - 1 ] , ":" )
var level int
fmt . Sscanf ( levelStr , "%d" , & level )
perm := models . Permission {
// 生成确定性 ID
id := fmt . Sprintf ( "%s:%s:%s:%d" , a . scope , role . Code , permID , level )
targetIDs = append ( targetIDs , id )
// 检查是否存在
if ! existingMap [ id ] {
// 不存在,创建新权限
newPerm := models . Permission {
Scope : a . scope ,
RoleID : & role . ID ,
PermissionID : permID ,
Level : level ,
}
if err := db . Create ( & perm ) . Error ; err != nil {
newPerm . ID = id
if err := db . Create ( & newPerm ) . Error ; err != nil {
return err
}
}
}
// 3. 清理不再需要的权限
if len ( targetIDs ) > 0 {
if err := db . Unscoped ( ) . Where ( "role_id = ? AND scope = ? AND id NOT IN ?" , role . ID , a . scope , targetIDs ) .
Delete ( & models . Permission { } ) . Error ; err != nil {
return err
}
} else {
// 如果没有策略,删除所有
if err := db . Unscoped ( ) . Where ( "role_id = ? AND scope = ?" , role . ID , a . scope ) .
Delete ( & models . Permission { } ) . Error ; err != nil {
return err
}
}
@ -446,19 +473,19 @@ func (a *appAuth) getUserPermissions(userID string) ([]models.Permission, error)
// 2. 角色权限
// 查用户角色
// UserRole 关联的是 RoleID , Role 表有 Scope
// 我们需要关联查询: UserRole -> Role (where scope=a.scope)
// UserRole 关联的是 RoleID
// Role 表已经没有 Scope, 所以这里查出用户拥有的所有角色ID
var roleIDs [ ] string
if err := db . Table ( "user_roles" ) .
Joins ( "JOIN roles ON roles.id = user_roles.role_id" ) .
Where ( "user_roles.user_id = ? AND roles.scope = ?" , userID , a . scope ) .
Pluck ( "user_roles.role_id" , & roleIDs ) . Error ; err != nil {
Where ( "user_id = ?" , userID ) .
Pluck ( "role_id" , & roleIDs ) . Error ; err != nil {
return nil , err
}
if len ( roleIDs ) > 0 {
var rolePerms [ ] models . Permission
if err := db . Where ( "role_id IN ?" , roleIDs ) . Find ( & rolePerms ) . Error ; err != nil {
// 查询这些角色在当前 scope 下拥有的权限
if err := db . Where ( "role_id IN ? AND scope = ?" , roleIDs , a . scope ) . Find ( & rolePerms ) . Error ; err != nil {
return nil , err
}
perms = append ( perms , rolePerms ... )