mirror of https://github.com/Xhofe/alist
				
				
				
			
		
			
				
	
	
		
			137 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
package op
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/Xhofe/go-cache"
 | 
						|
	"github.com/alist-org/alist/v3/internal/db"
 | 
						|
	"github.com/alist-org/alist/v3/internal/errs"
 | 
						|
	"github.com/alist-org/alist/v3/internal/model"
 | 
						|
	"github.com/alist-org/alist/v3/pkg/singleflight"
 | 
						|
	"github.com/alist-org/alist/v3/pkg/utils"
 | 
						|
)
 | 
						|
 | 
						|
var roleCache = cache.NewMemCache[*model.Role](cache.WithShards[*model.Role](2))
 | 
						|
var roleG singleflight.Group[*model.Role]
 | 
						|
 | 
						|
func GetRole(id uint) (*model.Role, error) {
 | 
						|
	key := fmt.Sprint(id)
 | 
						|
	if r, ok := roleCache.Get(key); ok {
 | 
						|
		return r, nil
 | 
						|
	}
 | 
						|
	r, err, _ := roleG.Do(key, func() (*model.Role, error) {
 | 
						|
		_r, err := db.GetRole(id)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
 | 
						|
		return _r, nil
 | 
						|
	})
 | 
						|
	return r, err
 | 
						|
}
 | 
						|
 | 
						|
func GetRoleByName(name string) (*model.Role, error) {
 | 
						|
	if r, ok := roleCache.Get(name); ok {
 | 
						|
		return r, nil
 | 
						|
	}
 | 
						|
	r, err, _ := roleG.Do(name, func() (*model.Role, error) {
 | 
						|
		_r, err := db.GetRoleByName(name)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		roleCache.Set(name, _r, cache.WithEx[*model.Role](time.Hour))
 | 
						|
		return _r, nil
 | 
						|
	})
 | 
						|
	return r, err
 | 
						|
}
 | 
						|
 | 
						|
func GetRolesByUserID(userID uint) ([]model.Role, error) {
 | 
						|
	user, err := GetUserById(userID)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	var roles []model.Role
 | 
						|
	for _, roleID := range user.Role {
 | 
						|
		key := fmt.Sprint(roleID)
 | 
						|
 | 
						|
		if r, ok := roleCache.Get(key); ok {
 | 
						|
			roles = append(roles, *r)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		r, err, _ := roleG.Do(key, func() (*model.Role, error) {
 | 
						|
			_r, err := db.GetRole(uint(roleID))
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			}
 | 
						|
			roleCache.Set(key, _r, cache.WithEx[*model.Role](time.Hour))
 | 
						|
			return _r, nil
 | 
						|
		})
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		roles = append(roles, *r)
 | 
						|
	}
 | 
						|
 | 
						|
	return roles, nil
 | 
						|
}
 | 
						|
 | 
						|
func GetRoles(pageIndex, pageSize int) ([]model.Role, int64, error) {
 | 
						|
	return db.GetRoles(pageIndex, pageSize)
 | 
						|
}
 | 
						|
 | 
						|
func CreateRole(r *model.Role) error {
 | 
						|
	for i := range r.PermissionScopes {
 | 
						|
		r.PermissionScopes[i].Path = utils.FixAndCleanPath(r.PermissionScopes[i].Path)
 | 
						|
	}
 | 
						|
	roleCache.Del(fmt.Sprint(r.ID))
 | 
						|
	roleCache.Del(r.Name)
 | 
						|
	return db.CreateRole(r)
 | 
						|
}
 | 
						|
 | 
						|
func UpdateRole(r *model.Role) error {
 | 
						|
	old, err := db.GetRole(r.ID)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if old.Name == "admin" || old.Name == "guest" {
 | 
						|
		return errs.ErrChangeDefaultRole
 | 
						|
	}
 | 
						|
	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
 | 
						|
		modifiedUsernames, err := db.UpdateUserBasePathPrefix(oldPath, newPath)
 | 
						|
		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)
 | 
						|
}
 | 
						|
 | 
						|
func DeleteRole(id uint) error {
 | 
						|
	old, err := db.GetRole(id)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if old.Name == "admin" || old.Name == "guest" {
 | 
						|
		return errs.ErrChangeDefaultRole
 | 
						|
	}
 | 
						|
	roleCache.Del(fmt.Sprint(id))
 | 
						|
	roleCache.Del(old.Name)
 | 
						|
	return db.DeleteRole(id)
 | 
						|
}
 |