Files
phylum/server/internal/core/filesystem.go
2025-07-12 16:34:10 +05:30

109 lines
2.5 KiB
Go

package core
import (
"strings"
"codeberg.org/shroff/phylum/server/internal/db"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
type FileSystem struct {
db db.Handler
pathRoot pgtype.UUID
userID int32
userPermissions UserPermissions
scopes []string
scopePermissions Permission
}
type txFileSystem struct {
*FileSystem
db db.TxHandler
}
func OpenFileSystem(db db.Handler, pathRoot pgtype.UUID, userID int32, userPermissions UserPermissions, scopes []string) *FileSystem {
return &FileSystem{
db: db,
pathRoot: pathRoot,
userID: userID,
userPermissions: userPermissions,
scopes: scopes,
scopePermissions: getScopePermissions(scopes, pathRoot.Bytes),
}
}
func getScopePermissions(scopes []string, id uuid.UUID) (p Permission) {
idString := id.String()
for _, s := range scopes {
if s == "" || s == "*" {
return PermissionSU
}
parts := strings.Split(s, ":")
if parts[0] == "*" || parts[0] == idString {
if len(parts) == 1 || parts[1] == "*" {
return PermissionSU
} else if parts[1] == "read" {
p |= PermissionRead
} else if parts[1] == "write" {
p |= PermissionWrite
} else if parts[1] == "share" {
p |= PermissionShare
}
}
}
return p
}
func OpenSUFileSystem(db db.Handler) *FileSystem {
return &FileSystem{
db: db,
pathRoot: fsPathRoot,
userID: -1,
userPermissions: -1,
scopes: []string{"*"},
scopePermissions: -1,
}
}
func openSUFileSystemTx(db db.TxHandler) txFileSystem {
return txFileSystem{
FileSystem: OpenSUFileSystem(db),
db: db,
}
}
func (f *FileSystem) runInTx(fn func(f txFileSystem) error) error {
return f.db.RunInTx(func(tx db.TxHandler) error {
return fn(txFileSystem{
FileSystem: f,
db: tx,
})
})
}
func (f *FileSystem) withPathRoot(pathRoot pgtype.UUID) *FileSystem {
return &FileSystem{
db: f.db,
pathRoot: pathRoot,
userID: f.userID,
userPermissions: f.userPermissions,
scopes: f.scopes,
scopePermissions: getScopePermissions(f.scopes, pathRoot.Bytes),
}
}
func (f *FileSystem) checkPermission(r Resource, p Permission) error {
if f.userPermissions&PermissionFilesAll != 0 {
return nil
}
if up, err := readPermissionFromJson(r.permissions, f.userID); err != nil {
return err
} else if (up&p == 0) || (f.scopePermissions&p == 0) {
return ErrInsufficientPermissions
}
return nil
}