Skip to content

Commit

Permalink
Update recycle methods in file systems and add EOS implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Oct 13, 2021
1 parent e0ca864 commit 8641587
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 64 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ require (
go 1.16

replace (
github.com/cs3org/go-cs3apis => github.com/ishank011/go-cs3apis v0.0.0-20211013113149-f3f37b224c33
github.com/cs3org/go-cs3apis => github.com/ishank011/go-cs3apis v0.0.0-20211013150624-b23a3cdd34a2
github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a
github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1
google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ishank011/go-cs3apis v0.0.0-20211013113149-f3f37b224c33 h1:wpjZz46J4TooX1SjrptGGjLwk+X2e2qKNk6epSZ3xa8=
github.com/ishank011/go-cs3apis v0.0.0-20211013113149-f3f37b224c33/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/ishank011/go-cs3apis v0.0.0-20211013150624-b23a3cdd34a2 h1:UnMagbmyhO+efFGIcQ1loCaHDINHUSD9ZPIBo8WrD4M=
github.com/ishank011/go-cs3apis v0.0.0-20211013150624-b23a3cdd34a2/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
Expand Down
12 changes: 9 additions & 3 deletions internal/grpc/services/storageprovider/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,8 @@ func (s *service) RestoreRecycleItem(ctx context.Context, req *provider.RestoreR
if err != nil {
return nil, err
}
if err := s.storage.RestoreRecycleItem(ctx, req.Key, ref.Path, req.RestoreRef); err != nil {
key, itemPath := router.ShiftPath(req.Key)
if err := s.storage.RestoreRecycleItem(ctx, ref.GetPath(), key, itemPath, req.RestoreRef); err != nil {
var st *rpc.Status
switch err.(type) {
case errtypes.IsNotFound:
Expand All @@ -920,9 +921,14 @@ func (s *service) RestoreRecycleItem(ctx context.Context, req *provider.RestoreR
}

func (s *service) PurgeRecycle(ctx context.Context, req *provider.PurgeRecycleRequest) (*provider.PurgeRecycleResponse, error) {
ref, err := s.unwrap(ctx, req.Ref)
if err != nil {
return nil, err
}
// if a key was sent as opaque id purge only that item
if req.GetRef() != nil && req.GetRef().GetResourceId() != nil && req.GetRef().GetResourceId().OpaqueId != "" {
if err := s.storage.PurgeRecycleItem(ctx, req.GetRef().GetResourceId().OpaqueId, req.GetRef().Path); err != nil {
if req.Key != "" {
key, itemPath := router.ShiftPath(req.Key)
if err := s.storage.PurgeRecycleItem(ctx, ref.GetPath(), key, itemPath); err != nil {
var st *rpc.Status
switch err.(type) {
case errtypes.IsNotFound:
Expand Down
26 changes: 6 additions & 20 deletions internal/http/services/owncloud/ocdav/trashbin.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,9 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc
// use the key which is prefixed with the StoragePath to lookup the correct storage ...
// TODO currently limited to the home storage
Ref: &provider.Reference{
Path: path.Join(basePath, itemPath),
Path: basePath,
},
Key: key,
Key: path.Join(key, itemPath),
RestoreRef: &provider.Reference{Path: dst},
}

Expand Down Expand Up @@ -600,28 +600,14 @@ func (h *TrashbinHandler) delete(w http.ResponseWriter, r *http.Request, s *svc,
return
}

sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{Path: basePath}})
if err != nil {
sublog.Error().Err(err).Msg("error calling Stat")
w.WriteHeader(http.StatusInternalServerError)
return
}
if sRes.Status.Code != rpc.Code_CODE_OK {
HandleErrorStatus(&sublog, w, sRes.Status)
return
}

// set key as opaque id, the storageprovider will use it as the key for the
// storage drives PurgeRecycleItem key call

req := &provider.PurgeRecycleRequest{
Ref: &provider.Reference{
ResourceId: &provider.ResourceId{
StorageId: sRes.Info.Id.StorageId,
OpaqueId: key,
},
Path: utils.MakeRelativePath(itemPath),
Path: basePath,
},
Key: path.Join(key, utils.MakeRelativePath(itemPath)),
}

res, err := client.PurgeRecycle(ctx, req)
Expand All @@ -634,9 +620,9 @@ func (h *TrashbinHandler) delete(w http.ResponseWriter, r *http.Request, s *svc,
case rpc.Code_CODE_OK:
w.WriteHeader(http.StatusNoContent)
case rpc.Code_CODE_NOT_FOUND:
sublog.Debug().Str("storageid", sRes.Info.Id.StorageId).Str("key", key).Interface("status", res.Status).Msg("resource not found")
sublog.Debug().Str("path", basePath).Str("key", key).Interface("status", res.Status).Msg("resource not found")
w.WriteHeader(http.StatusConflict)
m := fmt.Sprintf("storageid %v not found", sRes.Info.Id.StorageId)
m := fmt.Sprintf("path %s not found", basePath)
b, err := Marshal(exception{
code: SabredavConflict,
message: m,
Expand Down
14 changes: 8 additions & 6 deletions pkg/cbox/storage/eoswrapper/eoswrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (

type wrapper struct {
storage.FS
conf *eosfs.Config
mountIDTemplate *template.Template
}

Expand Down Expand Up @@ -90,7 +91,7 @@ func New(m map[string]interface{}) (storage.FS, error) {
return nil, err
}

return &wrapper{FS: eos, mountIDTemplate: mountIDTemplate}, nil
return &wrapper{FS: eos, conf: c, mountIDTemplate: mountIDTemplate}, nil
}

// We need to override the two methods, GetMD and ListFolder to fill the
Expand Down Expand Up @@ -142,15 +143,16 @@ func (w *wrapper) getMountID(ctx context.Context, r *provider.ResourceInfo) stri
}

func (w *wrapper) setProjectSharingPermissions(ctx context.Context, r *provider.ResourceInfo) error {
if strings.HasPrefix(r.Path, eosProjectsNamespace) {
// Check if this storage provider corresponds to a project spaces instance
if strings.HasPrefix(w.conf.Namespace, eosProjectsNamespace) {

// Extract project name from the path resembling /eos/project/c/cernbox/minutes/..
// Extract project name from the path resembling /c/cernbox or /c/cernbox/minutes/..
path := strings.TrimPrefix(r.Path, eosProjectsNamespace)
parts := strings.SplitN(path, "/", 3)
if len(parts) != 3 {
parts := strings.SplitN(path, "/", 4)
if len(parts) != 4 && len(parts) != 3 {
return errtypes.BadRequest("eoswrapper: path does not follow the allowed format")
}
adminGroup := projectSpaceGroupsPrefix + parts[1] + projectSpaceAdminGroupsSuffix
adminGroup := projectSpaceGroupsPrefix + parts[2] + projectSpaceAdminGroupsSuffix
user := ctxpkg.ContextMustGetUser(ctx)

for _, g := range user.Groups {
Expand Down
8 changes: 4 additions & 4 deletions pkg/storage/fs/nextcloud/nextcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,15 +473,15 @@ func (nc *StorageDriver) ListRecycle(ctx context.Context, basePath, key string,
}

// RestoreRecycleItem as defined in the storage.FS interface
func (nc *StorageDriver) RestoreRecycleItem(ctx context.Context, key string, path string, restoreRef *provider.Reference) error {
func (nc *StorageDriver) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
type paramsObj struct {
Key string `json:"key"`
Path string `json:"path"`
RestoreRef *provider.Reference `json:"restoreRef"`
}
bodyObj := &paramsObj{
Key: key,
Path: path,
Path: relativePath,
RestoreRef: restoreRef,
}
bodyStr, _ := json.Marshal(bodyObj)
Expand All @@ -495,14 +495,14 @@ func (nc *StorageDriver) RestoreRecycleItem(ctx context.Context, key string, pat
}

// PurgeRecycleItem as defined in the storage.FS interface
func (nc *StorageDriver) PurgeRecycleItem(ctx context.Context, key string, path string) error {
func (nc *StorageDriver) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
type paramsObj struct {
Key string `json:"key"`
Path string `json:"path"`
}
bodyObj := &paramsObj{
Key: key,
Path: path,
Path: relativePath,
}
bodyStr, _ := json.Marshal(bodyObj)
log := appctx.GetLogger(ctx)
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/fs/nextcloud/nextcloud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ var _ = Describe("Nextcloud", func() {
}
path := "original/location/when/deleted.txt"
key := "asdf"
err := nc.RestoreRecycleItem(ctx, key, path, restoreRef)
err := nc.RestoreRecycleItem(ctx, "/", key, path, restoreRef)
Expect(err).ToNot(HaveOccurred())
checkCalled(called, `POST /apps/sciencemesh/~tester/api/storage/RestoreRecycleItem {"key":"asdf","path":"original/location/when/deleted.txt","restoreRef":{"resource_id":{"storage_id":"storage-id","opaque_id":"opaque-id"},"path":"some/file/path.txt"}}`)
})
Expand All @@ -635,7 +635,7 @@ var _ = Describe("Nextcloud", func() {
defer teardown()
path := "original/location/when/deleted.txt"
key := "asdf"
err := nc.PurgeRecycleItem(ctx, key, path)
err := nc.PurgeRecycleItem(ctx, "/", key, path)
Expect(err).ToNot(HaveOccurred())
checkCalled(called, `POST /apps/sciencemesh/~tester/api/storage/PurgeRecycleItem {"key":"asdf","path":"original/location/when/deleted.txt"}`)
})
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/fs/owncloud/owncloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -2069,7 +2069,7 @@ func (fs *ocfs) RestoreRevision(ctx context.Context, ref *provider.Reference, re
return fs.propagate(ctx, ip)
}

func (fs *ocfs) PurgeRecycleItem(ctx context.Context, key, path string) error {
func (fs *ocfs) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
rp, err := fs.getRecyclePath(ctx)
if err != nil {
return errors.Wrap(err, "ocfs: error resolving recycle path")
Expand Down Expand Up @@ -2189,7 +2189,7 @@ func (fs *ocfs) ListRecycle(ctx context.Context, basePath, key, relativePath str
return items, nil
}

func (fs *ocfs) RestoreRecycleItem(ctx context.Context, key, path string, restoreRef *provider.Reference) error {
func (fs *ocfs) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
// TODO check permission? on what? user must be the owner?
log := appctx.GetLogger(ctx)
rp, err := fs.getRecyclePath(ctx)
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/fs/owncloudsql/owncloudsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ func (fs *owncloudsqlfs) RestoreRevision(ctx context.Context, ref *provider.Refe
return fs.propagate(ctx, ip)
}

func (fs *owncloudsqlfs) PurgeRecycleItem(ctx context.Context, key, path string) error {
func (fs *owncloudsqlfs) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
rp, err := fs.getRecyclePath(ctx)
if err != nil {
return errors.Wrap(err, "owncloudsql: error resolving recycle path")
Expand Down Expand Up @@ -1738,7 +1738,7 @@ func (fs *owncloudsqlfs) ListRecycle(ctx context.Context, basePath, key, relativ
return items, nil
}

func (fs *owncloudsqlfs) RestoreRecycleItem(ctx context.Context, key, path string, restoreRef *provider.Reference) error {
func (fs *owncloudsqlfs) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
log := appctx.GetLogger(ctx)

base, ttime, err := splitTrashKey(key)
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/fs/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ func (fs *s3FS) RestoreRevision(ctx context.Context, ref *provider.Reference, re
return errtypes.NotSupported("restore revision")
}

func (fs *s3FS) PurgeRecycleItem(ctx context.Context, key, path string) error {
func (fs *s3FS) PurgeRecycleItem(ctx context.Context, kbasePath, key, relativePath string) error {
return errtypes.NotSupported("purge recycle item")
}

Expand All @@ -673,7 +673,7 @@ func (fs *s3FS) ListRecycle(ctx context.Context, basePath, key, relativePath str
return nil, errtypes.NotSupported("list recycle")
}

func (fs *s3FS) RestoreRecycleItem(ctx context.Context, key, path string, restoreRef *provider.Reference) error {
func (fs *s3FS) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
return errtypes.NotSupported("restore recycle")
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ type FS interface {
DownloadRevision(ctx context.Context, ref *provider.Reference, key string) (io.ReadCloser, error)
RestoreRevision(ctx context.Context, ref *provider.Reference, key string) error
ListRecycle(ctx context.Context, basePath, key, relativePath string) ([]*provider.RecycleItem, error)
RestoreRecycleItem(ctx context.Context, key, path string, restoreRef *provider.Reference) error
PurgeRecycleItem(ctx context.Context, key, path string) error
RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error
PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error
EmptyRecycle(ctx context.Context) error
GetPathByID(ctx context.Context, id *provider.ResourceId) (string, error)
AddGrant(ctx context.Context, ref *provider.Reference, g *provider.Grant) error
Expand Down
8 changes: 4 additions & 4 deletions pkg/storage/utils/decomposedfs/recycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,11 @@ func (fs *Decomposedfs) listTrashRoot(ctx context.Context) ([]*provider.RecycleI
}

// RestoreRecycleItem restores the specified item
func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, key, path string, restoreRef *provider.Reference) error {
func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
if restoreRef == nil {
restoreRef = &provider.Reference{}
}
rn, p, restoreFunc, err := fs.tp.RestoreRecycleItemFunc(ctx, key, path, restoreRef.Path)
rn, p, restoreFunc, err := fs.tp.RestoreRecycleItemFunc(ctx, key, relativePath, restoreRef.Path)
if err != nil {
return err
}
Expand Down Expand Up @@ -293,8 +293,8 @@ func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, key, path string
}

// PurgeRecycleItem purges the specified item
func (fs *Decomposedfs) PurgeRecycleItem(ctx context.Context, key, path string) error {
rn, purgeFunc, err := fs.tp.PurgeRecycleItemFunc(ctx, key, path)
func (fs *Decomposedfs) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
rn, purgeFunc, err := fs.tp.PurgeRecycleItemFunc(ctx, key, relativePath)
if err != nil {
return err
}
Expand Down
48 changes: 36 additions & 12 deletions pkg/storage/utils/eosfs/eosfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,7 @@ func (fs *eosfs) RestoreRevision(ctx context.Context, ref *provider.Reference, r
return fs.c.RollbackToVersion(ctx, auth, fn, revisionKey)
}

func (fs *eosfs) PurgeRecycleItem(ctx context.Context, key, itemPath string) error {
func (fs *eosfs) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
return errtypes.NotSupported("eosfs: operation not supported")
}

Expand All @@ -1467,11 +1467,7 @@ func (fs *eosfs) EmptyRecycle(ctx context.Context) error {
}

func (fs *eosfs) ListRecycle(ctx context.Context, basePath, key, relativePath string) ([]*provider.RecycleItem, error) {
u, err := getUser(ctx)
if err != nil {
return nil, errors.Wrap(err, "eosfs: no user in ctx")
}
auth, err := fs.getUserAuth(ctx, u, "")
auth, err := fs.getUserAuthForPath(ctx, basePath)
if err != nil {
return nil, err
}
Expand All @@ -1496,19 +1492,47 @@ func (fs *eosfs) ListRecycle(ctx context.Context, basePath, key, relativePath st
return recycleEntries, nil
}

func (fs *eosfs) RestoreRecycleItem(ctx context.Context, key, itemPath string, restoreRef *provider.Reference) error {
u, err := getUser(ctx)
if err != nil {
return errors.Wrap(err, "eosfs: no user in ctx")
}
auth, err := fs.getUserAuth(ctx, u, "")
func (fs *eosfs) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {
auth, err := fs.getUserAuthForPath(ctx, basePath)
if err != nil {
return err
}

return fs.c.RestoreDeletedEntry(ctx, auth, key)
}

func (fs *eosfs) getUserAuthForPath(ctx context.Context, path string) (eosclient.Authorization, error) {
var auth eosclient.Authorization

if !fs.conf.EnableHome && path != "/" {
// We need to list recycle for a non-home reference.
// We'll get the owner of the particular resource and impersonate them
// if we have access to it.
md, err := fs.GetMD(ctx, &provider.Reference{Path: path}, nil)
if err != nil {
return auth, err
}
if md.PermissionSet.ListRecycle {
auth, err = fs.getUIDGateway(ctx, md.Owner)
if err != nil {
return auth, err
}
}
} else {
// We just list the logged-in user's recycle bin
u, err := getUser(ctx)
if err != nil {
return auth, errors.Wrap(err, "eosfs: no user in ctx")
}
auth, err = fs.getUserAuth(ctx, u, "")
if err != nil {
return auth, err
}
}

return auth, nil
}

func (fs *eosfs) ListStorageSpaces(ctx context.Context, filter []*provider.ListStorageSpacesRequest_Filter) ([]*provider.StorageSpace, error) {
return nil, errtypes.NotSupported("list storage spaces")
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/storage/utils/localfs/localfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,7 @@ func (fs *localfs) RestoreRevision(ctx context.Context, ref *provider.Reference,
return fs.propagate(ctx, np)
}

func (fs *localfs) PurgeRecycleItem(ctx context.Context, key, itemPath string) error {
func (fs *localfs) PurgeRecycleItem(ctx context.Context, basePath, key, relativePath string) error {
rp := fs.wrapRecycleBin(ctx, key)

if err := os.Remove(rp); err != nil {
Expand Down Expand Up @@ -1214,7 +1214,7 @@ func (fs *localfs) ListRecycle(ctx context.Context, basePath, key, relativePath
return items, nil
}

func (fs *localfs) RestoreRecycleItem(ctx context.Context, key, itemPath string, restoreRef *provider.Reference) error {
func (fs *localfs) RestoreRecycleItem(ctx context.Context, basePath, key, relativePath string, restoreRef *provider.Reference) error {

suffix := path.Ext(key)
if len(suffix) == 0 || !strings.HasPrefix(suffix, ".d") {
Expand Down

0 comments on commit 8641587

Please sign in to comment.