修复管理员查看超级管理员范围
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-10-01 05:19:23 +08:00
parent 3e07b90c1b
commit dab7f96249
2 changed files with 46 additions and 2 deletions

View File

@ -21,14 +21,15 @@ var (
// ScopePredicate 的外层必须是用户表。使用实时子查询,不缓存管理员的分组范围。
// 未建立成员关系的旧账号以及新账号都属于默认分组,无需迁移或复制账号数据。
func ScopePredicate(actorID int) (string, []any) {
return `(id IN (
return `((id IN (
SELECT gm.user_id FROM account_group_member gm
JOIN account_group_member am ON gm.group_id = am.group_id
WHERE am.user_id = ?
) OR ((id NOT IN (SELECT user_id FROM account_group_member)
OR id IN (SELECT user_id FROM account_group_member WHERE group_id = 0))
AND (NOT EXISTS (SELECT 1 FROM account_group_member WHERE user_id = ?)
OR EXISTS (SELECT 1 FROM account_group_member WHERE user_id = ? AND group_id = 0))))`,
OR EXISTS (SELECT 1 FROM account_group_member WHERE user_id = ? AND group_id = 0))))
AND NOT ` + models.SuperAdminPredicate + `)`,
[]any{actorID, actorID, actorID}
}

View File

@ -0,0 +1,43 @@
package accountgroup
import (
"testing"
"git.pcux.cn/xuans/Smail/models"
"git.pcux.cn/xuans/Smail/services/access"
_ "modernc.org/sqlite"
"xorm.io/xorm"
)
func TestCanAccessExcludesSuperAdminFromAdminScope(t *testing.T) {
engine, err := xorm.NewEngine("sqlite", ":memory:")
if err != nil {
t.Fatal(err)
}
defer engine.Close()
if err := engine.Sync2(new(models.User), new(models.AccountGroupMember)); err != nil {
t.Fatal(err)
}
superAdmin := models.User{Account: "superadmin", Name: "超级管理员", Role: string(access.RoleSuperAdmin)}
admin := models.User{Account: "admin", Name: "分组管理员", Role: string(access.RoleAdmin), IsAdmin: 1}
member := models.User{Account: "member", Name: "普通用户", Role: string(access.RoleUser)}
if _, err := engine.Insert(&superAdmin, &admin, &member); err != nil {
t.Fatal(err)
}
if _, err := engine.Insert(
&models.AccountGroupMember{UserID: admin.ID, GroupID: 1},
&models.AccountGroupMember{UserID: member.ID, GroupID: 1},
); err != nil {
t.Fatal(err)
}
if CanAccess(engine, admin.ID, access.RoleAdmin, superAdmin.ID) {
t.Fatal("管理员不应访问超级管理员账户")
}
if !CanAccess(engine, admin.ID, access.RoleAdmin, member.ID) {
t.Fatal("管理员应访问同组普通用户账户")
}
}