Skip to content
Snippets Groups Projects
roleFileSystemStore.go 3.88 KiB
Newer Older
  • Learn to ignore specific revisions
  • package rbac
    
    import (
    
    	"context"
    
    	"encoding/json"
    
    Andre Sterba's avatar
    Andre Sterba committed
    	"os"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    
    // FileSystemRoleStore is the filesystem implementation of the role store.
    
    type FileSystemRoleStore struct {
    	fileMutex      sync.Mutex
    	pathToRoleFile string
    }
    
    // NewFileSystemRoleStore returns a filesystem implementation for a role store.
    func NewFileSystemRoleStore() rbac.RoleStore {
    
    	if err := store.EnsureFilesystemStorePathExists(store.RoleFilename); err != nil {
    		log.Error(err)
    	}
    
    
    	return &FileSystemRoleStore{
    		fileMutex:      sync.Mutex{},
    		pathToRoleFile: store.GetCompletePathToFileStore(store.RoleFilename),
    	}
    }
    
    func (s *FileSystemRoleStore) readAllRolesFromFile() ([]rbac.LoadedRole, error) {
    	var loadedRoles []rbac.LoadedRole
    
    Andre Sterba's avatar
    Andre Sterba committed
    	content, err := os.ReadFile(s.pathToRoleFile)
    
    	if err != nil {
    		return nil, err
    	}
    
    	err = json.Unmarshal(content, &loadedRoles)
    	if err != nil {
    		return nil, err
    	}
    
    	return loadedRoles, nil
    }
    
    
    func (s *FileSystemRoleStore) writeAllRolesToFile(roles []rbac.LoadedRole) error {
    	serializedData, err := json.Marshal(roles)
    
    	if err != nil {
    		return err
    	}
    
    
    Andre Sterba's avatar
    Andre Sterba committed
    	err = os.WriteFile(s.pathToRoleFile, serializedData, 0600)
    
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    
    // Add adds a Role to the Role store.
    
    func (s *FileSystemRoleStore) Add(ctx context.Context, roleToAdd rbac.Role) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	roles, err := s.readAllRolesFromFile()
    	if err != nil {
    		return err
    	}
    
    	var loadedRole rbac.LoadedRole
    
    	loadedRole, err = store.TransformObjectToLoadedObject[rbac.Role, rbac.LoadedRole](roleToAdd)
    
    	if err != nil {
    		return err
    	}
    
    	roles = append(roles, loadedRole)
    
    	err = s.writeAllRolesToFile(roles)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    
    Andre Sterba's avatar
    Andre Sterba committed
    // Delete deletes a Role from the Role store.
    
    func (s *FileSystemRoleStore) Delete(ctx context.Context, roleToDelete rbac.Role) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	roles, err := s.readAllRolesFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, role := range roles {
    
    		if role.ID == roleToDelete.ID().String() {
    
    			//remove item from slice
    			roles[i] = roles[len(roles)-1]
    			roles = roles[:len(roles)-1]
    
    			err = s.writeAllRolesToFile(roles)
    			if err != nil {
    				return err
    			}
    
    			return nil
    		}
    	}
    
    
    	return &customerrs.CouldNotDeleteError{Identifier: roleToDelete.ID(), Type: roleToDelete, Err: err}
    
    Andre Sterba's avatar
    Andre Sterba committed
    // Get takes a Roles ID and return the Role if found.
    
    func (s *FileSystemRoleStore) Get(ctx context.Context, query store.Query) (rbac.LoadedRole, error) {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	var role rbac.LoadedRole
    	roles, err := s.readAllRolesFromFile()
    	if err != nil {
    		return role, err
    	}
    
    	for _, role := range roles {
    		if role.ID == query.ID.String() || role.RoleName == query.Name {
    			return role, nil
    		}
    	}
    
    
    	return role, &customerrs.CouldNotFindError{ID: query.ID, Name: query.Name}
    
    func (s *FileSystemRoleStore) GetAll(ctx context.Context) ([]rbac.LoadedRole, error) {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	Roles, err := s.readAllRolesFromFile()
    	return Roles, err
    }
    
    
    Andre Sterba's avatar
    Andre Sterba committed
    // Update updates an exsisting Role.
    
    func (s *FileSystemRoleStore) Update(ctx context.Context, roleToUpdate rbac.Role) error {
    
    	s.fileMutex.Lock()
    	defer s.fileMutex.Unlock()
    
    	loadedRole, err := store.TransformObjectToLoadedObject[rbac.Role, rbac.LoadedRole](roleToUpdate)
    	if err != nil {
    		return err
    	}
    	Roles, err := s.readAllRolesFromFile()
    	if err != nil {
    		return err
    	}
    
    	for i, Role := range Roles {
    		if Role.ID == roleToUpdate.ID().String() {
    			Roles[i] = loadedRole
    			err = s.writeAllRolesToFile(Roles)
    			if err != nil {
    				return err
    			}
    			return nil
    		}
    	}
    
    
    	return &customerrs.CouldNotUpdateError{Identifier: roleToUpdate.ID(), Type: roleToUpdate, Err: err}