mirror of https://github.com/Xhofe/alist
feat: Check usage before deleting storage (#9322)
* feat(storage): Added role and user path checking functionality - Added `GetAllRoles` function to retrieve all roles - Added `GetAllUsers` function to retrieve all users - Added `firstPathSegment` function to extract the first segment of a path - Checks whether a storage object is used by a role or user, and returns relevant information for unusing it * fix(storage): Fixed a potential null value issue with not checking firstMount. - Added a check to see if `firstMount` is null to prevent logic errors. - Adjusted the loading logic of `GetAllRoles` and `GetAllUsers` to only execute when `firstMount` is non-null. - Fixed the `usedBy` check logic to ensure that an error message is returned under the correct conditions. - Optimized code structure to reduce unnecessary execution paths.pull/9292/merge v3.53.0
parent
16cce37947
commit
e1800f18e4
|
@ -34,6 +34,14 @@ func GetRoles(pageIndex, pageSize int) (roles []model.Role, count int64, err err
|
||||||
return roles, count, nil
|
return roles, count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAllRoles() ([]model.Role, error) {
|
||||||
|
var roles []model.Role
|
||||||
|
if err := db.Find(&roles).Error; err != nil {
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
return roles, nil
|
||||||
|
}
|
||||||
|
|
||||||
func CreateRole(r *model.Role) error {
|
func CreateRole(r *model.Role) error {
|
||||||
if err := db.Create(r).Error; err != nil {
|
if err := db.Create(r).Error; err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
|
|
|
@ -83,6 +83,14 @@ func GetUsers(pageIndex, pageSize int) (users []model.User, count int64, err err
|
||||||
return users, count, nil
|
return users, count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAllUsers() ([]model.User, error) {
|
||||||
|
var users []model.User
|
||||||
|
if err := db.Find(&users).Error; err != nil {
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteUserById(id uint) error {
|
func DeleteUserById(id uint) error {
|
||||||
return errors.WithStack(db.Delete(&model.User{}, id).Error)
|
return errors.WithStack(db.Delete(&model.User{}, id).Error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,18 @@ func GetStorageByMountPath(mountPath string) (driver.Driver, error) {
|
||||||
return storageDriver, nil
|
return storageDriver, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func firstPathSegment(p string) string {
|
||||||
|
p = utils.FixAndCleanPath(p)
|
||||||
|
p = strings.TrimPrefix(p, "/")
|
||||||
|
if p == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if i := strings.Index(p, "/"); i >= 0 {
|
||||||
|
return p[:i]
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
// CreateStorage Save the storage to database so storage can get an id
|
// CreateStorage Save the storage to database so storage can get an id
|
||||||
// then instantiate corresponding driver and save it in memory
|
// then instantiate corresponding driver and save it in memory
|
||||||
func CreateStorage(ctx context.Context, storage model.Storage) (uint, error) {
|
func CreateStorage(ctx context.Context, storage model.Storage) (uint, error) {
|
||||||
|
@ -267,6 +279,34 @@ func DeleteStorageById(ctx context.Context, id uint) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithMessage(err, "failed get storage")
|
return errors.WithMessage(err, "failed get storage")
|
||||||
}
|
}
|
||||||
|
firstMount := firstPathSegment(storage.MountPath)
|
||||||
|
if firstMount != "" {
|
||||||
|
roles, err := db.GetAllRoles()
|
||||||
|
if err != nil {
|
||||||
|
return errors.WithMessage(err, "failed to load roles")
|
||||||
|
}
|
||||||
|
users, err := db.GetAllUsers()
|
||||||
|
if err != nil {
|
||||||
|
return errors.WithMessage(err, "failed to load users")
|
||||||
|
}
|
||||||
|
var usedBy []string
|
||||||
|
for _, r := range roles {
|
||||||
|
for _, entry := range r.PermissionScopes {
|
||||||
|
if firstPathSegment(entry.Path) == firstMount {
|
||||||
|
usedBy = append(usedBy, "role:"+r.Name)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, u := range users {
|
||||||
|
if firstPathSegment(u.BasePath) == firstMount {
|
||||||
|
usedBy = append(usedBy, "user:"+u.Username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(usedBy) > 0 {
|
||||||
|
return errors.Errorf("storage is used by %s, please cancel usage first", strings.Join(usedBy, ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
if !storage.Disabled {
|
if !storage.Disabled {
|
||||||
storageDriver, err := GetStorageByMountPath(storage.MountPath)
|
storageDriver, err := GetStorageByMountPath(storage.MountPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue