diff --git a/go.mod b/go.mod index 2f9566aa0..3e345cc0b 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/coreos/go-oidc 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.18.1-0.20240115094008-bde86a38bd77 + github.com/cs3org/reva/v2 v2.18.1-0.20240122171534-e8fc07f2395a 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 816a6ecb7..c9ca0d89b 100644 --- a/go.sum +++ b/go.sum @@ -1018,8 +1018,10 @@ 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.18.1-0.20240115094008-bde86a38bd77 h1:wDi6MOBGdd9zyqDSwhm2FBYqkiEVgDUevpMBKQ6zSf4= -github.com/cs3org/reva/v2 v2.18.1-0.20240115094008-bde86a38bd77/go.mod h1:plMbmaHczZbP+1rtV56YCYs5lkmpdRNpj0KZb9BWLus= +github.com/cs3org/reva/v2 v2.18.1-0.20240122154113-d79f163775db h1:0nc89DfeCGRr98Z/NZor9fRyQ0pGxq0iQnnUsWFhnek= +github.com/cs3org/reva/v2 v2.18.1-0.20240122154113-d79f163775db/go.mod h1:plMbmaHczZbP+1rtV56YCYs5lkmpdRNpj0KZb9BWLus= +github.com/cs3org/reva/v2 v2.18.1-0.20240122171534-e8fc07f2395a h1:2FLa9HFgDlvXTAdDjqcHsb8Ky2eTBXIIR/ukZeemMKI= +github.com/cs3org/reva/v2 v2.18.1-0.20240122171534-e8fc07f2395a/go.mod h1:GCN3g6uYE0Nvd31dGlhaGGyUviUfbG2NkecPRv5oSc4= 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/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 012ee4bce..432bcb15c 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 @@ -859,6 +859,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer OpaqueId: share.Share.Id.OpaqueId, } info.Path = filepath.Base(share.MountPoint.Path) + info.Name = info.Path infos = append(infos, info) } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go index 6efc53a59..0710d0078 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/usershareprovider/usershareprovider.go @@ -198,7 +198,7 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar Status: status.NewPermissionDenied(ctx, nil, "no permission to add grants on shared resource"), }, err } - // check if the requested share creation has sufficient permissions to do so. + // check if the share creator has sufficient permissions to do so. if shareCreationAllowed := conversions.SufficientCS3Permissions( sRes.GetInfo().GetPermissionSet(), req.GetGrant().GetPermissions().GetPermissions(), @@ -207,6 +207,14 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar Status: status.NewPermissionDenied(ctx, nil, "insufficient permissions to create that kind of share"), }, nil } + // check if the requested permission are plausible for the Resource + if sRes.GetInfo().GetType() == provider.ResourceType_RESOURCE_TYPE_FILE { + if newPermissions := req.GetGrant().GetPermissions().GetPermissions(); newPermissions.GetCreateContainer() || newPermissions.GetMove() || newPermissions.GetDelete() { + return &collaboration.CreateShareResponse{ + Status: status.NewInvalid(ctx, "cannot set the requested permissions on that type of resource"), + }, nil + } + } if !s.isPathAllowed(req.GetResourceInfo().GetPath()) { return &collaboration.CreateShareResponse{ diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go index 0eabd525e..509a6ea63 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go @@ -286,8 +286,6 @@ func (s *svc) ApplyLayout(ctx context.Context, ns string, useLoggedInUserNS bool func addAccessHeaders(w http.ResponseWriter, r *http.Request) { headers := w.Header() - // the webdav api is accessible from anywhere - headers.Set("Access-Control-Allow-Origin", "*") // all resources served via the DAV endpoint should have the strictest possible as default headers.Set("Content-Security-Policy", "default-src 'none';") // disable sniffing the content type for IE diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go index f9271fbbe..fc5764738 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind/propfind.go @@ -486,12 +486,16 @@ func (p *Handler) propfindResponse(ctx context.Context, w http.ResponseWriter, r w.Header().Set(net.HeaderDav, "1, 3, extended-mkcol") w.Header().Set(net.HeaderContentType, "application/xml; charset=utf-8") if sendTusHeaders { - w.Header().Add(net.HeaderAccessControlExposeHeaders, strings.Join([]string{net.HeaderTusResumable, net.HeaderTusVersion, net.HeaderTusExtension}, ", ")) + w.Header().Add(net.HeaderAccessControlExposeHeaders, net.HeaderTusResumable) + w.Header().Add(net.HeaderAccessControlExposeHeaders, net.HeaderTusVersion) + w.Header().Add(net.HeaderAccessControlExposeHeaders, net.HeaderTusExtension) + w.Header().Set(net.HeaderAccessControlExposeHeaders, strings.Join(w.Header().Values(net.HeaderAccessControlExposeHeaders), ", ")) w.Header().Set(net.HeaderTusResumable, "1.0.0") w.Header().Set(net.HeaderTusVersion, "1.0.0") - w.Header().Set(net.HeaderTusExtension, "creation,creation-with-upload,checksum,expiration") + w.Header().Set(net.HeaderTusExtension, "creation, creation-with-upload, checksum, expiration") } - w.Header().Set(net.HeaderVary, net.HeaderPrefer) + w.Header().Add(net.HeaderVary, net.HeaderPrefer) + w.Header().Set(net.HeaderVary, strings.Join(w.Header().Values(net.HeaderVary), ", ")) if returnMinimal { w.Header().Set(net.HeaderPreferenceApplied, "return=minimal") } diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go index b53d18021..ca6c28df5 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go @@ -36,6 +36,7 @@ import ( "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/response" "github.com/cs3org/reva/v2/pkg/appctx" "github.com/cs3org/reva/v2/pkg/conversions" + "github.com/cs3org/reva/v2/pkg/errtypes" "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-chi/chi/v5" "github.com/pkg/errors" @@ -63,62 +64,110 @@ func (h *Handler) AcceptReceivedShare(w http.ResponseWriter, r *http.Request) { return } - rs, ocsResponse := getReceivedShareFromID(ctx, client, shareID) + receivedShare, ocsResponse := getReceivedShareFromID(ctx, client, shareID) if ocsResponse != nil { response.WriteOCSResponse(w, r, *ocsResponse, nil) return } - sharedResource, ocsResponse := getSharedResource(ctx, client, rs.Share.Share.ResourceId) + sharedResource, ocsResponse := getSharedResource(ctx, client, receivedShare.Share.ResourceId) if ocsResponse != nil { response.WriteOCSResponse(w, r, *ocsResponse, nil) return } - lrs, ocsResponse := getSharesList(ctx, client) - if ocsResponse != nil { - response.WriteOCSResponse(w, r, *ocsResponse, nil) + mount, unmountedShares, err := GetMountpointAndUnmountedShares(ctx, client, sharedResource.Info) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "could not determine mountpoint", err) return } + // first update the requested share + receivedShare.State = collaboration.ShareState_SHARE_STATE_ACCEPTED + // we need to add a path to the share + receivedShare.MountPoint = &provider.Reference{ + Path: mount, + } + + updateMask := &fieldmaskpb.FieldMask{Paths: []string{"state", "mount_point"}} + data, meta, err := h.updateReceivedShare(r.Context(), receivedShare, updateMask) + if err != nil { + // we log an error for affected shares, for the actual share we return an error + response.WriteOCSData(w, r, meta, data, err) + return + } + response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) + + // then update other unmounted shares to the same resource + for _, rs := range unmountedShares { + if rs.GetShare().GetId().GetOpaqueId() == shareID { + // we already updated this one + continue + } + + rs.State = collaboration.ShareState_SHARE_STATE_ACCEPTED + // set the same mountpoint as for the requested received share + rs.MountPoint = &provider.Reference{ + Path: mount, + } + + _, _, err := h.updateReceivedShare(r.Context(), rs, updateMask) + if err != nil { + // we log an error for affected shares, the actual share was successful + appctx.GetLogger(ctx).Error().Err(err).Str("received_share", shareID).Str("affected_share", rs.GetShare().GetId().GetOpaqueId()).Msg("could not update affected received share") + } + } +} + +// GetMountpointAndUnmountedShares returns a new or existing mountpoint for the given info and produces a list of unmounted received shares for the same resource +func GetMountpointAndUnmountedShares(ctx context.Context, gwc gateway.GatewayAPIClient, info *provider.ResourceInfo) (string, []*collaboration.ReceivedShare, error) { + unmountedShares := []*collaboration.ReceivedShare{} + receivedShares, err := listReceivedShares(ctx, gwc) + if err != nil { + return "", unmountedShares, err + } + // we need to sort the received shares by mount point in order to make things easier to evaluate. - base := path.Base(sharedResource.GetInfo().GetPath()) - mount := base - var mountedShares []*collaboration.ReceivedShare - sharesToAccept := map[string]bool{shareID: true} - for _, s := range lrs.Shares { - if utils.ResourceIDEqual(s.Share.ResourceId, rs.Share.Share.GetResourceId()) { + mount := filepath.Clean(info.Name) + existingMountpoint := "" + mountedShares := make([]*collaboration.ReceivedShare, 0, len(receivedShares)) + for _, s := range receivedShares { + if utils.ResourceIDEqual(s.Share.ResourceId, info.GetId()) { if s.State == collaboration.ShareState_SHARE_STATE_ACCEPTED { - mount = s.MountPoint.Path + // a share to the resource already exists and is mounted, remember the mount point + _, err := utils.GetResourceByID(ctx, s.Share.ResourceId, gwc) + if err == nil { + existingMountpoint = s.MountPoint.Path + } } else { - sharesToAccept[s.Share.Id.OpaqueId] = true - } - } else { - if s.State == collaboration.ShareState_SHARE_STATE_ACCEPTED { - s.Hidden = h.getReceivedShareHideFlagFromShareID(r.Context(), shareID) - mountedShares = append(mountedShares, s) + // a share to the resource already exists but is not mounted, collect the unmounted share + unmountedShares = append(unmountedShares, s) } } + + if s.State == collaboration.ShareState_SHARE_STATE_ACCEPTED { + mountedShares = append(mountedShares, s) + } } - compareMountPoint := func(i, j int) bool { + sort.Slice(mountedShares, func(i, j int) bool { return mountedShares[i].MountPoint.Path > mountedShares[j].MountPoint.Path - } - sort.Slice(mountedShares, compareMountPoint) + }) - // now we have a list of shares, we want to iterate over all of them and check for name collisions + if existingMountpoint != "" { + // we want to reuse the same mountpoint for all unmounted shares to the same resource + return existingMountpoint, unmountedShares, nil + } + + // we have a list of shares, we want to iterate over all of them and check for name collisions for i, ms := range mountedShares { if ms.MountPoint.Path == mount { // does the shared resource still exist? - res, err := client.Stat(ctx, &provider.StatRequest{ - Ref: &provider.Reference{ - ResourceId: ms.Share.ResourceId, - }, - }) - if err == nil && res.Status.Code == rpc.Code_CODE_OK { + _, err := utils.GetResourceByID(ctx, ms.Share.ResourceId, gwc) + if err == nil { // The mount point really already exists, we need to insert a number into the filename - ext := filepath.Ext(base) - name := strings.TrimSuffix(base, ext) + ext := filepath.Ext(mount) + name := strings.TrimSuffix(mount, ext) // be smart about .tar.(gz|bz) files if strings.HasSuffix(name, ".tar") { name = strings.TrimSuffix(name, ".tar") @@ -130,26 +179,7 @@ func (h *Handler) AcceptReceivedShare(w http.ResponseWriter, r *http.Request) { // TODO we could delete shares here if the stat returns code NOT FOUND ... but listening for file deletes would be better } } - // we need to add a path to the share - receivedShare := &collaboration.ReceivedShare{ - Share: &collaboration.Share{ - Id: &collaboration.ShareId{OpaqueId: shareID}, - }, - State: collaboration.ShareState_SHARE_STATE_ACCEPTED, - Hidden: h.getReceivedShareHideFlagFromShareID(r.Context(), shareID), - MountPoint: &provider.Reference{ - Path: mount, - }, - } - updateMask := &fieldmaskpb.FieldMask{Paths: []string{"state", "hidden", "mount_point"}} - - for id := range sharesToAccept { - data := h.updateReceivedShare(w, r, receivedShare, updateMask) - // only render the data for the changed share - if id == shareID && data != nil { - response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) - } - } + return mount, unmountedShares, nil } // RejectReceivedShare handles DELETE Requests on /apps/files_sharing/api/v1/shares/{shareid} @@ -166,15 +196,15 @@ func (h *Handler) RejectReceivedShare(w http.ResponseWriter, r *http.Request) { Share: &collaboration.Share{ Id: &collaboration.ShareId{OpaqueId: shareID}, }, - State: collaboration.ShareState_SHARE_STATE_REJECTED, - Hidden: h.getReceivedShareHideFlagFromShareID(r.Context(), shareID), + State: collaboration.ShareState_SHARE_STATE_REJECTED, } - updateMask := &fieldmaskpb.FieldMask{Paths: []string{"state", "hidden"}} + updateMask := &fieldmaskpb.FieldMask{Paths: []string{"state"}} - data := h.updateReceivedShare(w, r, receivedShare, updateMask) - if data != nil { - response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) + data, meta, err := h.updateReceivedShare(r.Context(), receivedShare, updateMask) + if err != nil { + response.WriteOCSData(w, r, meta, nil, err) } + response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) } func (h *Handler) UpdateReceivedShare(w http.ResponseWriter, r *http.Request) { @@ -199,18 +229,17 @@ func (h *Handler) UpdateReceivedShare(w http.ResponseWriter, r *http.Request) { rs, _ := getReceivedShareFromID(r.Context(), client, shareID) if rs != nil && rs.Share != nil { - receivedShare.State = rs.Share.State + receivedShare.State = rs.State } - data := h.updateReceivedShare(w, r, receivedShare, updateMask) - if data != nil { - response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) + data, meta, err := h.updateReceivedShare(r.Context(), receivedShare, updateMask) + if err != nil { + response.WriteOCSData(w, r, meta, nil, err) } - // TODO: do we need error handling here? + response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) } -func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, receivedShare *collaboration.ReceivedShare, fieldMask *fieldmaskpb.FieldMask) *conversions.ShareData { - ctx := r.Context() +func (h *Handler) updateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *fieldmaskpb.FieldMask) (*conversions.ShareData, response.Meta, error) { logger := appctx.GetLogger(ctx) updateShareRequest := &collaboration.UpdateReceivedShareRequest{ @@ -220,23 +249,19 @@ func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, re client, err := h.getClient() if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) - return nil + return nil, response.MetaServerError, errors.Wrap(err, "error getting grpc gateway client") } shareRes, err := client.UpdateReceivedShare(ctx, updateShareRequest) if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc update received share request failed", err) - return nil + return nil, response.MetaServerError, errors.Wrap(err, "grpc update received share request failed") } if shareRes.Status.Code != rpc.Code_CODE_OK { if shareRes.Status.Code == rpc.Code_CODE_NOT_FOUND { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil) - return nil + return nil, response.MetaNotFound, errors.New(shareRes.Status.Message) } - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc update received share request failed", errors.Errorf("code: %d, message: %s", shareRes.Status.Code, shareRes.Status.Message)) - return nil + return nil, response.MetaServerError, errors.Errorf("grpc update received share request failed: code: %d, message: %s", shareRes.Status.Code, shareRes.Status.Message) } rs := shareRes.GetShare() @@ -244,27 +269,23 @@ func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, re info, status, err := h.getResourceInfoByID(ctx, client, rs.Share.ResourceId) if err != nil || status.Code != rpc.Code_CODE_OK { h.logProblems(logger, status, err, "could not stat, skipping") - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc get resource info failed", errors.Errorf("code: %d, message: %s", status.Code, status.Message)) - return nil + return nil, response.MetaServerError, errors.Errorf("grpc get resource info failed: code: %d, message: %s", status.Code, status.Message) } - data, err := conversions.CS3Share2ShareData(r.Context(), rs.Share) - if err != nil { - logger.Debug().Interface("share", rs.Share).Interface("shareData", data).Err(err).Msg("could not CS3Share2ShareData, skipping") - } + data := conversions.CS3Share2ShareData(ctx, rs.Share) data.State = mapState(rs.GetState()) data.Hidden = rs.GetHidden() h.addFileInfo(ctx, data, info) - h.mapUserIds(r.Context(), client, data) + h.mapUserIds(ctx, client, data) if data.State == ocsStateAccepted { // Needed because received shares can be jailed in a folder in the users home data.Path = path.Join(h.sharePrefix, path.Base(info.Path)) } - return data + return data, response.MetaOK, nil } func (h *Handler) updateReceivedFederatedShare(w http.ResponseWriter, r *http.Request, shareID string, rejectShare bool) { @@ -337,21 +358,8 @@ func (h *Handler) updateReceivedFederatedShare(w http.ResponseWriter, r *http.Re response.WriteOCSSuccess(w, r, []*conversions.ShareData{data}) } -// getReceivedShareHideFlagFromShareId returns the hide flag of a received share based on its ID. -func (h *Handler) getReceivedShareHideFlagFromShareID(ctx context.Context, shareID string) bool { - client, err := h.getClient() - if err != nil { - return false - } - rs, _ := getReceivedShareFromID(ctx, client, shareID) - if rs != nil { - return rs.GetShare().GetHidden() - } - return false -} - // getReceivedShareFromID uses a client to the gateway to fetch a share based on its ID. -func getReceivedShareFromID(ctx context.Context, client gateway.GatewayAPIClient, shareID string) (*collaboration.GetReceivedShareResponse, *response.Response) { +func getReceivedShareFromID(ctx context.Context, client gateway.GatewayAPIClient, shareID string) (*collaboration.ReceivedShare, *response.Response) { s, err := client.GetReceivedShare(ctx, &collaboration.GetReceivedShareRequest{ Ref: &collaboration.ShareReference{ Spec: &collaboration.ShareReference_Id{ @@ -376,7 +384,7 @@ func getReceivedShareFromID(ctx context.Context, client gateway.GatewayAPIClient return nil, arbitraryOcsResponse(response.MetaBadRequest.StatusCode, e.Error()) } - return s, nil + return s.Share, nil } // getSharedResource attempts to get a shared resource from the storage from the resource reference. @@ -403,23 +411,17 @@ func getSharedResource(ctx context.Context, client gateway.GatewayAPIClient, res return res, nil } -// getSharedResource gets the list of all shares for the current user. -func getSharesList(ctx context.Context, client gateway.GatewayAPIClient) (*collaboration.ListReceivedSharesResponse, *response.Response) { - shares, err := client.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{}) +// listReceivedShares list all received shares for the current user. +func listReceivedShares(ctx context.Context, client gateway.GatewayAPIClient) ([]*collaboration.ReceivedShare, error) { + res, err := client.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{}) if err != nil { - e := errors.Wrap(err, "error getting shares list") - return nil, arbitraryOcsResponse(response.MetaNotFound.StatusCode, e.Error()) + return nil, errtypes.InternalError("grpc list received shares request failed") } - if shares.Status.Code != rpc.Code_CODE_OK { - if shares.Status.Code == rpc.Code_CODE_NOT_FOUND { - e := fmt.Errorf("not found") - return nil, arbitraryOcsResponse(response.MetaNotFound.StatusCode, e.Error()) - } - e := fmt.Errorf(shares.GetStatus().GetMessage()) - return nil, arbitraryOcsResponse(response.MetaServerError.StatusCode, e.Error()) + if err := errtypes.NewErrtypeFromStatus(res.Status); err != nil { + return nil, err } - return shares, nil + return res.Shares, nil } // arbitraryOcsResponse abstracts the boilerplate that is creating a response.Response struct. diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 303fc95d4..f75a30b34 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -303,11 +303,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) { return } - s, err := conversions.CS3Share2ShareData(ctx, share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } + s := conversions.CS3Share2ShareData(ctx, share) h.addFileInfo(ctx, s, statRes.Info) @@ -402,12 +398,12 @@ func (h *Handler) updateExistingShareMountpoints(ctx context.Context, shareType } granteeCtx = metadata.AppendToOutgoingContext(granteeCtx, ctxpkg.TokenHeader, authRes.Token) - lrs, ocsResponse := getSharesList(granteeCtx, client) - if ocsResponse != nil { - return ocsResponse.OCS.Meta.StatusCode, ocsResponse.OCS.Meta.Message, nil + receivedShares, err := listReceivedShares(granteeCtx, client) + if err != nil { + return response.MetaServerError.StatusCode, "could not list shares", nil } - for _, s := range lrs.Shares { + for _, s := range receivedShares { if s.GetShare().GetId() != share.Id && s.State == collaboration.ShareState_SHARE_STATE_ACCEPTED && utils.ResourceIDEqual(s.Share.ResourceId, info.GetId()) { updateRequest := &collaboration.UpdateReceivedShareRequest{ Share: &collaboration.ReceivedShare{ @@ -595,12 +591,8 @@ func (h *Handler) GetShare(w http.ResponseWriter, r *http.Request) { }) if err == nil && uRes.GetShare() != nil { resourceID = uRes.Share.Share.ResourceId - share, err = conversions.CS3Share2ShareData(ctx, uRes.Share.Share) + share = conversions.CS3Share2ShareData(ctx, uRes.Share.Share) share.Hidden = uRes.Share.Hidden - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } } } @@ -635,11 +627,7 @@ func (h *Handler) GetShare(w http.ResponseWriter, r *http.Request) { if err == nil && uRes.GetShare() != nil { resourceID = uRes.Share.ResourceId - share, err = conversions.CS3Share2ShareData(ctx, uRes.Share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } + share = conversions.CS3Share2ShareData(ctx, uRes.Share) } } @@ -874,11 +862,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, share *col h.statCache.RemoveStat(currentUser.Id, share.ResourceId) } - resultshare, err := conversions.CS3Share2ShareData(ctx, uRes.Share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } + resultshare := conversions.CS3Share2ShareData(ctx, uRes.Share) statReq := provider.StatRequest{Ref: &provider.Reference{ ResourceId: uRes.Share.ResourceId, @@ -1072,11 +1056,7 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { } } - data, err := conversions.CS3Share2ShareData(r.Context(), rs.Share) - if err != nil { - sublog.Debug().Interface("share", rs.Share).Interface("shareData", data).Err(err).Msg("could not CS3Share2ShareData, skipping") - continue - } + data := conversions.CS3Share2ShareData(r.Context(), rs.Share) data.State = mapState(rs.GetState()) data.Hidden = rs.Hidden diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go index 04498b220..dd940741b 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go @@ -281,11 +281,7 @@ func (h *Handler) removeUserShare(w http.ResponseWriter, r *http.Request, share }, } - data, err := conversions.CS3Share2ShareData(ctx, share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "deleting share failed", err) - return - } + data := conversions.CS3Share2ShareData(ctx, share) // A deleted share should not have an ID. data.ID = "" @@ -337,11 +333,7 @@ func (h *Handler) listUserShares(r *http.Request, filters []*collaboration.Filte // build OCS response payload for _, s := range lsUserSharesResponse.Shares { - data, err := conversions.CS3Share2ShareData(ctx, s) - if err != nil { - log.Debug().Interface("share", s).Interface("shareData", data).Err(err).Msg("could not CS3Share2ShareData, skipping") - continue - } + data := conversions.CS3Share2ShareData(ctx, s) info, status, err := h.getResourceInfoByID(ctx, client, s.ResourceId) if err != nil || status.Code != rpc.Code_CODE_OK { diff --git a/vendor/github.com/cs3org/reva/v2/pkg/conversions/main.go b/vendor/github.com/cs3org/reva/v2/pkg/conversions/main.go index 8ef5dc395..dbeaedd37 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/conversions/main.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/conversions/main.go @@ -232,7 +232,7 @@ type MatchValueData struct { } // CS3Share2ShareData converts a cs3api user share into shareData data model -func CS3Share2ShareData(ctx context.Context, share *collaboration.Share) (*ShareData, error) { +func CS3Share2ShareData(ctx context.Context, share *collaboration.Share) *ShareData { sd := &ShareData{ // share.permissions are mapped below // Displaynames are added later @@ -269,7 +269,7 @@ func CS3Share2ShareData(ctx context.Context, share *collaboration.Share) (*Share sd.Expiration = expiration.Format(_iso8601) } - return sd, nil + return sd } // PublicShare2ShareData converts a cs3api public share into shareData data model diff --git a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/utils/download/download.go b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/utils/download/download.go index cf0c86323..c15029bd2 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/utils/download/download.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/rhttp/datatx/utils/download/download.go @@ -159,6 +159,8 @@ func GetOrHeadFile(w http.ResponseWriter, r *http.Request, fs storage.FS, spaceI w.Header().Set("Accept-Ranges", "bytes") } + w.Header().Set(net.HeaderContentType, strings.Join([]string{md.MimeType, "charset=UTF-8"}, "; ")) + if len(ranges) > 0 { sublog.Debug().Int64("start", ranges[0].Start).Int64("length", ranges[0].Length).Msg("range request") if s == nil { @@ -200,7 +202,7 @@ func GetOrHeadFile(w http.ResponseWriter, r *http.Request, fs storage.FS, spaceI defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish. go func() { for _, ra := range ranges { - part, err := mw.CreatePart(ra.MimeHeader(md.MimeType, int64(md.Size))) + part, err := mw.CreatePart(ra.MimeHeader(md.MimeType+"; charset=UTF-8", int64(md.Size))) if err != nil { _ = pw.CloseWithError(err) // CloseWithError always returns nil return @@ -224,7 +226,6 @@ func GetOrHeadFile(w http.ResponseWriter, r *http.Request, fs storage.FS, spaceI w.Header().Set(net.HeaderContentLength, strconv.FormatInt(sendSize, 10)) } - w.Header().Set(net.HeaderContentType, md.MimeType) w.Header().Set(net.HeaderContentDisposistion, net.ContentDispositionAttachment(path.Base(md.Path))) w.Header().Set(net.HeaderETag, md.Etag) w.Header().Set(net.HeaderOCFileID, storagespace.FormatResourceID(*md.Id)) diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/grants.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/grants.go index ed3f7ca11..9dda19fa6 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/grants.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/grants.go @@ -197,11 +197,6 @@ func (fs *Decomposedfs) RemoveGrant(ctx context.Context, ref *provider.Reference } } - // check lock - if err := grantNode.CheckLock(ctx); err != nil { - return err - } - if err := grantNode.DeleteGrant(ctx, g, false); err != nil { return err } @@ -308,11 +303,6 @@ func (fs *Decomposedfs) loadGrant(ctx context.Context, ref *provider.Reference, } func (fs *Decomposedfs) storeGrant(ctx context.Context, n *node.Node, g *provider.Grant) error { - // check lock - if err := n.CheckLock(ctx); err != nil { - return err - } - var spaceType string spaceGrant := ctx.Value(utils.SpaceGrant) // this is not a grant on a space root we are just adding a share diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go index 6e081fdce..f58edff6a 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/options/options.go @@ -91,11 +91,7 @@ type AsyncPropagatorOptions struct { // EventOptions are the configurable options for events type EventOptions struct { - NatsAddress string `mapstructure:"natsaddress"` - NatsClusterID string `mapstructure:"natsclusterid"` - TLSInsecure bool `mapstructure:"tlsinsecure"` - TLSRootCACertificate string `mapstructure:"tlsrootcacertificate"` - NumConsumers int `mapstructure:"numconsumers"` + NumConsumers int `mapstructure:"numconsumers"` } // TokenOptions are the configurable option for tokens diff --git a/vendor/github.com/cs3org/reva/v2/pkg/store/store.go b/vendor/github.com/cs3org/reva/v2/pkg/store/store.go index f26edff2e..0038d0058 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/store/store.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/store/store.go @@ -151,8 +151,8 @@ func Create(opts ...microstore.Option) microstore.Store { } return natsjskv.NewStore( append(opts, - natsjs.NatsOptions(natsOptions), // always pass in properly initialized default nats options - natsjs.DefaultTTL(ttl))..., + natsjskv.NatsOptions(natsOptions), // always pass in properly initialized default nats options + natsjskv.DefaultTTL(ttl))..., ) case TypeMemory, "mem", "": // allow existing short form and use as default return microstore.NewMemoryStore(opts...) diff --git a/vendor/modules.txt b/vendor/modules.txt index 552be2a0b..1e48fa46e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -362,7 +362,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.18.1-0.20240115094008-bde86a38bd77 +# github.com/cs3org/reva/v2 v2.18.1-0.20240122171534-e8fc07f2395a ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime