Skip to content

Commit

Permalink
fix remove/update share permissions when the file is locked
Browse files Browse the repository at this point in the history
  • Loading branch information
2403905 committed Feb 23, 2024
1 parent 6d5a4d7 commit 41588ef
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/fix-remove-update-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Bugfix: Fix remove/update share permissions

This is a workaround that should prevent removing or changing the share permissions when the file is locked.
These limitations have to be removed after the wopi server will be able to unlock the file properly.
These limitations are not spread on the files inside the shared folder.

https://github.com/cs3org/reva/pull/4534
https://github.com/owncloud/ocis/issues/8273
67 changes: 67 additions & 0 deletions internal/grpc/services/gateway/usershareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ func (s *svc) ListShares(ctx context.Context, req *collaboration.ListSharesReque
}

func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareRequest) (*collaboration.UpdateShareResponse, error) {
// TODO: update wopi server
// FIXME This is a workaround that should prevent removing or changing the share permissions when the file is locked.
// https://github.com/owncloud/ocis/issues/8474
if status, err := s.checkLock(ctx, req.GetShare().GetId()); err != nil {
return &collaboration.UpdateShareResponse{
Status: status,
}, nil
}

c, err := pool.GetUserShareProviderClient(s.c.UserShareProviderEndpoint)
if err != nil {
appctx.GetLogger(ctx).
Expand Down Expand Up @@ -657,6 +666,15 @@ func (s *svc) removeShare(ctx context.Context, req *collaboration.RemoveShareReq
share = getShareRes.Share
}

// TODO: update wopi server
// FIXME This is a workaround that should prevent removing or changing the share permissions when the file is locked.
// https://github.com/owncloud/ocis/issues/8474
if status, err := s.checkShareLock(ctx, share); err != nil {
return &collaboration.RemoveShareResponse{
Status: status,
}, nil
}

res, err := c.RemoveShare(ctx, req)
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling RemoveShare")
Expand Down Expand Up @@ -712,6 +730,55 @@ func (s *svc) removeSpaceShare(ctx context.Context, ref *provider.ResourceId, gr
return &collaboration.RemoveShareResponse{Status: status.NewOK(ctx)}, nil
}

func (s *svc) checkLock(ctx context.Context, shareId *collaboration.ShareId) (*rpc.Status, error) {
logger := appctx.GetLogger(ctx)
getShareRes, err := s.GetShare(ctx, &collaboration.GetShareRequest{
Ref: &collaboration.ShareReference{
Spec: &collaboration.ShareReference_Id{Id: shareId},
},
})
if err != nil {
msg := "gateway: error calling GetShare"
logger.Err(err).Interface("share_id", shareId).Msg(msg)
return status.NewInternal(ctx, msg), errors.Wrap(err, msg)
}
if getShareRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
msg := "can not get share stat " + getShareRes.GetStatus().GetMessage()
logger.Debug().Interface("share", shareId).Msg(msg)
if getShareRes.GetStatus().GetCode() != rpc.Code_CODE_NOT_FOUND {
return status.NewNotFound(ctx, msg), errors.New(msg)
}
return status.NewInternal(ctx, msg), errors.New(msg)
}
return s.checkShareLock(ctx, getShareRes.Share)
}

func (s *svc) checkShareLock(ctx context.Context, share *collaboration.Share) (*rpc.Status, error) {
logger := appctx.GetLogger(ctx)
sRes, err := s.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: share.GetResourceId()},
ArbitraryMetadataKeys: []string{"lockdiscovery"}})
if err != nil {
msg := "failed to stat shared resource"
logger.Err(err).Interface("resource_id", share.GetResourceId()).Msg(msg)
return status.NewInternal(ctx, msg), errors.Wrap(err, msg)
}
if sRes.GetStatus().GetCode() != rpc.Code_CODE_OK {
msg := "can not get share stat " + sRes.GetStatus().GetMessage()
logger.Debug().Interface("lock", sRes.GetInfo().GetLock()).Msg(msg)
if sRes.GetStatus().GetCode() != rpc.Code_CODE_NOT_FOUND {
return status.NewNotFound(ctx, msg), errors.New(msg)
}
return status.NewInternal(ctx, msg), errors.New(msg)
}

if sRes.GetInfo().GetLock() != nil {
msg := "can not chane grants, the shared resource is locked"
logger.Debug().Interface("lock", sRes.GetInfo().GetLock()).Msg(msg)
return status.NewLocked(ctx, msg), errors.New(msg)
}
return nil, nil
}

func refIsSpaceRoot(ref *provider.ResourceId) bool {
if ref == nil {
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,9 +850,13 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, share *col
}

if uRes.Status.Code != rpc.Code_CODE_OK {
if uRes.Status.Code == rpc.Code_CODE_NOT_FOUND {
switch uRes.Status.Code {
case rpc.Code_CODE_NOT_FOUND:
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil)
return
case rpc.Code_CODE_LOCKED:
response.WriteOCSError(w, r, response.MetaLocked.StatusCode, uRes.GetStatus().GetMessage(), nil)
return
}
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc update share request failed", err)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,13 @@ func (h *Handler) removeUserShare(w http.ResponseWriter, r *http.Request, share
}

if uRes.Status.Code != rpc.Code_CODE_OK {
if uRes.Status.Code == rpc.Code_CODE_NOT_FOUND {
switch uRes.Status.Code {
case rpc.Code_CODE_NOT_FOUND:
response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil)
return
case rpc.Code_CODE_LOCKED:
response.WriteOCSError(w, r, response.MetaLocked.StatusCode, uRes.GetStatus().GetMessage(), nil)
return
}
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc delete share request failed", err)
return
Expand Down
1 change: 1 addition & 0 deletions pkg/storage/utils/decomposedfs/node/locks.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ func readLocksIntoOpaque(ctx context.Context, n *Node, ri *provider.ResourceInfo
Decoder: "json",
Value: b,
}
ri.Lock = lock
return err
}

Expand Down

0 comments on commit 41588ef

Please sign in to comment.