-
Fabian Seidl authoredFabian Seidl authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
roleFileSystemStore.go 3.66 KiB
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"
)
// 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 {
store.EnsureFilesystemStorePathExists(store.RoleFilename)
return &FileSystemRoleStore{
fileMutex: sync.Mutex{},
pathToRoleFile: store.GetCompletePathToFileStore(store.RoleFilename),
}
}
func (s *FileSystemRoleStore) readAllRolesFromFile() ([]rbac.LoadedRole, error) {
var loadedRoles []rbac.LoadedRole
content, err := ioutil.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
}
err = ioutil.WriteFile(s.pathToRoleFile, serializedData, 0600)
if err != nil {
return err
}
return nil
}
// Add adds a Role to the Role store
func (s *FileSystemRoleStore) Add(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
}
//Delete deletes a Role from the Role store
func (s *FileSystemRoleStore) Delete(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 &errors.ErrCouldNotFind{ID: RoleToDelete.ID(), Name: RoleToDelete.Name()}
}
//Get takes a Roles ID and return the Role if found
func (s *FileSystemRoleStore) Get(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, &errors.ErrCouldNotFind{ID: query.ID, Name: query.Name}
}
// GetAll returns all the Roles
func (s *FileSystemRoleStore) GetAll() ([]rbac.LoadedRole, error) {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
Roles, err := s.readAllRolesFromFile()
return Roles, err
}
//Update updates an exsisting Role
func (s *FileSystemRoleStore) Update(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 &errors.ErrCouldNotFind{ID: roleToUpdate.ID(), Name: roleToUpdate.Name()}
}