mirror of https://github.com/Xhofe/alist
feat(user): enhance path management and role handling (#9249)
- Add `GetUsersByRole` function for fetching users by role. - Introduce `GetAllBasePathsFromRoles` to aggregate paths from roles. - Refine path handling in `pkg/utils/path.go` for normalization. - Comment out base path prefix updates to simplify role operations.main beta
parent
85fe4e5bb3
commit
6b2d81eede
|
@ -149,9 +149,21 @@ func (u *User) JoinPath(reqPath string) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if u.CheckPathLimit() && !utils.IsSubPath(u.BasePath, path) {
|
||||
return "", errs.PermissionDenied
|
||||
|
||||
if u.CheckPathLimit() {
|
||||
basePaths := GetAllBasePathsFromRoles(u)
|
||||
match := false
|
||||
for _, base := range basePaths {
|
||||
if utils.IsSubPath(base, path) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
return "", errs.PermissionDenied
|
||||
}
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
|
@ -193,3 +205,22 @@ func (u *User) WebAuthnCredentials() []webauthn.Credential {
|
|||
func (u *User) WebAuthnIcon() string {
|
||||
return "https://alistgo.com/logo.svg"
|
||||
}
|
||||
|
||||
// GetAllBasePathsFromRoles returns all permission paths from user's roles
|
||||
func GetAllBasePathsFromRoles(u *User) []string {
|
||||
basePaths := make([]string, 0)
|
||||
seen := make(map[string]struct{})
|
||||
|
||||
for _, role := range u.RolesDetail {
|
||||
for _, entry := range role.PermissionScopes {
|
||||
if entry.Path == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[entry.Path]; !ok {
|
||||
basePaths = append(basePaths, entry.Path)
|
||||
seen[entry.Path] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return basePaths
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package op
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
|
||||
"github.com/Xhofe/go-cache"
|
||||
|
@ -106,26 +105,26 @@ func UpdateRole(r *model.Role) error {
|
|||
for i := range r.PermissionScopes {
|
||||
r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)
|
||||
}
|
||||
if len(old.PermissionScopes) > 0 && len(r.PermissionScopes) > 0 &&
|
||||
old.PermissionScopes[0].Path != r.PermissionScopes[0].Path {
|
||||
|
||||
oldPath := old.PermissionScopes[0].Path
|
||||
newPath := r.PermissionScopes[0].Path
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
for _, name := range modifiedUsernames {
|
||||
userCache.Del(name)
|
||||
}
|
||||
}
|
||||
//if len(old.PermissionScopes) > 0 && len(r.PermissionScopes) > 0 &&
|
||||
// old.PermissionScopes[0].Path != r.PermissionScopes[0].Path {
|
||||
//
|
||||
// oldPath := old.PermissionScopes[0].Path
|
||||
// newPath := r.PermissionScopes[0].Path
|
||||
//
|
||||
// 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")
|
||||
// }
|
||||
//
|
||||
// for _, name := range modifiedUsernames {
|
||||
// userCache.Del(name)
|
||||
// }
|
||||
//}
|
||||
roleCache.Del(fmt.Sprint(r.ID))
|
||||
roleCache.Del(r.Name)
|
||||
return db.UpdateRole(r)
|
||||
|
|
|
@ -232,12 +232,20 @@ func UpdateStorage(ctx context.Context, storage model.Storage) error {
|
|||
roleCache.Del(fmt.Sprint(id))
|
||||
}
|
||||
|
||||
modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldStorage.MountPath, storage.MountPath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed to update user base path")
|
||||
}
|
||||
for _, name := range modifiedUsernames {
|
||||
userCache.Del(name)
|
||||
//modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldStorage.MountPath, storage.MountPath)
|
||||
//if err != nil {
|
||||
// return errors.WithMessage(err, "failed to update user base path")
|
||||
//}
|
||||
for _, id := range modifiedRoleIDs {
|
||||
roleCache.Del(fmt.Sprint(id))
|
||||
|
||||
users, err := db.GetUsersByRole(int(id))
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed to get users by role")
|
||||
}
|
||||
for _, user := range users {
|
||||
userCache.Del(user.Username)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
@ -50,6 +50,10 @@ func GetUserByRole(role int) (*model.User, error) {
|
|||
return db.GetUserByRole(role)
|
||||
}
|
||||
|
||||
func GetUsersByRole(role int) ([]model.User, error) {
|
||||
return db.GetUsersByRole(role)
|
||||
}
|
||||
|
||||
func GetUserByName(username string) (*model.User, error) {
|
||||
if username == "" {
|
||||
return nil, errs.EmptyUsername
|
||||
|
@ -124,17 +128,17 @@ func UpdateUser(u *model.User) error {
|
|||
}
|
||||
userCache.Del(old.Username)
|
||||
u.BasePath = utils.FixAndCleanPath(u.BasePath)
|
||||
if len(u.Role) > 0 {
|
||||
roles, err := GetRolesByUserID(u.ID)
|
||||
if err == nil {
|
||||
for _, role := range roles {
|
||||
if len(role.PermissionScopes) > 0 {
|
||||
u.BasePath = utils.FixAndCleanPath(role.PermissionScopes[0].Path)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if len(u.Role) > 0 {
|
||||
// roles, err := GetRolesByUserID(u.ID)
|
||||
// if err == nil {
|
||||
// for _, role := range roles {
|
||||
// if len(role.PermissionScopes) > 0 {
|
||||
// u.BasePath = utils.FixAndCleanPath(role.PermissionScopes[0].Path)
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
return db.UpdateUser(u)
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,13 @@ func JoinBasePath(basePath, reqPath string) (string, error) {
|
|||
strings.Contains(reqPath, "/../") {
|
||||
return "", errs.RelativePath
|
||||
}
|
||||
|
||||
reqPath = FixAndCleanPath(reqPath)
|
||||
|
||||
if strings.HasPrefix(reqPath, "/") {
|
||||
return reqPath, nil
|
||||
}
|
||||
|
||||
return stdpath.Join(FixAndCleanPath(basePath), FixAndCleanPath(reqPath)), nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue