Skip to content

Commit 55b2bb6

Browse files
authored
feat(user-management): Enhance admin management and role handling
2 parents 3353055 + d5df6fa commit 55b2bb6

File tree

5 files changed

+39
-5
lines changed

5 files changed

+39
-5
lines changed

internal/db/user.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package db
22

33
import (
44
"encoding/base64"
5+
"fmt"
56
"github.com/alist-org/alist/v3/internal/model"
67
"github.com/alist-org/alist/v3/pkg/utils"
78
"github.com/go-webauthn/webauthn/webauthn"
@@ -140,3 +141,13 @@ func UpdateUserBasePathPrefix(oldPath, newPath string) ([]string, error) {
140141

141142
return modifiedUsernames, nil
142143
}
144+
145+
func CountUsersByRoleAndEnabledExclude(roleID uint, excludeUserID uint) (int64, error) {
146+
var count int64
147+
jsonValue := fmt.Sprintf("[%d]", roleID)
148+
err := db.Model(&model.User{}).
149+
Where("disabled = ? AND id != ?", false, excludeUserID).
150+
Where("JSON_CONTAINS(role, ?)", jsonValue).
151+
Count(&count).Error
152+
return count, err
153+
}

internal/op/role.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,12 @@ func UpdateRole(r *model.Role) error {
9797
if err != nil {
9898
return err
9999
}
100-
if old.Name == "admin" || old.Name == "guest" {
100+
switch old.Name {
101+
case "admin":
101102
return errs.ErrChangeDefaultRole
103+
104+
case "guest":
105+
r.Name = "guest"
102106
}
103107
for i := range r.PermissionScopes {
104108
r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)

internal/op/user.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,11 @@ func DelUserCache(username string) error {
165165
userCache.Del(username)
166166
return nil
167167
}
168+
169+
func CountEnabledAdminsExcluding(userID uint) (int64, error) {
170+
adminRole, err := GetRoleByName("admin")
171+
if err != nil {
172+
return 0, err
173+
}
174+
return db.CountUsersByRoleAndEnabledExclude(adminRole.ID, userID)
175+
}

server/handles/role.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,13 @@ func UpdateRole(c *gin.Context) {
6666
common.ErrorResp(c, err, 500, true)
6767
return
6868
}
69-
if role.Name == "admin" || role.Name == "guest" {
69+
switch role.Name {
70+
case "admin":
7071
common.ErrorResp(c, errs.ErrChangeDefaultRole, 403)
7172
return
73+
74+
case "guest":
75+
req.Name = "guest"
7276
}
7377
if err := op.UpdateRole(&req); err != nil {
7478
common.ErrorResp(c, err, 500, true)

server/handles/user.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,16 @@ func UpdateUser(c *gin.Context) {
8383
if req.OtpSecret == "" {
8484
req.OtpSecret = user.OtpSecret
8585
}
86-
if req.Disabled && req.IsAdmin() {
87-
common.ErrorStrResp(c, "admin user can not be disabled", 400)
88-
return
86+
if req.Disabled && user.IsAdmin() {
87+
count, err := op.CountEnabledAdminsExcluding(user.ID)
88+
if err != nil {
89+
common.ErrorResp(c, err, 500)
90+
return
91+
}
92+
if count == 0 {
93+
common.ErrorStrResp(c, "at least one enabled admin must be kept", 400)
94+
return
95+
}
8996
}
9097
if err := op.UpdateUser(&req); err != nil {
9198
common.ErrorResp(c, err, 500)

0 commit comments

Comments
 (0)