Skip to content

Commit 82ab576

Browse files
committed
fix(auth): prevent and heal dirty admin permissions
1 parent 39c236b commit 82ab576

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

internal/db/role.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ func UpdateRolePermissionsPathPrefix(oldPath, newPath string) ([]uint, error) {
7979
}
8080

8181
for _, role := range roles {
82+
if role.Name == "admin" || role.Name == "guest" {
83+
continue
84+
}
8285
updated := false
8386
for i, entry := range role.PermissionScopes {
8487
entryPath := path.Clean(entry.Path)

internal/op/role.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,24 @@ func init() {
2121
model.FetchRole = GetRole
2222
}
2323

24+
func enforceAdminRoleDefaults(r *model.Role) error {
25+
if r == nil || r.Name != "admin" {
26+
return nil
27+
}
28+
if len(r.PermissionScopes) == 1 {
29+
scopePath := utils.FixAndCleanPath(r.PermissionScopes[0].Path)
30+
if scopePath == "/" && r.PermissionScopes[0].Permission == 0xFFFF {
31+
r.PermissionScopes[0].Path = "/"
32+
return nil
33+
}
34+
}
35+
36+
r.PermissionScopes = []model.PermissionEntry{
37+
{Path: "/", Permission: 0xFFFF},
38+
}
39+
return db.UpdateRole(r)
40+
}
41+
2442
func GetRole(id uint) (*model.Role, error) {
2543
key := fmt.Sprint(id)
2644
if r, ok := roleCache.Get(key); ok {
@@ -31,7 +49,11 @@ func GetRole(id uint) (*model.Role, error) {
3149
if err != nil {
3250
return nil, err
3351
}
52+
if err := enforceAdminRoleDefaults(_r); err != nil {
53+
return nil, err
54+
}
3455
roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
56+
roleCache.Set(_r.Name, _r, cache.WithEx[*model.Role](time.Hour))
3557
return _r, nil
3658
})
3759
return r, err
@@ -46,7 +68,11 @@ func GetRoleByName(name string) (*model.Role, error) {
4668
if err != nil {
4769
return nil, err
4870
}
71+
if err := enforceAdminRoleDefaults(_r); err != nil {
72+
return nil, err
73+
}
4974
roleCache.Set(name, _r, cache.WithEx[*model.Role](time.Hour))
75+
roleCache.Set(fmt.Sprint(_r.ID), _r, cache.WithEx[*model.Role](time.Hour))
5076
return _r, nil
5177
})
5278
return r, err
@@ -89,7 +115,11 @@ func GetRolesByUserID(userID uint) ([]model.Role, error) {
89115
if err != nil {
90116
return nil, err
91117
}
118+
if err := enforceAdminRoleDefaults(_r); err != nil {
119+
return nil, err
120+
}
92121
roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
122+
roleCache.Set(_r.Name, _r, cache.WithEx[*model.Role](time.Hour))
93123
return _r, nil
94124
})
95125
if err != nil {

internal/op/user.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ var userG singleflight.Group[*model.User]
1616
var guestUser *model.User
1717
var adminUser *model.User
1818

19+
func enforceAdminUserDefaults(u *model.User) error {
20+
if u == nil || !u.IsAdmin() {
21+
return nil
22+
}
23+
changed := false
24+
if utils.FixAndCleanPath(u.BasePath) != "/" {
25+
u.BasePath = "/"
26+
changed = true
27+
}
28+
if u.Permission != 0xFFFF {
29+
u.Permission = 0xFFFF
30+
changed = true
31+
}
32+
if !changed {
33+
return nil
34+
}
35+
return db.UpdateUser(u)
36+
}
37+
1938
func GetAdmin() (*model.User, error) {
2039
if adminUser == nil {
2140
role, err := GetRoleByName("admin")
@@ -26,7 +45,12 @@ func GetAdmin() (*model.User, error) {
2645
if err != nil {
2746
return nil, err
2847
}
48+
if err := enforceAdminUserDefaults(user); err != nil {
49+
return nil, err
50+
}
2951
adminUser = user
52+
} else if err := enforceAdminUserDefaults(adminUser); err != nil {
53+
return nil, err
3054
}
3155
return adminUser, nil
3256
}
@@ -59,13 +83,19 @@ func GetUserByName(username string) (*model.User, error) {
5983
return nil, errs.EmptyUsername
6084
}
6185
if user, ok := userCache.Get(username); ok {
86+
if err := enforceAdminUserDefaults(user); err != nil {
87+
return nil, err
88+
}
6289
return user, nil
6390
}
6491
user, err, _ := userG.Do(username, func() (*model.User, error) {
6592
_user, err := db.GetUserByName(username)
6693
if err != nil {
6794
return nil, err
6895
}
96+
if err := enforceAdminUserDefaults(_user); err != nil {
97+
return nil, err
98+
}
6999
userCache.Set(username, _user, cache.WithEx[*model.User](time.Hour))
70100
return _user, nil
71101
})

0 commit comments

Comments
 (0)