diff --git a/changelog/unreleased/refresh-lock-improvements.md b/changelog/unreleased/refresh-lock-improvements.md new file mode 100644 index 00000000000..52637c8d976 --- /dev/null +++ b/changelog/unreleased/refresh-lock-improvements.md @@ -0,0 +1,6 @@ +Enhancement: Make Refresh Lock operation WOPI compliant + +We now support the WOPI compliant `UnlockAndRelock` operation. This has been implemented in the DecomposedFS. To make use of it, we need a compatible WOPI server. + +https://github.com/cs3org/reva/pull/3286 +https://learn.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/unlockandrelock diff --git a/internal/grpc/services/storageprovider/storageprovider.go b/internal/grpc/services/storageprovider/storageprovider.go index bba333ad7a5..2129e930f0b 100644 --- a/internal/grpc/services/storageprovider/storageprovider.go +++ b/internal/grpc/services/storageprovider/storageprovider.go @@ -354,7 +354,7 @@ func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequ }, nil } - if err = s.storage.RefreshLock(ctx, newRef, req.Lock); err != nil { + if err = s.storage.RefreshLock(ctx, newRef, req.Lock, req.ExistingLockId); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: diff --git a/pkg/storage/fs/nextcloud/nextcloud.go b/pkg/storage/fs/nextcloud/nextcloud.go index bb8f7ff5555..71c36173735 100644 --- a/pkg/storage/fs/nextcloud/nextcloud.go +++ b/pkg/storage/fs/nextcloud/nextcloud.go @@ -781,7 +781,7 @@ func (nc *StorageDriver) SetLock(ctx context.Context, ref *provider.Reference, l } // RefreshLock refreshes an existing lock on the given reference -func (nc *StorageDriver) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { +func (nc *StorageDriver) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error { return errtypes.NotSupported("unimplemented") } diff --git a/pkg/storage/fs/owncloudsql/owncloudsql.go b/pkg/storage/fs/owncloudsql/owncloudsql.go index b64d688a309..ebf2796c496 100644 --- a/pkg/storage/fs/owncloudsql/owncloudsql.go +++ b/pkg/storage/fs/owncloudsql/owncloudsql.go @@ -1035,7 +1035,7 @@ func (fs *owncloudsqlfs) SetLock(ctx context.Context, ref *provider.Reference, l } // RefreshLock refreshes an existing lock on the given reference -func (fs *owncloudsqlfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { +func (fs *owncloudsqlfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error { return errtypes.NotSupported("unimplemented") } diff --git a/pkg/storage/fs/s3/s3.go b/pkg/storage/fs/s3/s3.go index b777697e648..32a90fe4283 100644 --- a/pkg/storage/fs/s3/s3.go +++ b/pkg/storage/fs/s3/s3.go @@ -291,7 +291,7 @@ func (fs *s3FS) SetLock(ctx context.Context, ref *provider.Reference, lock *prov } // RefreshLock refreshes an existing lock on the given reference -func (fs *s3FS) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { +func (fs *s3FS) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error { return errtypes.NotSupported("unimplemented") } diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index b8af0eeb1aa..ebec63a004e 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -60,7 +60,7 @@ type FS interface { UnsetArbitraryMetadata(ctx context.Context, ref *provider.Reference, keys []string) error SetLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error GetLock(ctx context.Context, ref *provider.Reference) (*provider.Lock, error) - RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error + RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error Unlock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error ListStorageSpaces(ctx context.Context, filter []*provider.ListStorageSpacesRequest_Filter) ([]*provider.StorageSpace, error) CreateStorageSpace(ctx context.Context, req *provider.CreateStorageSpaceRequest) (*provider.CreateStorageSpaceResponse, error) diff --git a/pkg/storage/utils/decomposedfs/decomposedfs.go b/pkg/storage/utils/decomposedfs/decomposedfs.go index 33dadb0d06f..427a429a74a 100644 --- a/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -538,7 +538,7 @@ func (fs *Decomposedfs) SetLock(ctx context.Context, ref *provider.Reference, lo } // RefreshLock refreshes an existing lock on the given reference -func (fs *Decomposedfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { +func (fs *Decomposedfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error { return errtypes.NotSupported("unimplemented") } diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 197bbcf1da6..64f8981b25d 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -869,9 +869,7 @@ func encodeLock(l *provider.Lock) (string, error) { } // RefreshLock refreshes an existing lock on the given reference -func (fs *eosfs) RefreshLock(ctx context.Context, ref *provider.Reference, newLock *provider.Lock) error { - // TODO (gdelmont): check if the new lock is already expired? - +func (fs *eosfs) RefreshLock(ctx context.Context, ref *provider.Reference, newLock *provider.Lock, existingLockID string) error { if newLock.Type == provider.LockType_LOCK_TYPE_SHARED { return errtypes.NotSupported("shared lock not yet implemented") } @@ -897,6 +895,10 @@ func (fs *eosfs) RefreshLock(ctx context.Context, ref *provider.Reference, newLo return errtypes.BadRequest("caller does not hold the lock") } + if existingLockID != "" && oldLock.LockId != existingLockID { + return errtypes.BadRequest("mismatching existing lock id") + } + path, err := fs.resolve(ctx, ref) if err != nil { return errors.Wrap(err, "eosfs: error resolving reference") diff --git a/pkg/storage/utils/localfs/localfs.go b/pkg/storage/utils/localfs/localfs.go index 7673ee45774..f7e6abdc59c 100644 --- a/pkg/storage/utils/localfs/localfs.go +++ b/pkg/storage/utils/localfs/localfs.go @@ -722,7 +722,7 @@ func (fs *localfs) SetLock(ctx context.Context, ref *provider.Reference, lock *p } // RefreshLock refreshes an existing lock on the given reference -func (fs *localfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { +func (fs *localfs) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error { return errtypes.NotSupported("unimplemented") }