[server] Split fs.ResourceInfo out of fs.Resource

This commit is contained in:
Abhishek Shroff
2024-11-01 11:52:56 +05:30
parent 3ee89e1e27
commit 260fac2952
29 changed files with 330 additions and 216 deletions
+55 -38
View File
@@ -16,7 +16,7 @@ func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
}
// Check source directory permissions
parent, err := r.f.ResourceByID(*r.ParentID)
parent, err := r.f.ResourceByID(*r.ParentID())
if err != nil {
return Resource{}, false, err
}
@@ -35,8 +35,14 @@ func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
if !destParent.hasPermission(PermissionWrite) {
return Resource{}, false, ErrInsufficientPermissions
}
if res, err := r.f.db.ResourceByID(r.f.ctx, db.ResourceByIDParams{Root: r.ID, ResourceID: destParent.ID, Username: r.f.username}); err != nil || res.Found {
return Resource{}, false, ErrResourceMoveTargetSubdirectory
if res, err := r.f.db.ResourceByID(r.f.ctx, destParent.ID()); err != nil {
return Resource{}, false, err
} else {
for i := 1; i < len(res); i++ {
if res[i].ID == r.ID() {
return Resource{}, false, ErrResourceMoveTargetSubdirectory
}
}
}
var deleted = false
@@ -49,14 +55,14 @@ func (r Resource) Move(target string, overwrite bool) (Resource, bool, error) {
return err
}
}
if nameParent, err := f.db.UpdateResourceNameParent(f.ctx, db.UpdateResourceNameParentParams{ID: r.ID, Name: destName, Parent: destParent.ID}); err != nil {
if nameParent, err := f.db.UpdateResourceNameParent(f.ctx, db.UpdateResourceNameParentParams{ID: r.ID(), Name: destName, Parent: destParent.ID()}); err != nil {
if strings.Contains(err.Error(), "unique_member_resource_name") {
return ErrResourceNameConflict
}
return err
} else {
r.Name = nameParent.Name
r.ParentID = nameParent.Parent
r.Ancestry[0].Name = nameParent.Name
r.Ancestry[0].ParentID = nameParent.Parent
return nil
}
})
@@ -76,7 +82,7 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
}
return Resource{}, false, err
}
if !destParent.Dir {
if !destParent.FSDir() {
return Resource{}, false, ErrResourceNotCollection
}
@@ -84,35 +90,35 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
return Resource{}, false, ErrInsufficientPermissions
}
var tree []db.ResourceResult
if recursive && r.Dir {
var tree []db.PublinkedResource
if recursive && r.FSDir() {
var err error
tree, err = r.f.db.ReadDir(r.f.ctx, db.ReadDirParams{ResourceID: r.ID, Path: r.Path, MinDepth: 1, MaxDepth: 1000})
tree, err = r.f.db.ReadDir(r.f.ctx, db.ReadDirParams{ResourceID: r.ID(), MinDepth: 1, MaxDepth: 1000})
if err != nil {
return Resource{}, false, err
}
}
create := make([]db.CreateResourcesParams, 0, len(tree)+1)
copy := make(map[uuid.UUID]uuid.UUID)
ids := make(map[string]uuid.UUID)
if r.Dir {
ids[""] = id
contents := make(map[uuid.UUID]uuid.UUID)
ids := make(map[uuid.UUID]uuid.UUID)
if r.FSDir() {
ids[r.ID()] = id
} else {
copy[r.ID] = id
contents[r.ID()] = id
}
create = append(create, db.CreateResourcesParams{
ID: id,
Parent: destParent.ID,
Parent: destParent.ID(),
Name: destName,
Dir: r.Dir,
ContentSize: r.ContentSize,
ContentType: r.ContentType,
ContentSha256: r.ContentSHA256,
Dir: r.FSDir(),
ContentSize: r.FSContentSize(),
ContentType: r.FSContentType(),
ContentSha256: r.FSContentSHA256(),
})
for _, src := range tree {
id, _ := uuid.NewUUID()
parent := ids[src.Path[0:strings.LastIndex(src.Path, "/")]]
parent := ids[*src.Parent]
create = append(create, db.CreateResourcesParams{
ID: id,
@@ -125,9 +131,9 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
})
if src.Dir {
ids[src.Path] = id
ids[src.ID] = id
} else {
copy[src.ID] = id
contents[src.ID] = id
}
}
@@ -147,12 +153,12 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
}
return err
}
return dbh.UpdateResourceModified(f.ctx, destParent.ID)
return dbh.UpdateResourceModified(f.ctx, destParent.ID())
})
if err == nil {
func() {
for k, v := range copy {
for k, v := range contents {
if err := r.f.cs.CopyContents(k, v); err != nil {
logrus.Warn("unable to copy " + k.String() + " to " + v.String() + ": " + err.Error())
}
@@ -161,25 +167,36 @@ func (r Resource) Copy(target string, id uuid.UUID, recursive, overwrite bool) (
}()
}
var dest = Resource{
f: r.f,
parentID := destParent.ID()
var info = ResourceInfo{
ID: id,
ParentID: &destParent.ID,
ParentID: &parentID,
Name: destName,
Dir: r.Dir,
Dir: r.FSDir(),
Created: time.Now(),
Modified: time.Now(),
Deleted: nil,
ContentSize: r.ContentSize,
ContentType: r.ContentType,
ContentSHA256: r.ContentSHA256,
ContentSize: r.FSContentSize(),
ContentType: r.FSContentType(),
ContentSHA256: r.FSContentSHA256(),
Permissions: "{}",
// Not Needed
// UserPermissions: ??
// InheritedPermissions: ??
// Path: destParent.Path + "/" + destName,
Publinks: 0,
}
return dest, deleted, err
if destParent.FSPath() == "/" {
info.Path = "/" + info.Name
} else {
info.Path = destParent.FSPath() + "/" + info.Name
}
ancestry := make([]ResourceInfo, len(destParent.Ancestry)+1)
copy(ancestry, destParent.Ancestry)
ancestry = append(ancestry, info)
created := Resource{
f: r.f,
Ancestry: ancestry,
UserPermission: destParent.UserPermission,
}
return created, deleted, err
}
// targetByPathOrUUID splits a target path or uuid into its constituent components
@@ -231,7 +248,7 @@ func (f filesystem) targetByPathOrUUID(src Resource, pathOrUUID string) (Resourc
name := pathOrUUID[index+1:]
if name == "" {
name = src.Name
name = src.FSName()
} else if CheckNameInvalid(name) {
return Resource{}, "", ErrResourceNameInvalid
}
+50 -30
View File
@@ -32,7 +32,7 @@ func (f filesystem) CreateResourceByPath(path string, dir, recursive bool) (Reso
}
func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool) (Resource, error) {
if !r.Dir {
if !r.FSDir() {
return Resource{}, ErrResourceNotCollection
}
if !r.hasPermission(PermissionWrite) {
@@ -47,7 +47,7 @@ func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool) (Res
var result db.Resource
err := r.f.db.WithTx(r.f.ctx, func(d *db.DbHandler) error {
var err error
parent := r.ID
parent := r.ID()
if result, err = d.CreateResource(r.f.ctx, db.CreateResourceParams{ID: id, Parent: &parent, Name: name, Dir: dir}); err != nil {
if strings.Contains(err.Error(), "unique_member_resource_name") {
return ErrResourceNameConflict
@@ -62,7 +62,7 @@ func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool) (Res
if err != nil {
return Resource{}, err
}
if !r.Dir {
if !r.FSDir() {
out, err := r.f.cs.OpenWrite(id, nil, nil)
if err == nil {
err = out.Close()
@@ -72,34 +72,54 @@ func (r Resource) CreateMemberResource(name string, id uuid.UUID, dir bool) (Res
}
}
p, err := MergePermissionStrings(r.InheritedPermissions, r.Permissions)
if err != nil {
return Resource{}, err
}
var deleted *time.Time
if result.Deleted.Valid {
deleted = &result.Deleted.Time
}
path := r.Path + "/" + result.Name
if r.Path == "/" {
path = result.Name
// return Resource{
// f: r.f,
// ID: result.ID,
// ParentID: result.Parent,
// Name: result.Name,
// Created: result.Created.Time,
// Modified: result.Modified.Time,
// Deleted: deleted,
// Dir: result.Dir,
// ContentSize: result.ContentSize,
// ContentType: result.ContentType,
// ContentSHA256: result.ContentSha256,
// Permissions: string(result.Permissions),
// Path: path,
// UserPermission: r.UserPermission,
// }, nil
info := resourceInfoFromDBResource(result)
if r.FSPath() == "/" {
info.Path = "/" + info.Name
} else {
info.Path = r.FSPath() + "/" + info.Name
}
ancestry := make([]ResourceInfo, len(r.Ancestry)+1)
copy(ancestry, r.Ancestry)
ancestry = append(ancestry, info)
return Resource{
f: r.f,
ID: result.ID,
ParentID: result.Parent,
Name: result.Name,
Created: result.Created.Time,
Modified: result.Modified.Time,
Deleted: deleted,
Dir: result.Dir,
ContentSize: result.ContentSize,
ContentType: result.ContentType,
ContentSHA256: result.ContentSha256,
Permissions: string(result.Permissions),
Path: path,
UserPermission: r.UserPermission,
InheritedPermissions: p,
Publinks: 0,
f: r.f,
Ancestry: ancestry,
UserPermission: r.UserPermission,
}, nil
}
func resourceInfoFromDBResource(r db.Resource) 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),
}
}
+5 -5
View File
@@ -14,28 +14,28 @@ func (r Resource) DeleteChildRecursive(name string, hardDelete bool) error {
return ErrInsufficientPermissions
}
id, err := r.f.db.ChildResourceIDByName(r.f.ctx, db.ChildResourceIDByNameParams{Parent: r.ID, Name: name})
id, err := r.f.db.ChildResourceIDByName(r.f.ctx, db.ChildResourceIDByNameParams{Parent: r.ID(), Name: name})
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return ErrResourceNotFound
}
return err
}
return r.f.deleteRecursive(id, r.ID, hardDelete)
return r.f.deleteRecursive(id, r.ID(), hardDelete)
}
func (r Resource) DeleteRecursive(hardDelete bool) error {
if r.ParentID == nil {
if r.ParentID() == nil {
return ErrInsufficientPermissions
}
parent, err := r.f.ResourceByID(*r.ParentID)
parent, err := r.f.ResourceByID(*r.ParentID())
if err != nil {
return err
}
if !parent.hasPermission(PermissionWrite) {
return ErrInsufficientPermissions
}
return r.f.deleteRecursive(r.ID, parent.ID, hardDelete)
return r.f.deleteRecursive(r.ID(), parent.ID(), hardDelete)
}
func (f filesystem) deleteRecursive(id, parent uuid.UUID, hardDelete bool) error {
+1 -1
View File
@@ -8,7 +8,7 @@ type DiskUsageInfo struct {
}
func (r Resource) DiskUsage() (DiskUsageInfo, error) {
if info, err := r.f.db.DiskUsage(r.f.ctx, r.ID); err != nil {
if info, err := r.f.db.DiskUsage(r.f.ctx, r.ID()); err != nil {
return DiskUsageInfo{}, err
} else {
return DiskUsageInfo{
+59 -12
View File
@@ -1,35 +1,86 @@
package fs
import (
"encoding/json"
"strings"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"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, Username: f.username}))
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, db.ResourceByIDParams{Root: f.rootID, ResourceID: id, Username: f.username}))
return f.resourceFromResult(f.db.ResourceByID(f.ctx, id))
}
func (f filesystem) resourceFromResult(r db.ResourceResult, err error) (Resource, error) {
if err == pgx.ErrNoRows || !r.Found || (r.UserPermission&PermissionRead == 0) {
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 Resource{
f: f,
return ResourceInfo{
ID: r.ID,
ParentID: r.Parent,
Name: r.Name,
@@ -42,11 +93,7 @@ func (f filesystem) resourceFromResult(r db.ResourceResult, err error) (Resource
ContentSHA256: r.ContentSha256,
Permissions: string(r.Permissions),
Publinks: int(r.Publinks),
// Definitely Needed
Path: r.Path,
UserPermission: r.UserPermission,
InheritedPermissions: string(r.InheritedPermissions),
}, nil
}
}
func (f filesystem) ResourceByPathOrUUID(pathOrUUID string) (Resource, error) {
+20 -32
View File
@@ -4,6 +4,7 @@ import (
"crypto/sha256"
"io"
"github.com/google/uuid"
"github.com/shroff/phylum/server/internal/api/serve"
"github.com/shroff/phylum/server/internal/core/db"
)
@@ -12,16 +13,16 @@ func (r Resource) OpenRead(start, length int64) (io.ReadCloser, error) {
if !r.hasPermission(PermissionRead) {
return nil, ErrInsufficientPermissions
}
return r.f.cs.OpenRead(r.ID, start, length)
return r.f.cs.OpenRead(r.ID(), start, length)
}
func (r Resource) OpenWrite() (io.WriteCloser, error) {
if !r.hasPermission(PermissionWrite) {
return nil, ErrInsufficientPermissions
}
return r.f.cs.OpenWrite(r.ID, sha256.New, func(len int, sum, mime string) error {
return r.f.cs.OpenWrite(r.ID(), sha256.New, func(len int, sum, mime string) error {
return r.f.db.UpdateResourceContents(r.f.ctx, db.UpdateResourceContentsParams{
ID: r.ID,
ID: r.ID(),
ContentType: mime,
ContentSize: int64(len),
ContentSha256: sum,
@@ -29,11 +30,11 @@ func (r Resource) OpenWrite() (io.WriteCloser, error) {
})
}
func (r Resource) ReadDir(recursive bool) ([]serve.Resource, error) {
func (r Resource) ReadDir(recursive bool) ([]serve.ResourceInfo, error) {
if !r.hasPermission(PermissionRead) {
return nil, ErrInsufficientPermissions
}
if !r.Dir {
if !r.FSDir() {
return nil, ErrResourceNotCollection
}
maxDepth := 1
@@ -41,43 +42,30 @@ func (r Resource) ReadDir(recursive bool) ([]serve.Resource, error) {
maxDepth = 1000
}
children, err := r.f.db.ReadDir(r.f.ctx, db.ReadDirParams{
ResourceID: r.ID,
InheritedPermissions: []byte(r.InheritedPermissions),
Path: r.Path,
Username: r.f.username,
MinDepth: 1,
MaxDepth: int32(maxDepth),
ResourceID: r.ID(),
MinDepth: 1,
MaxDepth: int32(maxDepth),
})
if err != nil {
return nil, err
}
result := make([]serve.Resource, len(children))
result := make([]serve.ResourceInfo, len(children))
path := make(map[uuid.UUID]string)
path[r.ID()] = r.FSPath()
if r.FSPath() == "/" {
path[r.ID()] = ""
}
for i, c := range children {
result[i] = Resource{
f: r.f,
ID: c.ID,
ParentID: c.Parent,
Name: c.Name,
Created: c.Created.Time,
Modified: c.Modified.Time,
Deleted: nil, // Query will not return deleted results
Dir: c.Dir,
ContentSize: c.ContentSize,
ContentType: c.ContentType,
ContentSHA256: c.ContentSha256,
Permissions: string(c.Permissions),
Publinks: int(c.Publinks),
Path: c.Path,
UserPermission: c.UserPermission,
InheritedPermissions: string(c.InheritedPermissions),
}
info := resourceInfoFromDBPublinkedResource(c)
info.Path = path[*info.ParentID] + "/" + info.Name
path[info.ID] = info.Path
result[i] = info
}
return result, nil
}
func (r Resource) Walk(depth int, fn func(serve.Resource) error) error {
func (r Resource) Walk(depth int, fn func(serve.ResourceInfo) error) error {
err := fn(r)
if err != nil {
return err
+19 -2
View File
@@ -22,10 +22,27 @@ func (r Resource) hasPermission(p Permission) bool {
}
func (r Resource) PermissionsString() string {
return r.Ancestry[0].PermissionsString()
}
func (r ResourceInfo) PermissionsString() string {
return permissionJsonString(r.Permissions)
}
func (r Resource) InheritedPermissionsString() string {
return permissionJsonString(r.InheritedPermissions)
func (r Resource) FullPermissionsString() string {
result := make(map[string]Permission)
for _, i := range r.Ancestry {
p := make(map[string]Permission)
json.Unmarshal([]byte(i.Permissions), &p)
for k, v := range p {
result[k] = result[k] | v
}
}
res, err := json.Marshal(result)
if err != nil {
return err.Error()
}
return permissionJsonString(string(res))
}
func permissionJsonString(j string) string {
+2 -2
View File
@@ -35,7 +35,7 @@ func (r Resource) CreatePublink(name, password string, duration time.Duration, a
return r.f.db.CreatePublink(r.f.ctx, db.CreatePublinkParams{
Name: name,
CreatedBy: r.f.username,
Root: r.ID,
Root: r.ID(),
PasswordHash: passwordHash,
Expires: expires,
MaxAccesses: int32(accesses),
@@ -43,7 +43,7 @@ func (r Resource) CreatePublink(name, password string, duration time.Duration, a
}
func (r Resource) ListPublinks() ([]publink.Info, error) {
res, err := r.f.db.PublinksByRoot(r.f.ctx, r.ID)
res, err := r.f.db.PublinksByRoot(r.f.ctx, r.ID())
if err != nil {
return nil, err
}
+41 -24
View File
@@ -7,29 +7,46 @@ import (
)
type Resource struct {
f filesystem
ID uuid.UUID `json:"id"`
ParentID *uuid.UUID `json:"parent"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created time.Time `json:"created"`
Modified time.Time `json:"modified"`
Deleted *time.Time `json:"deleted"`
ContentSize int64 `json:"csize"`
ContentType string `json:"ctype"`
ContentSHA256 string `json:"csha256"`
Permissions string `json:"permissions"`
Publinks int `json:"publinks"`
Path string `json:"path"`
UserPermission Permission `json:"perm"`
InheritedPermissions string `json:"inherited"`
f filesystem
Ancestry []ResourceInfo `json:"ancestry"`
UserPermission Permission `json:"perm"`
}
func (r Resource) FSName() string { return r.Name }
func (r Resource) FSPath() string { return r.Path }
func (r Resource) FSDir() bool { return r.Dir }
func (r Resource) FSCreated() time.Time { return r.Created }
func (r Resource) FSModified() time.Time { return r.Modified }
func (r Resource) FSContentSize() int64 { return r.ContentSize }
func (r Resource) FSContentSHA256() string { return r.ContentSHA256 }
func (r Resource) FSContentType() string { return r.ContentType }
type ResourceInfo struct {
ID uuid.UUID `json:"id"`
ParentID *uuid.UUID `json:"parent"`
Name string `json:"name"`
Dir bool `json:"dir"`
Created time.Time `json:"created"`
Modified time.Time `json:"modified"`
Deleted *time.Time `json:"deleted"`
ContentSize int64 `json:"csize"`
ContentType string `json:"ctype"`
ContentSHA256 string `json:"csha256"`
Permissions string `json:"permissions"`
Publinks int `json:"publinks"`
Path string `json:"-"`
}
func (r Resource) Info() ResourceInfo { return r.Ancestry[len(r.Ancestry)-1] }
func (r Resource) ID() uuid.UUID { return r.Info().ID }
func (r Resource) ParentID() *uuid.UUID { return r.Info().ParentID }
func (r Resource) FSName() string { return r.Info().Name }
func (r Resource) FSDir() bool { return r.Info().Dir }
func (r Resource) FSCreated() time.Time { return r.Info().Created }
func (r Resource) FSModified() time.Time { return r.Info().Modified }
func (r Resource) Deleted() *time.Time { return r.Info().Deleted }
func (r Resource) FSContentSize() int64 { return r.Info().ContentSize }
func (r Resource) FSContentSHA256() string { return r.Info().ContentSHA256 }
func (r Resource) FSContentType() string { return r.Info().ContentType }
func (r Resource) Publinks() int { return r.Info().Publinks }
func (r Resource) FSPath() string { return r.Info().Path }
func (r ResourceInfo) FSName() string { return r.Name }
func (r ResourceInfo) FSDir() bool { return r.Dir }
func (r ResourceInfo) FSCreated() time.Time { return r.Created }
func (r ResourceInfo) FSModified() time.Time { return r.Modified }
func (r ResourceInfo) FSContentSize() int64 { return r.ContentSize }
func (r ResourceInfo) FSContentSHA256() string { return r.ContentSHA256 }
func (r ResourceInfo) FSContentType() string { return r.ContentType }
func (r ResourceInfo) FSPath() string { return r.Path }
+3 -3
View File
@@ -15,12 +15,12 @@ func (r Resource) UpdatePermissions(username string, permission Permission) (Res
var err error
if permission == 0 {
p, err = r.f.db.RemoveUserPermissionForResource(r.f.ctx, db.RemoveUserPermissionForResourceParams{
ResourceID: r.ID,
ResourceID: r.ID(),
Username: username,
})
} else {
p, err = r.f.db.UpdateUserPermissionsForResource(r.f.ctx, db.UpdateUserPermissionsForResourceParams{
ResourceID: r.ID,
ResourceID: r.ID(),
Username: username,
Permission: permission,
})
@@ -28,6 +28,6 @@ func (r Resource) UpdatePermissions(username string, permission Permission) (Res
if err != nil {
return Resource{}, err
}
r.Permissions = string(p)
r.Ancestry[0].Permissions = string(p)
return r, nil
}
+8 -4
View File
@@ -17,7 +17,7 @@ type filesystem struct {
}
func (f filesystem) resourceByPath(search string) (Resource, error) {
e, err := f.db.ResourceByPath(f.ctx, db.ResourceByPathParams{Path: search})
e, err := f.db.ResourceByPath(f.ctx, db.ResourceByPathParams{Path: search, Root: &f.root})
if len(e) == 0 {
err = ErrNotFound
}
@@ -30,14 +30,18 @@ func (f filesystem) resourceByPath(search string) (Resource, error) {
if e[i].ID == f.root {
found = true
}
if b.Len() != 0 {
if i != len(e)-i {
b.WriteByte('/')
b.WriteString(e[i].Name)
}
b.WriteString(e[i].Name)
}
if !found {
return Resource{}, err
}
path := b.String()
if b.Len() == 0 {
path = "/"
}
r := e[0]
return Resource{
@@ -45,7 +49,7 @@ func (f filesystem) resourceByPath(search string) (Resource, error) {
id: r.ID,
name: r.Name,
dir: r.Dir,
path: b.String(),
path: path,
created: r.Created.Time,
modified: r.Modified.Time,
contentSize: r.ContentSize,
+2 -2
View File
@@ -37,7 +37,7 @@ func (r Resource) OpenRead(start, length int64) (io.ReadCloser, error) {
return r.f.cs.OpenRead(r.id, start, length)
}
func (r Resource) ReadDir(recursive bool) ([]serve.Resource, error) {
func (r Resource) ReadDir(recursive bool) ([]serve.ResourceInfo, error) {
if !r.dir {
return nil, errors.New("resource is not a collection")
}
@@ -53,7 +53,7 @@ func (r Resource) ReadDir(recursive bool) ([]serve.Resource, error) {
return nil, err
}
result := make([]serve.Resource, len(children))
result := make([]serve.ResourceInfo, len(children))
parentPath := r.path
if parentPath == "/" {
+2 -2
View File
@@ -41,8 +41,8 @@ type Manager interface {
ReadAccessToken(accessToken string) (User, error)
// user_lists.go
SharedResources(u User) (result []fs.Resource, err error)
Bookmarks(u User) ([]fs.Resource, error)
SharedResources(u User) (result []fs.ResourceInfo, err error)
Bookmarks(u User) ([]fs.ResourceInfo, error)
AddBookmark(u User, resource fs.Resource) error
RemoveBookmark(u User, id uuid.UUID) error
}
+7 -7
View File
@@ -8,14 +8,14 @@ import (
"github.com/shroff/phylum/server/internal/core/fs"
)
func (m manager) SharedResources(u User) ([]fs.Resource, error) {
func (m manager) SharedResources(u User) ([]fs.ResourceInfo, error) {
// TODO: #permissions This doesn't take permissions into account. is this okay?
res, err := m.db.Queries.SharedResources(m.ctx, db.SharedResourcesParams{Username: u.Username, UserHome: u.Home})
if err != nil {
return nil, err
}
result := make([]fs.Resource, len(res))
result := make([]fs.ResourceInfo, len(res))
for i, r := range res {
result[i] = resourceFromDB(r)
}
@@ -23,33 +23,33 @@ func (m manager) SharedResources(u User) ([]fs.Resource, error) {
}
func (m manager) AddBookmark(u User, resource fs.Resource) error {
return m.db.Queries.AddBookmark(m.ctx, db.AddBookmarkParams{Username: u.Username, ID: resource.ID})
return m.db.Queries.AddBookmark(m.ctx, db.AddBookmarkParams{Username: u.Username, ID: resource.ID()})
}
func (m manager) RemoveBookmark(u User, id uuid.UUID) error {
return m.db.Queries.RemoveBookmark(m.ctx, db.RemoveBookmarkParams{Username: u.Username, ID: id})
}
func (m manager) Bookmarks(u User) ([]fs.Resource, error) {
func (m manager) Bookmarks(u User) ([]fs.ResourceInfo, error) {
// TODO: #permissions This doesn't take permissions into account. is this okay?
res, err := m.db.Queries.ListBookmarks(m.ctx, u.Username)
if err != nil {
return nil, err
}
result := make([]fs.Resource, len(res))
result := make([]fs.ResourceInfo, len(res))
for i, r := range res {
result[i] = resourceFromDB(r)
}
return result, err
}
func resourceFromDB(r db.Resource) fs.Resource {
func resourceFromDB(r db.Resource) fs.ResourceInfo {
var deleted *time.Time
if r.Deleted.Valid {
deleted = &r.Deleted.Time
}
return fs.Resource{
return fs.ResourceInfo{
ID: r.ID,
ParentID: r.Parent,
Name: r.Name,