Files
phylum/server/internal/core/fs/find.go
2024-11-01 12:17:22 +05:30

112 lines
2.6 KiB
Go

package fs
import (
"encoding/json"
"strings"
"time"
"github.com/google/uuid"
"github.com/shroff/phylum/server/internal/core/db"
)
func (f filesystem) ResourceByPath(path string) (Resource, error) {
return f.resourceFromResult(f.db.ResourceByPath(f.ctx, db.ResourceByPathParams{Root: &f.rootID, Path: path}))
}
func (f filesystem) ResourceByID(id uuid.UUID) (Resource, error) {
return f.resourceFromResult(f.db.ResourceByID(f.ctx, id))
}
func (f filesystem) resourceFromResult(e []db.PublinkedResource, err error) (Resource, error) {
if len(e) == 0 {
err = ErrResourceNotFound
}
if err != nil {
return Resource{}, err
}
var b strings.Builder
found := false
permission := Permission(0)
ancestry := make([]ResourceInfo, len(e))
for i := len(e) - 1; i >= 0; i-- {
if i != len(e)-1 {
b.WriteByte('/')
b.WriteString(e[i].Name)
}
info := resourceInfoFromDBPublinkedResource(e[i])
if b.Len() == 0 {
info.path = "/"
} else {
info.path = b.String()
}
ancestry[len(e)-i-1] = info
if e[i].ID == f.rootID {
found = true
}
if p, err := readPermissionFromJson(e[i].Permissions, f.username); err != nil {
return Resource{}, err
} else {
permission = permission | p
}
}
if !found || permission&PermissionRead == 0 {
return Resource{}, err
}
return Resource{
f: f,
Ancestry: ancestry,
UserPermission: permission,
}, nil
}
func readPermissionFromJson(j []byte, username string) (Permission, error) {
if len(j) == 2 {
return PermissionNone, nil
}
p := make(map[string]Permission)
err := json.Unmarshal(j, &p)
if err != nil {
return PermissionNone, err
}
if p, ok := p[username]; ok {
return p, nil
}
return PermissionNone, nil
}
func resourceInfoFromDBPublinkedResource(r db.PublinkedResource) ResourceInfo {
var delTime *time.Time
if r.Deleted.Valid {
delTime = &r.Deleted.Time
}
return ResourceInfo{
id: r.ID,
parentID: r.Parent,
name: r.Name,
dir: r.Dir,
created: r.Created.Time,
modified: r.Modified.Time,
deleted: delTime,
contentSize: r.ContentSize,
contentType: r.ContentType,
contentSHA256: r.ContentSha256,
permissions: string(r.Permissions),
publinks: int(r.Publinks),
}
}
func (f filesystem) ResourceByPathOrUUID(pathOrUUID string) (Resource, error) {
if pathOrUUID == "" {
return Resource{}, ErrResourcePathInvalid
}
if pathOrUUID[0] == '/' {
return f.ResourceByPath(pathOrUUID)
}
if id, err := uuid.Parse(pathOrUUID); err != nil {
return Resource{}, err
} else {
return f.ResourceByID(id)
}
}