Skip to content
Snippets Groups Projects
userFileSystemStore.go 3.68 KiB
Newer Older
  • Learn to ignore specific revisions
  • package rbac
    
    import (
    	"encoding/json"
    	"io/ioutil"
    	"sync"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
    	"code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors"
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    )
    
    // FileSystemUserStore is the filesystem implementation of the user store
    type FileSystemUserStore struct {
    	fileMutex      sync.Mutex
    	pathToUserFile string
    }
    
    // NewFileSystemUserStore returns a filesystem implementation for a user store.
    func NewFileSystemUserStore() rbac.UserStore {
    	store.EnsureFilesystemStorePathExists(store.UserFilename)
    	return &FileSystemUserStore{
    		fileMutex:      sync.Mutex{},
    		pathToUserFile: store.GetCompletePathToFileStore(store.UserFilename),
    	}
    }
    
    func (s *FileSystemUserStore) readAllUsersFromFile() ([]rbac.LoadedUser, error) {
    	var loadedUsers []rbac.LoadedUser
    	content, err := ioutil.ReadFile(s.pathToUserFile)
    	if err != nil {
    		return nil, err
    	}
    
    	err = json.Unmarshal(content, &loadedUsers)
    	if err != nil {
    		return nil, err
    	}
    
    	return loadedUsers, nil
    }
    
    func (s *FileSystemUserStore) writeAllUsersToFile(users []rbac.LoadedUser) error {
    	serializedData, err := json.Marshal(users)
    	if err != nil {
    		return err
    	}
    
    	err = ioutil.WriteFile(s.pathToUserFile, serializedData, 0600)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Add adds a User to the User store
    func (s *FileSystemUserStore) Add(UserToAdd rbac.User) error {
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	users, err := s.readAllUsersFromFile()
    	if err != nil {
    		return err
    	}
    
    	var loadedUser rbac.LoadedUser
    	loadedUser, err = store.TransformObjectToLoadedObject[rbac.User, rbac.LoadedUser](UserToAdd)
    	if err != nil {
    		return err
    	}
    
    	users = append(users, loadedUser)
    
    	err = s.writeAllUsersToFile(users)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    //Delete deletes a User from the User store
    func (s *FileSystemUserStore) Delete(userToDelete rbac.User) error {
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	users, err := s.readAllUsersFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, user := range users {
    		if user.ID == userToDelete.ID().String() {
    			//remove item from slice
    			users[i] = users[len(users)-1]
    			users = users[:len(users)-1]
    
    			err = s.writeAllUsersToFile(users)
    			if err != nil {
    				return err
    			}
    
    			return nil
    		}
    	}
    
    
    	return &errors.ErrCouldNotDelete{Identifier: userToDelete.ID(), Type: userToDelete, Err: err}
    
    }
    
    //Get takes a Users ID and return the User if found
    func (s *FileSystemUserStore) Get(query store.Query) (rbac.LoadedUser, error) {
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	var user rbac.LoadedUser
    
    	users, err := s.readAllUsersFromFile()
    	if err != nil {
    		return user, err
    	}
    
    	for _, user := range users {
    		if user.ID == query.ID.String() || user.UserName == query.Name {
    			return user, nil
    		}
    	}
    
    	return user, &errors.ErrCouldNotFind{ID: query.ID, Name: query.Name}
    
    }
    
    // GetAll returns all the Users
    func (s *FileSystemUserStore) GetAll() ([]rbac.LoadedUser, error) {
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	Users, err := s.readAllUsersFromFile()
    	return Users, err
    }
    
    //Update updates an exsisting user
    func (s *FileSystemUserStore) Update(userToUpdate rbac.User) error {
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	loadedUser, err := store.TransformObjectToLoadedObject[rbac.User, rbac.LoadedUser](userToUpdate)
    	if err != nil {
    		return err
    	}
    	users, err := s.readAllUsersFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, user := range users {
    		if user.ID == userToUpdate.ID().String() {
    			users[i] = loadedUser
    			err = s.writeAllUsersToFile(users)
    			if err != nil {
    				return err
    			}
    			return nil
    		}
    	}
    
    
    	return &errors.ErrCouldNotUpdate{Identifier: userToUpdate.ID(), Type: userToUpdate, Err: err}