Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement touch file #2369

Merged
merged 5 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-add-touch-file.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Implement TouchFile from the CS3apis

We've updated the CS3apis and implemented the TouchFile method.

https://github.com/cs3org/reva/pull/2369
https://github.com/cs3org/cs3apis/pull/154
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/cheggaaa/pb v1.0.29
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e
github.com/cs3org/go-cs3apis v0.0.0-20211104090126-8e972dca8304
github.com/cs3org/go-cs3apis v0.0.0-20211213090556-12c0d565f51d
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8
github.com/eventials/go-tus v0.0.0-20200718001131-45c7ec8f5d59
github.com/gdexlab/go-render v1.0.1
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJffz4pz0o1WuQxJ28+5x5JgaHD8=
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
github.com/cs3org/go-cs3apis v0.0.0-20210325133324-32b03d75a535 h1:555D8A3ddKqb4OyK9v5mdphw2zDLWKGXOkcnf1RQwTA=
github.com/cs3org/go-cs3apis v0.0.0-20210325133324-32b03d75a535/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/go-cs3apis v0.0.0-20211104090126-8e972dca8304 h1:e/nIPR518vyvrulo9goAZTtYD6gFfu/2/9MDe6mTGcw=
github.com/cs3org/go-cs3apis v0.0.0-20211104090126-8e972dca8304/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/go-cs3apis v0.0.0-20211213090556-12c0d565f51d h1:gnb2ciU4N+RwUug/nwe54wenWi7vSp5bAAjXINlgHZ8=
github.com/cs3org/go-cs3apis v0.0.0-20211213090556-12c0d565f51d/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
2 changes: 2 additions & 0 deletions internal/grpc/interceptors/auth/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ func extractRef(req interface{}, hasEditorRole bool) (*provider.Reference, bool)
// Write Requests
case *provider.CreateContainerRequest:
return v.GetRef(), true
case *provider.TouchFileRequest:
return v.GetRef(), true
case *provider.DeleteRequest:
return v.GetRef(), true
case *provider.MoveRequest:
Expand Down
6 changes: 5 additions & 1 deletion internal/grpc/interceptors/readonly/readonly.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ func NewUnary(map[string]interface{}) (grpc.UnaryServerInterceptor, int, error)
}, nil
case *provider.CreateContainerRequest:
return &provider.CreateContainerResponse{
Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create resoure on readonly storage"),
Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create ressource on readonly storage"),
wkloucek marked this conversation as resolved.
Show resolved Hide resolved
}, nil
case *provider.TouchFileRequest:
return &provider.TouchFileResponse{
Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create ressource on readonly storage"),
wkloucek marked this conversation as resolved.
Show resolved Hide resolved
}, nil
case *provider.CreateHomeRequest:
return &provider.CreateHomeResponse{
Expand Down
19 changes: 19 additions & 0 deletions internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,25 @@ func (s *svc) createContainer(ctx context.Context, req *provider.CreateContainer
return res, nil
}

func (s *svc) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) {
c, err := s.find(ctx, req.Ref)
if err != nil {
return &provider.TouchFileResponse{
Status: status.NewStatusFromErrType(ctx, "TouchFile ref="+req.Ref.String(), err),
}, nil
}

res, err := c.TouchFile(ctx, req)
if err != nil {
if gstatus.Code(err) == codes.PermissionDenied {
return &provider.TouchFileResponse{Status: &rpc.Status{Code: rpc.Code_CODE_PERMISSION_DENIED}}, nil
}
return nil, errors.Wrap(err, "gateway: error calling TouchFile")
}

return res, nil
}

// check if the path contains the prefix of the shared folder
func (s *svc) inSharedFolder(ctx context.Context, p string) bool {
sharedFolder := s.getSharedFolder(ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,19 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta
return res, nil
}

func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) {
ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref)
switch {
case err != nil:
return nil, err
case st != nil:
return &provider.TouchFileResponse{
Status: st,
}, nil
}
return s.gateway.TouchFile(ctx, &provider.TouchFileRequest{Opaque: req.Opaque, Ref: ref})
}

func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) {
ctx, span := rtrace.Provider.Tracer("publicstorageprovider").Start(ctx, "Delete")
defer span.End()
Expand Down
30 changes: 30 additions & 0 deletions internal/grpc/services/storageprovider/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,36 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta
return res, nil
}

func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) {
newRef, err := s.unwrap(ctx, req.Ref)
if err != nil {
return &provider.TouchFileResponse{
Status: status.NewInternal(ctx, err, "error unwrapping path"),
}, nil
}
if err := s.storage.TouchFile(ctx, newRef); err != nil {
var st *rpc.Status
switch err.(type) {
case errtypes.IsNotFound:
st = status.NewNotFound(ctx, "path not found when touching the file")
case errtypes.AlreadyExists:
st = status.NewAlreadyExists(ctx, err, "file already exists")
case errtypes.PermissionDenied:
st = status.NewPermissionDenied(ctx, err, "permission denied")
default:
st = status.NewInternal(ctx, err, "error touching file: "+req.Ref.String())
}
return &provider.TouchFileResponse{
Status: st,
}, nil
}

res := &provider.TouchFileResponse{
Status: status.NewOK(ctx),
}
return res, nil
}

func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) {
newRef, err := s.unwrap(ctx, req.Ref)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/auth/scope/publicshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func publicshareScope(ctx context.Context, scope *authpb.Scope, resource interfa
// need to return appropriate status codes in the ocs/ocdav layers.
case *provider.CreateContainerRequest:
return hasRoleEditor(*scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
case *provider.TouchFileRequest:
return hasRoleEditor(*scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
case *provider.DeleteRequest:
return hasRoleEditor(*scope) && checkStorageRef(ctx, &share, v.GetRef()), nil
case *provider.MoveRequest:
Expand Down
2 changes: 2 additions & 0 deletions pkg/auth/scope/resourceinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func resourceinfoScope(_ context.Context, scope *authpb.Scope, resource interfac
// need to return appropriate status codes in the ocs/ocdav layers.
case *provider.CreateContainerRequest:
return hasRoleEditor(*scope) && checkResourceInfo(&r, v.GetRef()), nil
case *provider.TouchFileRequest:
return hasRoleEditor(*scope) && checkResourceInfo(&r, v.GetRef()), nil
case *provider.DeleteRequest:
return hasRoleEditor(*scope) && checkResourceInfo(&r, v.GetRef()), nil
case *provider.MoveRequest:
Expand Down
2 changes: 2 additions & 0 deletions pkg/auth/scope/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func shareScope(_ context.Context, scope *authpb.Scope, resource interface{}, lo
// need to return appropriate status codes in the ocs/ocdav layers.
case *provider.CreateContainerRequest:
return checkShareStorageRef(&share, v.GetRef()), nil
case *provider.TouchFileRequest:
return checkShareStorageRef(&share, v.GetRef()), nil
case *provider.DeleteRequest:
return checkShareStorageRef(&share, v.GetRef()), nil
case *provider.MoveRequest:
Expand Down
5 changes: 5 additions & 0 deletions pkg/storage/fs/nextcloud/nextcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ func (nc *StorageDriver) CreateDir(ctx context.Context, ref *provider.Reference)
return err
}

// TouchFile as defined in the storage.FS interface
func (nc *StorageDriver) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

// Delete as defined in the storage.FS interface
func (nc *StorageDriver) Delete(ctx context.Context, ref *provider.Reference) error {
bodyStr, err := json.Marshal(ref)
Expand Down
5 changes: 5 additions & 0 deletions pkg/storage/fs/owncloud/owncloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,11 @@ func (fs *ocfs) CreateDir(ctx context.Context, ref *provider.Reference) (err err
return fs.propagate(ctx, ip)
}

// TouchFile as defined in the storage.FS interface
func (fs *ocfs) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

func (fs *ocfs) isShareFolderChild(sp string) bool {
return strings.HasPrefix(sp, fs.c.ShareFolder)
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/storage/fs/owncloudsql/owncloudsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,11 @@ func (fs *owncloudsqlfs) CreateDir(ctx context.Context, ref *provider.Reference)
return fs.propagate(ctx, filepath.Dir(ip))
}

// TouchFile as defined in the storage.FS interface
func (fs *owncloudsqlfs) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

func (fs *owncloudsqlfs) CreateReference(ctx context.Context, sp string, targetURI *url.URL) error {
return errtypes.NotSupported("owncloudsql: operation not supported")
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/storage/fs/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ func (fs *s3FS) CreateDir(ctx context.Context, ref *provider.Reference) error {
return nil
}

// TouchFile as defined in the storage.FS interface
func (fs *s3FS) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

func (fs *s3FS) Delete(ctx context.Context, ref *provider.Reference) error {
log := appctx.GetLogger(ctx)

Expand Down
1 change: 1 addition & 0 deletions pkg/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type FS interface {
GetHome(ctx context.Context) (string, error)
CreateHome(ctx context.Context) error
CreateDir(ctx context.Context, ref *provider.Reference) error
TouchFile(ctx context.Context, ref *provider.Reference) error
Delete(ctx context.Context, ref *provider.Reference) error
Move(ctx context.Context, oldRef, newRef *provider.Reference) error
GetMD(ctx context.Context, ref *provider.Reference, mdKeys []string) (*provider.ResourceInfo, error)
Expand Down
6 changes: 6 additions & 0 deletions pkg/storage/utils/decomposedfs/decomposedfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package decomposedfs

import (
"context"
"fmt"
"io"
"net/url"
"os"
Expand Down Expand Up @@ -320,6 +321,11 @@ func (fs *Decomposedfs) CreateDir(ctx context.Context, ref *provider.Reference)
return
}

// TouchFile as defined in the storage.FS interface
func (fs *Decomposedfs) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

// CreateReference creates a reference as a node folder with the target stored in extended attributes
// There is no difference between the /Shares folder and normal nodes because the storage is not supposed to be accessible without the storage provider.
// In effect everything is a shadow namespace.
Expand Down
23 changes: 23 additions & 0 deletions pkg/storage/utils/eosfs/eosfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,29 @@ func (fs *eosfs) CreateDir(ctx context.Context, ref *provider.Reference) error {
return fs.c.CreateDir(ctx, auth, fn)
}

// TouchFile as defined in the storage.FS interface
func (fs *eosfs) TouchFile(ctx context.Context, ref *provider.Reference) error {
log := appctx.GetLogger(ctx)
u, err := getUser(ctx)
if err != nil {
return errors.Wrap(err, "eosfs: no user in ctx")
}
p, err := fs.resolve(ctx, ref)
if err != nil {
return nil
}

auth, err := fs.getUserAuth(ctx, u, p)
if err != nil {
return err
}

log.Info().Msgf("eosfs: touch file: path=%s", p)

fn := fs.wrap(ctx, p)
return fs.c.Touch(ctx, auth, fn)
}

func (fs *eosfs) CreateReference(ctx context.Context, p string, targetURI *url.URL) error {
// TODO(labkode): for the time being we only allow creating references
// in the virtual share folder to not pollute the nominal user tree.
Expand Down
5 changes: 5 additions & 0 deletions pkg/storage/utils/localfs/localfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,11 @@ func (fs *localfs) CreateDir(ctx context.Context, ref *provider.Reference) error
return fs.propagate(ctx, path.Dir(fn))
}

// TouchFile as defined in the storage.FS interface
func (fs *localfs) TouchFile(ctx context.Context, ref *provider.Reference) error {
return fmt.Errorf("unimplemented: TouchFile")
}

func (fs *localfs) Delete(ctx context.Context, ref *provider.Reference) error {
fn, err := fs.resolve(ctx, ref)
if err != nil {
Expand Down