From 6fb545b3c134caed541696ef440e81bceaf64b8b Mon Sep 17 00:00:00 2001 From: Roman Perekhod Date: Tue, 5 Mar 2024 16:36:26 +0100 Subject: [PATCH] [full-ci] [reva bump] fix an error when lock/unlock a file --- changelog/unreleased/fix-public-link-lock.md | 6 ++ go.mod | 2 +- go.sum | 4 +- ...ected-failures-localAPI-on-OCIS-storage.md | 9 --- .../sharesstorageprovider.go | 35 +++++--- .../storageprovider/storageprovider.go | 24 ++++++ .../services/owncloud/ocdav/errors/error.go | 18 +++++ .../http/services/owncloud/ocdav/locks.go | 79 +++++++++---------- .../cs3org/reva/v2/pkg/errtypes/errtypes.go | 43 +++++++++- vendor/modules.txt | 2 +- 10 files changed, 154 insertions(+), 68 deletions(-) create mode 100644 changelog/unreleased/fix-public-link-lock.md diff --git a/changelog/unreleased/fix-public-link-lock.md b/changelog/unreleased/fix-public-link-lock.md new file mode 100644 index 00000000000..f42eb0b7cf5 --- /dev/null +++ b/changelog/unreleased/fix-public-link-lock.md @@ -0,0 +1,6 @@ +Bugfix: Fix an error when lock/unlock a public shared file + +We fixed a bug when anonymous user with viewer role in public link of a folder can lock/unlock a file inside it + +https://github.com/owncloud/ocis/pull/8472 +https://github.com/owncloud/ocis/issues/7785 diff --git a/go.mod b/go.mod index 3f3ba7815c9..5ea12204fb5 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d + github.com/cs3org/reva/v2 v2.19.2-0.20240307091744-fa2caba1f4e4 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index b438d2f45c4..6bd01aafc83 100644 --- a/go.sum +++ b/go.sum @@ -1019,8 +1019,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d h1:ru/ebNMHDU0SJ9CyzYY9uHMpFXGXT4cDaAh6zib4xPg= -github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= +github.com/cs3org/reva/v2 v2.19.2-0.20240307091744-fa2caba1f4e4 h1:dOApLUv2cYnWU1Z8pqEBk8a9BEGe6VRl/f0sFmwzLw4= +github.com/cs3org/reva/v2 v2.19.2-0.20240307091744-fa2caba1f4e4/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 4e5a90f28ea..8624957ee41 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -238,15 +238,6 @@ The expected failures in this file are from features in the owncloud/ocis repo. - [apiLocks/lockFiles.feature:500](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L500) - [apiLocks/lockFiles.feature:501](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L501) -### [anonymous user with viewer role in public link of a folder can lock a file inside it](https://github.com/owncloud/ocis/issues/7785) - -- [apiLocks/lockFiles.feature:452](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L452) -- [apiLocks/lockFiles.feature:453](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L453) -- [apiLocks/lockFiles.feature:454](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L454) -- [apiLocks/lockFiles.feature:455](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L455) -- [apiLocks/lockFiles.feature:456](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L456) -- [apiLocks/lockFiles.feature:457](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiLocks/lockFiles.feature#L457) - ### [blocksDownload link type is not implemented yet (sharing-ng)](https://github.com/owncloud/ocis/issues/7879) - [apiSharingNg/linkShare.feature:78](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSharingNg/linkShare.feature#L78) diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go index 8d5316c6d93..5fd8db144c3 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go @@ -1057,11 +1057,11 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere return lsRes.Share, lsRes.Status, nil } - // we currently need to list all shares and match the path if the request is relative to the share jail root + // we currently need to list all accepted shares and match the path if the + // request is relative to the share jail root. Also we need to Stat() the + // shared resource's id to check whether that still exist. There might be + // old shares using the same path but for an already vanished resource id. if ref.ResourceId.OpaqueId == utils.ShareStorageProviderID && ref.Path != "." { - // we need to list accepted shares and match the path - - // look up share for this resourceid lsRes, err := sharingCollaborationClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{ Filters: []*collaboration.Filter{ { @@ -1080,15 +1080,32 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere return nil, lsRes.Status, nil } for _, receivedShare := range lsRes.Shares { - // make sure to skip unaccepted shares - if receivedShare.State != collaboration.ShareState_SHARE_STATE_ACCEPTED { - continue - } if isMountPointForPath(receivedShare.MountPoint.Path, ref.Path) { + // Only return this share if the resource still exists. + gatewayClient, err := s.gatewaySelector.Next() + if err != nil { + return nil, nil, err + } + sRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{ + Ref: &provider.Reference{ResourceId: receivedShare.GetShare().GetResourceId()}, + }) + if err != nil { + appctx.GetLogger(ctx).Debug(). + Err(err). + Interface("resourceID", receivedShare.GetShare().GetResourceId()). + Msg("resolveAcceptedShare: failed to stat shared resource") + continue + } + if sRes.Status.Code != rpc.Code_CODE_OK { + appctx.GetLogger(ctx).Debug(). + Interface("resourceID", receivedShare.GetShare().GetResourceId()). + Interface("status", sRes.Status). + Msg("resolveAcceptedShare: failed to stat shared resource") + continue + } return receivedShare, lsRes.Status, nil } } - } return nil, status.NewNotFound(ctx, "sharesstorageprovider: not found "+ref.String()), nil diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go index c125698c0b9..2a9982d2e8c 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go @@ -33,6 +33,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" "github.com/cs3org/reva/v2/pkg/appctx" + "github.com/cs3org/reva/v2/pkg/conversions" ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/errtypes" "github.com/cs3org/reva/v2/pkg/events" @@ -230,6 +231,11 @@ func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.Unse // SetLock puts a lock on the given reference func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*provider.SetLockResponse, error) { + if !canLockPublicShare(ctx) { + return &provider.SetLockResponse{ + Status: status.NewPermissionDenied(ctx, nil, "no permission to lock the share"), + }, nil + } err := s.storage.SetLock(ctx, req.Ref, req.Lock) return &provider.SetLockResponse{ @@ -249,6 +255,12 @@ func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*p // RefreshLock refreshes an existing lock on the given reference func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequest) (*provider.RefreshLockResponse, error) { + if !canLockPublicShare(ctx) { + return &provider.RefreshLockResponse{ + Status: status.NewPermissionDenied(ctx, nil, "no permission to refresh the share lock"), + }, nil + } + err := s.storage.RefreshLock(ctx, req.Ref, req.Lock, req.ExistingLockId) return &provider.RefreshLockResponse{ @@ -258,6 +270,12 @@ func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequ // Unlock removes an existing lock from the given reference func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provider.UnlockResponse, error) { + if !canLockPublicShare(ctx) { + return &provider.UnlockResponse{ + Status: status.NewPermissionDenied(ctx, nil, "no permission to unlock the share"), + }, nil + } + err := s.storage.Unlock(ctx, req.Ref, req.Lock) return &provider.UnlockResponse{ @@ -1285,3 +1303,9 @@ func estreamFromConfig(c eventconfig) (events.Stream, error) { return stream.NatsFromConfig("storageprovider", false, stream.NatsConfig(c)) } + +func canLockPublicShare(ctx context.Context) bool { + u := ctxpkg.ContextMustGetUser(ctx) + psr := utils.ReadPlainFromOpaque(u.Opaque, "public-share-role") + return psr == "" || psr == conversions.RoleEditor +} diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors/error.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors/error.go index 78df1d19835..adf55e589c7 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors/error.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors/error.go @@ -21,6 +21,7 @@ package errors import ( "bytes" "encoding/xml" + "fmt" "net/http" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" @@ -193,3 +194,20 @@ func HandleWebdavError(log *zerolog.Logger, w http.ResponseWriter, b []byte, err log.Err(err).Msg("error writing response") } } + +func NewErrFromStatus(s *rpc.Status) error { + switch s.GetCode() { + case rpc.Code_CODE_OK: + return nil + case rpc.Code_CODE_DEADLINE_EXCEEDED: + return ErrInvalidTimeout + case rpc.Code_CODE_PERMISSION_DENIED: + return ErrForbidden + case rpc.Code_CODE_LOCKED, rpc.Code_CODE_FAILED_PRECONDITION: + return ErrLocked + case rpc.Code_CODE_UNIMPLEMENTED: + return ErrNotImplemented + default: + return fmt.Errorf(s.GetMessage()) + } +} diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go index 332b9d22760..6760bfd90d7 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/locks.go @@ -21,6 +21,7 @@ package ocdav import ( "context" "encoding/xml" + "errors" "fmt" "io" "net/http" @@ -34,13 +35,12 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors" + ocdavErrors "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/prop" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup" "github.com/cs3org/reva/v2/pkg/appctx" ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" - "github.com/cs3org/reva/v2/pkg/errtypes" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" "github.com/cs3org/reva/v2/pkg/utils" "github.com/google/uuid" @@ -172,7 +172,7 @@ type cs3LS struct { } func (cls *cs3LS) Confirm(ctx context.Context, now time.Time, name0, name1 string, conditions ...Condition) (func(), error) { - return nil, errors.ErrNotImplemented + return nil, ocdavErrors.ErrNotImplemented } func (cls *cs3LS) Create(ctx context.Context, now time.Time, details LockDetails) (string, error) { @@ -180,7 +180,7 @@ func (cls *cs3LS) Create(ctx context.Context, now time.Time, details LockDetails /* if !details.ZeroDepth { The CS3 Lock api currently has no depth property, it only locks single resources - return "", errors.ErrUnsupportedLockInfo + return "", ocdavErrors.ErrUnsupportedLockInfo } */ @@ -225,20 +225,19 @@ func (cls *cs3LS) Create(ctx context.Context, now time.Time, details LockDetails if err != nil { return "", err } - switch res.Status.Code { + switch res.GetStatus().GetCode() { case rpc.Code_CODE_OK: return lockTokenPrefix + token.String(), nil - case rpc.Code_CODE_FAILED_PRECONDITION: - return "", errtypes.Aborted("file is already locked") default: - return "", errtypes.NewErrtypeFromStatus(res.Status) + return "", ocdavErrors.NewErrFromStatus(res.GetStatus()) } } func (cls *cs3LS) Refresh(ctx context.Context, now time.Time, token string, duration time.Duration) (LockDetails, error) { - return LockDetails{}, errors.ErrNotImplemented + return LockDetails{}, ocdavErrors.ErrNotImplemented } + func (cls *cs3LS) Unlock(ctx context.Context, now time.Time, ref *provider.Reference, token string) error { u := ctxpkg.ContextMustGetUser(ctx) @@ -260,14 +259,11 @@ func (cls *cs3LS) Unlock(ctx context.Context, now time.Time, ref *provider.Refer return err } - switch res.Status.Code { - case rpc.Code_CODE_OK: - return nil - case rpc.Code_CODE_FAILED_PRECONDITION: - return errtypes.Aborted("file is not locked") - default: - return errtypes.NewErrtypeFromStatus(res.Status) + newErr := ocdavErrors.NewErrFromStatus(res.GetStatus()) + if newErr != nil { + appctx.GetLogger(ctx).Error().Str("token", token).Interface("unlock", ref).Msg("could not unlock " + res.GetStatus().GetMessage()) } + return newErr } // LockDetails are a lock's metadata. @@ -302,7 +298,7 @@ func readLockInfo(r io.Reader) (li lockInfo, status int, err error) { // http://www.webdav.org/specs/rfc4918.html#refreshing-locks return lockInfo{}, 0, nil } - err = errors.ErrInvalidLockInfo + err = ocdavErrors.ErrInvalidLockInfo } return lockInfo{}, http.StatusBadRequest, err } @@ -349,15 +345,15 @@ func parseTimeout(s string) (time.Duration, error) { } const pre = "Second-" if !strings.HasPrefix(s, pre) { - return 0, errors.ErrInvalidTimeout + return 0, ocdavErrors.ErrInvalidTimeout } s = s[len(pre):] if s == "" || s[0] < '0' || '9' < s[0] { - return 0, errors.ErrInvalidTimeout + return 0, ocdavErrors.ErrInvalidTimeout } n, err := strconv.ParseInt(s, 10, 64) if err != nil || 1<<32-1 < n { - return 0, errors.ErrInvalidTimeout + return 0, ocdavErrors.ErrInvalidTimeout } return time.Duration(n) * time.Second, nil } @@ -420,7 +416,7 @@ func (s *svc) handleLock(w http.ResponseWriter, r *http.Request, ns string) (ret return http.StatusInternalServerError, err } if cs3Status.Code != rpc.Code_CODE_OK { - return http.StatusInternalServerError, errtypes.NewErrtypeFromStatus(cs3Status) + return http.StatusInternalServerError, ocdavErrors.NewErrFromStatus(cs3Status) } return s.lockReference(ctx, w, r, ref) @@ -444,12 +440,12 @@ func (s *svc) lockReference(ctx context.Context, w http.ResponseWriter, r *http. sublog := appctx.GetLogger(ctx).With().Interface("ref", ref).Logger() duration, err := parseTimeout(r.Header.Get(net.HeaderTimeout)) if err != nil { - return http.StatusBadRequest, errors.ErrInvalidTimeout + return http.StatusBadRequest, ocdavErrors.ErrInvalidTimeout } li, status, err := readLockInfo(r.Body) if err != nil { - return status, errors.ErrInvalidLockInfo + return status, ocdavErrors.ErrInvalidLockInfo } u := ctxpkg.ContextMustGetUser(ctx) @@ -459,17 +455,17 @@ func (s *svc) lockReference(ctx context.Context, w http.ResponseWriter, r *http. // An empty lockInfo means to refresh the lock. ih, ok := parseIfHeader(r.Header.Get(net.HeaderIf)) if !ok { - return http.StatusBadRequest, errors.ErrInvalidIfHeader + return http.StatusBadRequest, ocdavErrors.ErrInvalidIfHeader } if len(ih.lists) == 1 && len(ih.lists[0].conditions) == 1 { token = ih.lists[0].conditions[0].Token } if token == "" { - return http.StatusBadRequest, errors.ErrInvalidLockToken + return http.StatusBadRequest, ocdavErrors.ErrInvalidLockToken } ld, err = s.LockSystem.Refresh(ctx, now, token, duration) if err != nil { - if err == errors.ErrNoSuchLock { + if err == ocdavErrors.ErrNoSuchLock { return http.StatusPreconditionFailed, err } return http.StatusInternalServerError, err @@ -484,7 +480,7 @@ func (s *svc) lockReference(ctx context.Context, w http.ResponseWriter, r *http. if depth != 0 && depth != infiniteDepth { // Section 9.10.3 says that "Values other than 0 or infinity must not be // used with the Depth header on a LOCK method". - return http.StatusBadRequest, errors.ErrInvalidDepth + return http.StatusBadRequest, ocdavErrors.ErrInvalidDepth } } /* our url path has been shifted, so we don't need to do this? @@ -505,15 +501,16 @@ func (s *svc) lockReference(ctx context.Context, w http.ResponseWriter, r *http. // should we do that in the decomposedfs as well? the node does not exist // this actually is a name based lock ... ugh token, err = s.LockSystem.Create(ctx, now, ld) + + // if err != nil { - switch err.(type) { - case errtypes.Aborted: + switch { + case errors.Is(err, ocdavErrors.ErrLocked): return http.StatusLocked, err - case errtypes.PermissionDenied: + case errors.Is(err, ocdavErrors.ErrForbidden): return http.StatusForbidden, err default: return http.StatusInternalServerError, err - } } @@ -611,7 +608,7 @@ func (s *svc) handleUnlock(w http.ResponseWriter, r *http.Request, ns string) (s return http.StatusInternalServerError, err } if cs3Status.Code != rpc.Code_CODE_OK { - return http.StatusInternalServerError, errtypes.NewErrtypeFromStatus(cs3Status) + return http.StatusInternalServerError, ocdavErrors.NewErrFromStatus(cs3Status) } return s.unlockReference(ctx, w, r, ref) @@ -639,16 +636,14 @@ func (s *svc) unlockReference(ctx context.Context, _ http.ResponseWriter, r *htt t = t[1 : len(t)-1] } - switch err := s.LockSystem.Unlock(ctx, time.Now(), ref, t); err { - case nil: - return http.StatusNoContent, err - case errors.ErrForbidden: - return http.StatusForbidden, err - case errors.ErrLocked: + err := s.LockSystem.Unlock(ctx, time.Now(), ref, t) + switch { + case err == nil: + return http.StatusNoContent, nil + case errors.Is(err, ocdavErrors.ErrLocked): return http.StatusLocked, err - case errors.ErrNoSuchLock: - return http.StatusConflict, err - default: - return http.StatusInternalServerError, err + case errors.Is(err, ocdavErrors.ErrForbidden): + return http.StatusForbidden, err } + return http.StatusInternalServerError, err } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/errtypes/errtypes.go b/vendor/github.com/cs3org/reva/v2/pkg/errtypes/errtypes.go index 4aff2129312..07266f1184c 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/errtypes/errtypes.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/errtypes/errtypes.go @@ -295,12 +295,13 @@ func NewErrtypeFromStatus(status *rpc.Status) error { case rpc.Code_CODE_UNIMPLEMENTED: return NotSupported(status.Message) case rpc.Code_CODE_PERMISSION_DENIED: - // FIXME add locked status! - if strings.HasPrefix(status.Message, "set lock: error: locked by ") { - return Locked(strings.TrimPrefix(status.Message, "set lock: error: locked by ")) - } return PermissionDenied(status.Message) case rpc.Code_CODE_LOCKED: + // FIXME make something better for that + msg := strings.Split(status.Message, "error: locked by ") + if len(msg) > 1 { + return Locked(msg[len(msg)-1]) + } return Locked(status.Message) // case rpc.Code_CODE_DATA_LOSS: ? // IsPartialContent @@ -350,3 +351,37 @@ func NewErrtypeFromHTTPStatusCode(code int, message string) error { return InternalError(message) } } + +// NewHTTPStatusCodeFromErrtype maps an errtype to an http status +func NewHTTPStatusCodeFromErrtype(err error) int { + switch err.(type) { + case NotFound: + return http.StatusNotFound + case AlreadyExists: + return http.StatusConflict + case NotSupported: + return http.StatusNotImplemented + case NotModified: + return http.StatusNotModified + case InvalidCredentials: + return http.StatusUnauthorized + case PermissionDenied: + return http.StatusForbidden + case Locked: + return http.StatusLocked + case Aborted: + return http.StatusPreconditionFailed + case PreconditionFailed: + return http.StatusMethodNotAllowed + case InsufficientStorage: + return http.StatusInsufficientStorage + case BadRequest: + return http.StatusBadRequest + case PartialContent: + return http.StatusPartialContent + case ChecksumMismatch: + return StatusChecksumMismatch + default: + return http.StatusInternalServerError + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index cf2f6531ae6..6e51d387e1f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -359,7 +359,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.19.2-0.20240307063856-698d86209c3d +# github.com/cs3org/reva/v2 v2.19.2-0.20240307091744-fa2caba1f4e4 ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime