diff --git a/server/internal/api/serve/serve.go b/server/internal/api/serve/serve.go
index ee8957aa..1f4ef3ea 100644
--- a/server/internal/api/serve/serve.go
+++ b/server/internal/api/serve/serve.go
@@ -25,7 +25,7 @@ var htmlReplacer = strings.NewReplacer(
var ErrRangeNotSupported = errors.New("byte range not suppoered")
-type Resource interface {
+type ResourceInfo interface {
FSName() string
FSPath() string
FSDir() bool
@@ -34,7 +34,11 @@ type Resource interface {
FSContentSize() int64
FSContentSHA256() string
FSContentType() string
- ReadDir(recursive bool) ([]Resource, error)
+}
+
+type Resource interface {
+ ResourceInfo
+ ReadDir(recursive bool) ([]ResourceInfo, error)
OpenRead(start, length int64) (io.ReadCloser, error)
}
diff --git a/server/internal/api/v1/fs/cat.go b/server/internal/api/v1/fs/cat.go
index 2cbb2508..02160302 100644
--- a/server/internal/api/v1/fs/cat.go
+++ b/server/internal/api/v1/fs/cat.go
@@ -16,7 +16,7 @@ func handleCatRequest(c *gin.Context) {
f := auth.GetFileSystem(c)
r, err := f.ResourceByID(resourceID)
- if r.Dir {
+ if r.FSDir() {
err = fs.ErrResourceCollection
}
if err != nil {
diff --git a/server/internal/api/v1/fs/download.go b/server/internal/api/v1/fs/download.go
index ac8d97f4..c808d7bd 100644
--- a/server/internal/api/v1/fs/download.go
+++ b/server/internal/api/v1/fs/download.go
@@ -21,14 +21,14 @@ func handleDownloadRequest(c *gin.Context) {
f := auth.GetFileSystem(c)
r, err := f.ResourceByID(resourceID)
- prefix := path.Dir(r.Path)
+ prefix := path.Dir(r.FSPath())
c.Writer.Header().Set("Content-Type", "application/zip")
- c.Writer.Header().Set("Content-Disposition", "attachment; filename=\""+r.Name+".zip\"")
+ c.Writer.Header().Set("Content-Disposition", "attachment; filename=\""+r.FSName()+".zip\"")
var zip = zip.NewWriter(c.Writer)
close := c.Writer.CloseNotify()
- err = r.Walk(2, func(r serve.Resource) error {
+ err = r.Walk(2, func(r serve.ResourceInfo) error {
if r.FSDir() {
return nil
}
@@ -47,7 +47,7 @@ func handleDownloadRequest(c *gin.Context) {
if err != nil {
return err
}
- in, err := r.OpenRead(0, -1)
+ in, err := r.(fs.Resource).OpenRead(0, -1)
if err != nil {
return err
}
diff --git a/server/internal/api/v1/fs/ls.go b/server/internal/api/v1/fs/ls.go
index edff41f6..bea52513 100644
--- a/server/internal/api/v1/fs/ls.go
+++ b/server/internal/api/v1/fs/ls.go
@@ -32,14 +32,14 @@ func handleLsRequest(c *gin.Context) {
func LsResponseFromResource(f fs.FileSystem, r fs.Resource) ResourceLsResponse {
response := ResourceLsResponse{
Resource: r,
- InheritedPermissions: r.InheritedPermissions,
- }
- if r.Dir {
- children, err := r.ReadDir(false)
- if err != nil {
- panic(err)
- }
- response.Children = children
+ InheritedPermissions: r.FullPermissionsString(),
}
+ // if r.FSDir() {
+ // children, err := r.ReadDir(false)
+ // if err != nil {
+ // panic(err)
+ // }
+ // response.Children = children
+ // }
return response
}
diff --git a/server/internal/api/v1/my/routes.go b/server/internal/api/v1/my/routes.go
index b7480a24..1e662e3d 100644
--- a/server/internal/api/v1/my/routes.go
+++ b/server/internal/api/v1/my/routes.go
@@ -20,11 +20,11 @@ type homeResponse struct {
}
type sharedResponse struct {
- Shared []fs.Resource `json:"shared"`
+ Shared []fs.ResourceInfo `json:"shared"`
}
type bookmarksResponse struct {
- Bookmarks []fs.Resource `json:"bookmarks"`
+ Bookmarks []fs.ResourceInfo `json:"bookmarks"`
}
type bookmarkIDParams struct {
ID uuid.UUID `json:"id" binding:"required"`
diff --git a/server/internal/api/webdav/impl/prop.go b/server/internal/api/webdav/impl/prop.go
index dd55cb26..e106a0a8 100644
--- a/server/internal/api/webdav/impl/prop.go
+++ b/server/internal/api/webdav/impl/prop.go
@@ -69,7 +69,7 @@ func makePropstats(x, y Propstat) []Propstat {
var liveProps = map[xml.Name]struct {
// findFn implements the propfind function of this property. If nil,
// it indicates a hidden property.
- findFn func(serve.Resource) string
+ findFn func(serve.ResourceInfo) string
// dir is true if the property applies to directories.
dir bool
}{
@@ -132,7 +132,7 @@ var liveProps = map[xml.Name]struct {
//
// Each Propstat has a unique status and each property name will only be part
// of one Propstat element.
-func props(fs FileSystem, ls LockSystem, fi serve.Resource, pnames []xml.Name) ([]Propstat, error) {
+func props(fs FileSystem, ls LockSystem, fi serve.ResourceInfo, pnames []xml.Name) ([]Propstat, error) {
pstatOK := Propstat{Status: http.StatusOK}
pstatNotFound := Propstat{Status: http.StatusNotFound}
for _, pn := range pnames {
@@ -153,7 +153,7 @@ func props(fs FileSystem, ls LockSystem, fi serve.Resource, pnames []xml.Name) (
}
// propnames returns the property names defined for resource name.
-func propnames(fs FileSystem, ls LockSystem, fi serve.Resource) ([]xml.Name, error) {
+func propnames(fs FileSystem, ls LockSystem, fi serve.ResourceInfo) ([]xml.Name, error) {
pnames := make([]xml.Name, 0, len(liveProps))
for pn, prop := range liveProps {
if prop.findFn != nil && (prop.dir || !fi.FSDir()) {
@@ -171,7 +171,7 @@ func propnames(fs FileSystem, ls LockSystem, fi serve.Resource) ([]xml.Name, err
// returned if they are named in 'include'.
//
// See http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
-func allprop(fs FileSystem, ls LockSystem, fi serve.Resource, include []xml.Name) ([]Propstat, error) {
+func allprop(fs FileSystem, ls LockSystem, fi serve.ResourceInfo, include []xml.Name) ([]Propstat, error) {
pnames, err := propnames(fs, ls, fi)
if err != nil {
return nil, err
@@ -252,38 +252,38 @@ func escapeXML(s string) string {
return s
}
-func findResourceType(fi serve.Resource) string {
+func findResourceType(fi serve.ResourceInfo) string {
if fi.FSDir() {
return ``
}
return ""
}
-func findDisplayName(fi serve.Resource) string {
+func findDisplayName(fi serve.ResourceInfo) string {
return escapeXML(fi.FSName())
}
-func findContentLength(fi serve.Resource) string {
+func findContentLength(fi serve.ResourceInfo) string {
return strconv.FormatInt(fi.FSContentSize(), 10)
}
-func findCreationDate(fi serve.Resource) string {
+func findCreationDate(fi serve.ResourceInfo) string {
return fi.FSCreated().UTC().Format(http.TimeFormat)
}
-func findLastModified(fi serve.Resource) string {
+func findLastModified(fi serve.ResourceInfo) string {
return fi.FSModified().UTC().Format(http.TimeFormat)
}
-func findContentType(fi serve.Resource) string {
+func findContentType(fi serve.ResourceInfo) string {
return fi.FSContentType()
}
-func findETag(fi serve.Resource) string {
+func findETag(fi serve.ResourceInfo) string {
return fi.FSContentSHA256()
}
-func findSupportedLock(fi serve.Resource) string {
+func findSupportedLock(fi serve.ResourceInfo) string {
return `` +
`` +
`` +
diff --git a/server/internal/api/webdav/impl/webdav.go b/server/internal/api/webdav/impl/webdav.go
index 68d437bf..f57affec 100644
--- a/server/internal/api/webdav/impl/webdav.go
+++ b/server/internal/api/webdav/impl/webdav.go
@@ -167,7 +167,7 @@ func (h *Handler) confirmLocks(r *http.Request, src, dst string) (release func()
if res, err := h.FileSystem.ResourceByPath(path); err != nil {
return false, err
} else {
- return res.ContentSHA256 == etag, nil
+ return res.FSContentSHA256() == etag, nil
}
}, l.conditions...)
if err == ErrConfirmationFailed {
@@ -192,7 +192,7 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status
}
allow := "OPTIONS, LOCK, PUT, MKCOL"
if fi, err := h.FileSystem.ResourceByPath(reqPath); err == nil {
- if fi.Dir {
+ if fi.FSDir() {
allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND"
} else {
allow = "OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT"
@@ -268,7 +268,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int,
}
} else if err != nil {
return http.StatusNotFound, err
- } else if res.Dir {
+ } else if res.FSDir() {
return http.StatusConflict, fs.ErrResourceCollection
}
@@ -286,7 +286,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int,
if closeErr != nil {
return http.StatusMethodNotAllowed, closeErr
}
- w.Header().Set("ETag", fi.ContentSHA256)
+ w.Header().Set("ETag", fi.FSContentSHA256())
return http.StatusCreated, nil
}
@@ -456,7 +456,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
mw := multistatusWriter{w: w}
- writePropStat := func(r serve.Resource) error {
+ writePropStat := func(r serve.ResourceInfo) error {
var pstats []Propstat
if pf.Propname != nil {
pnames, err := propnames(h.FileSystem, h.LockSystem, r)
diff --git a/server/internal/command/fs/cat.go b/server/internal/command/fs/cat.go
index 2887b992..afe91c73 100644
--- a/server/internal/command/fs/cat.go
+++ b/server/internal/command/fs/cat.go
@@ -23,7 +23,7 @@ func setupCatCommand() *cobra.Command {
os.Exit(1)
}
- if r.Dir {
+ if r.FSDir() {
fmt.Println("cannot read'" + pathOrUUID + "': is a directory")
os.Exit(2)
}
diff --git a/server/internal/command/fs/cp.go b/server/internal/command/fs/cp.go
index 22188b4a..89a53394 100644
--- a/server/internal/command/fs/cp.go
+++ b/server/internal/command/fs/cp.go
@@ -24,7 +24,7 @@ func setupCpCommand() *cobra.Command {
}
force, _ := cmd.Flags().GetBool("force")
- if src.Dir {
+ if src.FSDir() {
if recursive, err := cmd.Flags().GetBool("recursive"); err != nil || !recursive {
fmt.Println("cannot copy'" + srcPathOrUUID + "' to '" + args[1] + "': must use -r to copy directories")
os.Exit(1)
diff --git a/server/internal/command/fs/import.go b/server/internal/command/fs/import.go
index 5222da10..19daf56b 100644
--- a/server/internal/command/fs/import.go
+++ b/server/internal/command/fs/import.go
@@ -62,7 +62,7 @@ func setupImportCommand() *cobra.Command {
ids["."], _ = uuid.NewUUID()
create = append(create, db.CreateResourcesParams{
ID: ids["."],
- Parent: destParent.ID,
+ Parent: destParent.ID(),
Name: destName,
Dir: stat.IsDir(),
})
@@ -117,7 +117,7 @@ func setupImportCommand() *cobra.Command {
return err
}
} else {
- _, err := f.WithRoot(destParent.ID).ResourceByPath(destName)
+ _, err := f.WithRoot(destParent.ID()).ResourceByPath(destName)
if err == nil {
return errors.New("resource with name '" + destName + "' already exist. use -f to overwrite")
} else if !errors.Is(err, fs.ErrResourceNotFound) {
@@ -130,7 +130,7 @@ func setupImportCommand() *cobra.Command {
}
return err
}
- return dbh.UpdateResourceModified(ctx, destParent.ID)
+ return dbh.UpdateResourceModified(ctx, destParent.ID())
})
if err == nil {
diff --git a/server/internal/command/fs/ls.go b/server/internal/command/fs/ls.go
index a8fd4ac7..880e75df 100644
--- a/server/internal/command/fs/ls.go
+++ b/server/internal/command/fs/ls.go
@@ -25,10 +25,10 @@ func setupLsCommand() *cobra.Command {
os.Exit(1)
}
- fmt.Println(r.Path + " " + r.InheritedPermissionsString())
- fmt.Println(formatRow(r.ID.String(), formatSize(r.ContentSize), r.ContentSHA256, ".", r.PermissionsString(), r.Publinks))
+ fmt.Println(r.FSPath() + " " + r.FullPermissionsString())
+ fmt.Println(formatRow(r.ID().String(), formatSize(r.FSContentSize()), r.FSContentSHA256(), ".", r.PermissionsString(), r.Publinks()))
- if r.Dir {
+ if r.FSDir() {
children, err := r.ReadDir(false)
if err != nil {
fmt.Println("cannot access '" + pathOrUUID + "': " + err.Error())
@@ -45,7 +45,7 @@ func setupLsCommand() *cobra.Command {
return strings.Compare(strings.ToLower(a.FSName()), strings.ToLower((b.FSName()))) <= 0
})
for _, c := range children {
- fmt.Println(formatResourceSummary(c.(fs.Resource)))
+ fmt.Println(formatResourceSummary(c.(fs.ResourceInfo)))
}
}
},
@@ -68,10 +68,10 @@ func formatRow(id, size, sha256, name, permissions string, links int) string {
return fmt.Sprintf("%s %2d %4s %s %-24s %s", id, links, size, sha256[0:8], name, permissions)
}
-func formatResourceSummary(r fs.Resource) string {
- name := r.Name
- if r.Dir {
+func formatResourceSummary(r fs.ResourceInfo) string {
+ name := r.FSName()
+ if r.FSDir() {
name += "/"
}
- return formatRow(r.ID.String(), formatSize(r.ContentSize), r.ContentSHA256, name, r.PermissionsString(), r.Publinks)
+ return formatRow(r.ID.String(), formatSize(r.FSContentSize()), r.FSContentSHA256(), name, r.PermissionsString(), r.Publinks)
}
diff --git a/server/internal/command/fs/rm.go b/server/internal/command/fs/rm.go
index 578bc4af..1165ceef 100644
--- a/server/internal/command/fs/rm.go
+++ b/server/internal/command/fs/rm.go
@@ -22,7 +22,7 @@ func setupRmCommand() *cobra.Command {
os.Exit(1)
}
- if r.Dir {
+ if r.FSDir() {
if recursive, err := cmd.Flags().GetBool("recursive"); err != nil || !recursive {
fmt.Println("cannot remove '" + pathOrUUID + "': Is a directory. Try again with '-r'")
os.Exit(1)
diff --git a/server/internal/command/user/add.go b/server/internal/command/user/add.go
index 078e7879..fc1194c5 100644
--- a/server/internal/command/user/add.go
+++ b/server/internal/command/user/add.go
@@ -70,7 +70,7 @@ func setupUserAddCommand() *cobra.Command {
fmt.Println("invalid value for flag 'chroot': " + err.Error())
os.Exit(1)
} else {
- root = r.ID
+ root = r.ID()
}
}
@@ -110,7 +110,7 @@ func setupUserAddCommand() *cobra.Command {
if _, err := home.UpdatePermissions(u.Username, fs.PermissionRead|fs.PermissionWrite|fs.PermissionShare); err != nil {
return err
}
- return userManager.UpdateUserHome(u, home.ID)
+ return userManager.UpdateUserHome(u, home.ID())
}
return nil
diff --git a/server/internal/command/user/bookmarks.go b/server/internal/command/user/bookmarks.go
index e00ff6cd..bf3e5baa 100644
--- a/server/internal/command/user/bookmarks.go
+++ b/server/internal/command/user/bookmarks.go
@@ -57,7 +57,7 @@ func setupBookmarksRemoveCommand() *cobra.Command {
os.Exit(1)
}
- if err := user.CreateManager(context.Background()).RemoveBookmark(common.User(cmd), r.ID); err != nil {
+ if err := user.CreateManager(context.Background()).RemoveBookmark(common.User(cmd), r.ID()); err != nil {
fmt.Println("unable to remove bookmark: " + err.Error())
os.Exit(1)
}
diff --git a/server/internal/command/user/cmd.go b/server/internal/command/user/cmd.go
index 133afeb4..760342dd 100644
--- a/server/internal/command/user/cmd.go
+++ b/server/internal/command/user/cmd.go
@@ -44,7 +44,7 @@ func setupUserChrootCommand() *cobra.Command {
if res, err := common.RootFileSystem().ResourceByPathOrUUID(idOrPath); err != nil {
logrus.Fatal(err)
} else {
- userManager.UpdateUserRoot(user, res.ID)
+ userManager.UpdateUserRoot(user, res.ID())
}
}
},
diff --git a/server/internal/core/fs/copy_move.go b/server/internal/core/fs/copy_move.go
index 2610c115..ad6884df 100644
--- a/server/internal/core/fs/copy_move.go
+++ b/server/internal/core/fs/copy_move.go
@@ -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
}
diff --git a/server/internal/core/fs/create.go b/server/internal/core/fs/create.go
index 7e112274..d057450f 100644
--- a/server/internal/core/fs/create.go
+++ b/server/internal/core/fs/create.go
@@ -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),
+ }
+}
diff --git a/server/internal/core/fs/delete.go b/server/internal/core/fs/delete.go
index fc99fcea..22294998 100644
--- a/server/internal/core/fs/delete.go
+++ b/server/internal/core/fs/delete.go
@@ -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 {
diff --git a/server/internal/core/fs/disk_usage.go b/server/internal/core/fs/disk_usage.go
index e8bbd307..2f523a70 100644
--- a/server/internal/core/fs/disk_usage.go
+++ b/server/internal/core/fs/disk_usage.go
@@ -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{
diff --git a/server/internal/core/fs/find.go b/server/internal/core/fs/find.go
index 96f28ed2..a5d30c22 100644
--- a/server/internal/core/fs/find.go
+++ b/server/internal/core/fs/find.go
@@ -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) {
diff --git a/server/internal/core/fs/open.go b/server/internal/core/fs/open.go
index b0448ffb..383d8e7b 100644
--- a/server/internal/core/fs/open.go
+++ b/server/internal/core/fs/open.go
@@ -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
diff --git a/server/internal/core/fs/permission.go b/server/internal/core/fs/permission.go
index 08f453b7..359edc9b 100644
--- a/server/internal/core/fs/permission.go
+++ b/server/internal/core/fs/permission.go
@@ -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 {
diff --git a/server/internal/core/fs/publink.go b/server/internal/core/fs/publink.go
index 4e4647ed..893434d6 100644
--- a/server/internal/core/fs/publink.go
+++ b/server/internal/core/fs/publink.go
@@ -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
}
diff --git a/server/internal/core/fs/resource.go b/server/internal/core/fs/resource.go
index 11fc9ed0..d6f6b2ca 100644
--- a/server/internal/core/fs/resource.go
+++ b/server/internal/core/fs/resource.go
@@ -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 }
diff --git a/server/internal/core/fs/update.go b/server/internal/core/fs/update.go
index 681335d4..862fa28c 100644
--- a/server/internal/core/fs/update.go
+++ b/server/internal/core/fs/update.go
@@ -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
}
diff --git a/server/internal/core/publink/filesystem.go b/server/internal/core/publink/filesystem.go
index fdee997d..33cfafa7 100644
--- a/server/internal/core/publink/filesystem.go
+++ b/server/internal/core/publink/filesystem.go
@@ -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,
diff --git a/server/internal/core/publink/resource.go b/server/internal/core/publink/resource.go
index b0739abc..7d2c38c8 100644
--- a/server/internal/core/publink/resource.go
+++ b/server/internal/core/publink/resource.go
@@ -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 == "/" {
diff --git a/server/internal/core/user/user.go b/server/internal/core/user/user.go
index 493e059c..b9a5504b 100644
--- a/server/internal/core/user/user.go
+++ b/server/internal/core/user/user.go
@@ -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
}
diff --git a/server/internal/core/user/user_lists.go b/server/internal/core/user/user_lists.go
index 72b8686d..eb9c11e4 100644
--- a/server/internal/core/user/user_lists.go
+++ b/server/internal/core/user/user_lists.go
@@ -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,