134 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
package users
 | 
						|
 | 
						|
import (
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/filebrowser/filebrowser/v2/errors"
 | 
						|
)
 | 
						|
 | 
						|
// StorageBackend is the interface to implement for a users storage.
 | 
						|
type StorageBackend interface {
 | 
						|
	GetBy(interface{}) (*User, error)
 | 
						|
	Gets() ([]*User, error)
 | 
						|
	Save(u *User) error
 | 
						|
	Update(u *User, fields ...string) error
 | 
						|
	DeleteByID(uint) error
 | 
						|
	DeleteByUsername(string) error
 | 
						|
}
 | 
						|
 | 
						|
type Store interface {
 | 
						|
	Get(baseScope string, id interface{}) (user *User, err error)
 | 
						|
	Gets(baseScope string) ([]*User, error)
 | 
						|
	Update(user *User, fields ...string) error
 | 
						|
	Save(user *User) error
 | 
						|
	Delete(id interface{}) error
 | 
						|
	LastUpdate(id uint) int64
 | 
						|
}
 | 
						|
 | 
						|
// Storage is a users storage.
 | 
						|
type Storage struct {
 | 
						|
	back    StorageBackend
 | 
						|
	updated map[uint]int64
 | 
						|
	mux     sync.RWMutex
 | 
						|
}
 | 
						|
 | 
						|
// NewStorage creates a users storage from a backend.
 | 
						|
func NewStorage(back StorageBackend) *Storage {
 | 
						|
	return &Storage{
 | 
						|
		back:    back,
 | 
						|
		updated: map[uint]int64{},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Get allows you to get a user by its name or username. The provided
 | 
						|
// id must be a string for username lookup or a uint for id lookup. If id
 | 
						|
// is neither, a ErrInvalidDataType will be returned.
 | 
						|
func (s *Storage) Get(baseScope string, id interface{}) (user *User, err error) {
 | 
						|
	user, err = s.back.GetBy(id)
 | 
						|
	if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if err := user.Clean(baseScope); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// Gets gets a list of all users.
 | 
						|
func (s *Storage) Gets(baseScope string) ([]*User, error) {
 | 
						|
	users, err := s.back.Gets()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	for _, user := range users {
 | 
						|
		if err := user.Clean(baseScope); err != nil { //nolint:govet
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return users, err
 | 
						|
}
 | 
						|
 | 
						|
// Update updates a user in the database.
 | 
						|
func (s *Storage) Update(user *User, fields ...string) error {
 | 
						|
	err := user.Clean("", fields...)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.back.Update(user, fields...)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	s.mux.Lock()
 | 
						|
	s.updated[user.ID] = time.Now().Unix()
 | 
						|
	s.mux.Unlock()
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Save saves the user in a storage.
 | 
						|
func (s *Storage) Save(user *User) error {
 | 
						|
	if err := user.Clean(""); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return s.back.Save(user)
 | 
						|
}
 | 
						|
 | 
						|
// Delete allows you to delete a user by its name or username. The provided
 | 
						|
// id must be a string for username lookup or a uint for id lookup. If id
 | 
						|
// is neither, a ErrInvalidDataType will be returned.
 | 
						|
func (s *Storage) Delete(id interface{}) error {
 | 
						|
	switch id := id.(type) {
 | 
						|
	case string:
 | 
						|
		user, err := s.back.GetBy(id)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		if user.ID == 1 {
 | 
						|
			return errors.ErrRootUserDeletion
 | 
						|
		}
 | 
						|
		return s.back.DeleteByUsername(id)
 | 
						|
	case uint:
 | 
						|
		if id == 1 {
 | 
						|
			return errors.ErrRootUserDeletion
 | 
						|
		}
 | 
						|
		return s.back.DeleteByID(id)
 | 
						|
	default:
 | 
						|
		return errors.ErrInvalidDataType
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// LastUpdate gets the timestamp for the last update of an user.
 | 
						|
func (s *Storage) LastUpdate(id uint) int64 {
 | 
						|
	s.mux.RLock()
 | 
						|
	defer s.mux.RUnlock()
 | 
						|
	if val, ok := s.updated[id]; ok {
 | 
						|
		return val
 | 
						|
	}
 | 
						|
	return 0
 | 
						|
}
 |