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
	
	 qianshi
						qianshi