feat(user-db): enhance user management with role-based queries (allow-edit-role-guest) (#9234)

- Add `GetUsersByRole` function to fetch users based on their roles.
- Extend `UpdateUserBasePathPrefix` to accept optional user lists.
- Ensure path cleaning in `UpdateUserBasePathPrefix` for consistency.
- Integrate guest role fetching in `auth.go` middleware.
- Utilize `GetUsersByRole` in `role.go` for base path modifications.
- Remove redundant line in `role.go` role modification logic.
main v3.47.1
千石 2025-07-30 13:15:35 +08:00 committed by GitHub
parent 74332e91fb
commit 280960ce3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 9 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/pkg/errors"
"gorm.io/gorm"
"path"
"slices"
"strings"
)
@ -25,6 +26,20 @@ func GetUserByRole(role int) (*model.User, error) {
return nil, gorm.ErrRecordNotFound
}
func GetUsersByRole(roleID int) ([]model.User, error) {
var users []model.User
if err := db.Find(&users).Error; err != nil {
return nil, err
}
var result []model.User
for _, u := range users {
if slices.Contains(u.Role, roleID) {
result = append(result, u)
}
}
return result, nil
}
func GetUserByName(username string) (*model.User, error) {
user := model.User{Username: username}
if err := db.Where(user).First(&user).Error; err != nil {
@ -109,25 +124,29 @@ func RemoveAuthn(u *model.User, id string) error {
return UpdateAuthn(u.ID, string(res))
}
func UpdateUserBasePathPrefix(oldPath, newPath string) ([]string, error) {
func UpdateUserBasePathPrefix(oldPath, newPath string, usersOpt ...[]model.User) ([]string, error) {
var users []model.User
var modifiedUsernames []string
if err := db.Find(&users).Error; err != nil {
return nil, errors.WithMessage(err, "failed to load users")
}
oldPathClean := path.Clean(oldPath)
if len(usersOpt) > 0 {
users = usersOpt[0]
} else {
if err := db.Find(&users).Error; err != nil {
return nil, errors.WithMessage(err, "failed to load users")
}
}
for _, user := range users {
basePath := path.Clean(user.BasePath)
updated := false
if basePath == oldPathClean {
user.BasePath = newPath
user.BasePath = path.Clean(newPath)
updated = true
} else if strings.HasPrefix(basePath, oldPathClean+"/") {
user.BasePath = newPath + basePath[len(oldPathClean):]
user.BasePath = path.Clean(newPath + basePath[len(oldPathClean):])
updated = true
}

View File

@ -100,7 +100,6 @@ func UpdateRole(r *model.Role) error {
switch old.Name {
case "admin":
return errs.ErrChangeDefaultRole
case "guest":
r.Name = "guest"
}
@ -112,7 +111,13 @@ func UpdateRole(r *model.Role) error {
oldPath := old.PermissionScopes[0].Path
newPath := r.PermissionScopes[0].Path
modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldPath, newPath)
users, err := db.GetUsersByRole(int(r.ID))
if err != nil {
return errors.WithMessage(err, "failed to get users by role")
}
modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldPath, newPath, users)
if err != nil {
return errors.WithMessage(err, "failed to update user base path when role updated")
}

View File

@ -41,6 +41,15 @@ func Auth(c *gin.Context) {
c.Abort()
return
}
if len(guest.Role) > 0 {
roles, err := op.GetRolesByUserID(guest.ID)
if err != nil {
common.ErrorStrResp(c, fmt.Sprintf("Fail to load guest roles: %v", err), 500)
c.Abort()
return
}
guest.RolesDetail = roles
}
c.Set("user", guest)
log.Debugf("use empty token: %+v", guest)
c.Next()