mirror of https://github.com/Xhofe/alist
feat(user-management): Enhance admin management and role handling
- Add `CountEnabledAdminsExcluding` function to count enabled admins excluding a specific user. - Implement `CountUsersByRoleAndEnabledExclude` in `internal/db/user.go` to support exclusion logic. - Refactor role handling with switch-case for better readability in `server/handles/role.go`. - Ensure at least one enabled admin remains when disabling an admin in `server/handles/user.go`. - Maintain guest role name consistency when updating roles in `internal/op/role.go`.pull/9227/head
parent
00120cba27
commit
5b8c26510b
|
@ -2,6 +2,7 @@ package db
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/alist-org/alist/v3/internal/model"
|
||||
"github.com/alist-org/alist/v3/pkg/utils"
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
|
@ -140,3 +141,13 @@ func UpdateUserBasePathPrefix(oldPath, newPath string) ([]string, error) {
|
|||
|
||||
return modifiedUsernames, nil
|
||||
}
|
||||
|
||||
func CountUsersByRoleAndEnabledExclude(roleID uint, excludeUserID uint) (int64, error) {
|
||||
var count int64
|
||||
jsonValue := fmt.Sprintf("[%d]", roleID)
|
||||
err := db.Model(&model.User{}).
|
||||
Where("disabled = ? AND id != ?", false, excludeUserID).
|
||||
Where("JSON_CONTAINS(role, ?)", jsonValue).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
|
|
@ -96,8 +96,12 @@ func UpdateRole(r *model.Role) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if old.Name == "admin" || old.Name == "guest" {
|
||||
switch old.Name {
|
||||
case "admin":
|
||||
return errs.ErrChangeDefaultRole
|
||||
|
||||
case "guest":
|
||||
r.Name = "guest"
|
||||
}
|
||||
for i := range r.PermissionScopes {
|
||||
r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)
|
||||
|
|
|
@ -136,3 +136,11 @@ func DelUserCache(username string) error {
|
|||
userCache.Del(username)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CountEnabledAdminsExcluding(userID uint) (int64, error) {
|
||||
adminRole, err := GetRoleByName("admin")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return db.CountUsersByRoleAndEnabledExclude(adminRole.ID, userID)
|
||||
}
|
||||
|
|
|
@ -66,9 +66,13 @@ func UpdateRole(c *gin.Context) {
|
|||
common.ErrorResp(c, err, 500, true)
|
||||
return
|
||||
}
|
||||
if role.Name == "admin" || role.Name == "guest" {
|
||||
switch role.Name {
|
||||
case "admin":
|
||||
common.ErrorResp(c, errs.ErrChangeDefaultRole, 403)
|
||||
return
|
||||
|
||||
case "guest":
|
||||
req.Name = "guest"
|
||||
}
|
||||
if err := op.UpdateRole(&req); err != nil {
|
||||
common.ErrorResp(c, err, 500, true)
|
||||
|
|
|
@ -74,9 +74,16 @@ func UpdateUser(c *gin.Context) {
|
|||
if req.OtpSecret == "" {
|
||||
req.OtpSecret = user.OtpSecret
|
||||
}
|
||||
if req.Disabled && req.IsAdmin() {
|
||||
common.ErrorStrResp(c, "admin user can not be disabled", 400)
|
||||
return
|
||||
if req.Disabled && user.IsAdmin() {
|
||||
count, err := op.CountEnabledAdminsExcluding(user.ID)
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
if count == 0 {
|
||||
common.ErrorStrResp(c, "at least one enabled admin must be kept", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := op.UpdateUser(&req); err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
|
|
Loading…
Reference in New Issue