Skip to content

Commit

Permalink
permission disk persistence
Browse files Browse the repository at this point in the history
  • Loading branch information
jokil123 committed Jan 14, 2024
1 parent 7d86ff6 commit 4777f2e
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 30 deletions.
2 changes: 2 additions & 0 deletions EsefexApi/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func main() {
Must(err)

fpdb, err := filepermisssiondb.NewFilePermissionDB(cfg.Database.Permissiondblocation)
Must(err)

verT := time.Duration(cfg.VerificationExpiry * float32(time.Minute))
ldb := memorylinktokenstore.NewMemoryLinkTokenStore(verT)
Expand Down Expand Up @@ -76,6 +77,7 @@ func main() {
<-plr.Stop()

udb.Close()
fpdb.Close()

log.Println("All components stopped, exiting...")
}()
Expand Down
76 changes: 56 additions & 20 deletions EsefexApi/permissiondb/filepermisssiondb/filepermisssiondb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"esefexapi/permissiondb"
"esefexapi/permissions"
"esefexapi/util"
"log"
"os"
"sync"

Expand All @@ -13,49 +15,83 @@ import (
var _ permissiondb.PermissionDB = &FilePermissionDB{}

type FilePermissionDB struct {
filePath string
rw *sync.RWMutex
stack *permissions.PermissionStack
file *os.File
rw *sync.RWMutex
stack permissions.PermissionStack
}

func NewFilePermissionDB(path string) (*FilePermissionDB, error) {
log.Printf("Creating FileDB at %s", path)
file, err := util.EnsureFile(path)
if err != nil {
return nil, errors.Wrap(err, "Error ensuring file")
}

fpdb := &FilePermissionDB{
filePath: path,
rw: &sync.RWMutex{},
stack: permissions.NewPermissionStack(),
file: file,
rw: &sync.RWMutex{},
stack: permissions.NewPermissionStack(),
}
err := fpdb.load()
return fpdb, err
err = fpdb.load()
if err != nil {
return nil, errors.Wrap(err, "Error loading permission stack")
}

return fpdb, nil
}

// load loads the permission stack from the file.
func (f *FilePermissionDB) load() error {
file, err := os.Open(f.filePath)
f.rw.Lock()
defer f.rw.Unlock()

// reset file
_, err := f.file.Seek(0, 0)
if err != nil {
return errors.Wrap(err, "Error opening file")
return errors.Wrap(err, "Error seeking to start of file")
}
defer file.Close()

err = json.NewDecoder(file).Decode(f.stack)
// read file
var perms permissions.PermissionStack
err = json.NewDecoder(f.file).Decode(&perms)
if err != nil {
return errors.Wrap(err, "Error decoding permission stack")
log.Printf("Error decoding file, creating empty permission stack: (%v)", err)
f.stack = permissions.NewPermissionStack()
} else {
f.stack = perms
}

return nil
}

func (f *FilePermissionDB) Close() error {
f.rw.Lock()
defer f.rw.Unlock()
log.Println("Closing file permissiondb")

err := f.save()
if err != nil {
return errors.Wrap(err, "Error saving permissiondb")
}
return f.file.Close()
}

// save saves the permission stack to the file.
// TODO: Make this work
func (f *FilePermissionDB) save() error {
file, err := os.OpenFile(f.filePath, os.O_RDWR|os.O_CREATE, os.ModePerm)
// It assumes that the lock is already held.
func (f FilePermissionDB) save() error {
// reset file
_, err := f.file.Seek(0, 0)
if err != nil {
return errors.Wrap(err, "Error seeking to start of file")
}
err = f.file.Truncate(0)
if err != nil {
return errors.Wrap(err, "Error opening file")
return errors.Wrap(err, "Error truncating file")
}
defer file.Close()

err = json.NewEncoder(file).Encode(f.stack)
err = json.NewEncoder(f.file).Encode(f.stack)
if err != nil {
return errors.Wrap(err, "Error encoding permission stack")
return errors.Wrap(err, "Error encoding file")
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions EsefexApi/permissions/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type PermissionStack struct {
Channel map[types.ChannelID]Permissions
}

func NewPermissionStack() *PermissionStack {
return &PermissionStack{
func NewPermissionStack() PermissionStack {
return PermissionStack{
User: make(map[types.UserID]Permissions),
Role: make(map[types.RoleID]Permissions),
Channel: make(map[types.ChannelID]Permissions),
Expand Down
7 changes: 2 additions & 5 deletions EsefexApi/userdb/fileuserdb/fileuserdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,14 @@ func NewFileUserDB(filePath string) (*FileUserDB, error) {
func (f *FileUserDB) Close() error {
log.Println("Closing userdb")

err := f.Save()
err := f.save()
if err != nil {
return errors.Wrap(err, "Error saving userdb")
}
return f.file.Close()
}

func (f *FileUserDB) Save() error {
f.fileLock.Lock()
defer f.fileLock.Unlock()

func (f FileUserDB) save() error {
// reset file
_, err := f.file.Seek(0, 0)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions EsefexApi/userdb/fileuserdb/impluserdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (f *FileUserDB) SetUser(user userdb.User) error {
f.Users[user.ID] = user

go func() {
err := f.Save()
err := f.save()
if err != nil {
log.Printf("Error saving userdb: %+v", err)
}
Expand All @@ -40,7 +40,7 @@ func (f *FileUserDB) DeleteUser(userID types.UserID) error {
delete(f.Users, userID)

go func() {
err := f.Save()
err := f.save()
if err != nil {
log.Printf("Error saving userdb: %+v", err)
}
Expand Down Expand Up @@ -87,7 +87,7 @@ func (f *FileUserDB) NewToken(userID types.UserID) (userdb.Token, error) {
log.Printf("%v", f)

go func() {
err := f.Save()
err := f.save()
if err != nil {
log.Printf("Error saving userdb: %+v", err)
}
Expand Down
16 changes: 16 additions & 0 deletions EsefexApi/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"fmt"
"math/rand"
"os"
"path"
"regexp"
"strings"

"github.com/bwmarrin/discordgo"
"github.com/pkg/errors"
"github.com/samber/lo"
)

Expand Down Expand Up @@ -58,3 +60,17 @@ func RandomString(charset []rune, length int) string {

return string(str)
}

func EnsureFile(p string) (*os.File, error) {
err := os.MkdirAll(path.Dir(p), os.ModePerm)
if err != nil {
return nil, errors.Wrap(err, "Error creating directory")
}

file, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
return nil, errors.Wrap(err, "Error opening file")
}

return file, nil
}

0 comments on commit 4777f2e

Please sign in to comment.