From 1ed03c12f249dae8dda2c0175fa90c8a99a7bb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 16 May 2024 13:59:07 +0200 Subject: [PATCH] try using viewOnlyToken to download file if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../pkg/connector/contentconnector.go | 11 +++- .../pkg/connector/contentconnector_test.go | 52 +++++++++++++++++-- .../pkg/middleware/wopicontext.go | 1 + .../pkg/service/grpc/v0/service.go | 2 + 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/services/collaboration/pkg/connector/contentconnector.go b/services/collaboration/pkg/connector/contentconnector.go index 7ce1a8977bb..5de55c79634 100644 --- a/services/collaboration/pkg/connector/contentconnector.go +++ b/services/collaboration/pkg/connector/contentconnector.go @@ -9,10 +9,12 @@ import ( "strconv" "time" + appproviderv1beta1 "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1" gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + revactx "github.com/cs3org/reva/v2/pkg/ctx" "github.com/owncloud/ocis/v2/services/collaboration/pkg/config" "github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware" "github.com/rs/zerolog" @@ -72,6 +74,9 @@ func (c *ContentConnector) GetFile(ctx context.Context, writer io.Writer) error Ref: &wopiContext.FileReference, } + if wopiContext.ViewMode == appproviderv1beta1.ViewMode_VIEW_MODE_VIEW_ONLY && wopiContext.ViewOnlyToken != "" { + ctx = revactx.ContextSetToken(ctx, wopiContext.ViewOnlyToken) + } resp, err := c.gwc.InitiateFileDownload(ctx, req) if err != nil { logger.Error().Err(err).Msg("GetFile: InitiateFileDownload failed") @@ -130,7 +135,11 @@ func (c *ContentConnector) GetFile(ctx context.Context, writer io.Writer) error // public link downloads have the token in the download endpoint httpReq.Header.Add("X-Reva-Transfer", downloadToken) } - httpReq.Header.Add("X-Access-Token", wopiContext.AccessToken) + if wopiContext.ViewMode == appproviderv1beta1.ViewMode_VIEW_MODE_VIEW_ONLY && wopiContext.ViewOnlyToken != "" { + httpReq.Header.Add("X-Access-Token", wopiContext.ViewOnlyToken) + } else { + httpReq.Header.Add("X-Access-Token", wopiContext.AccessToken) + } httpResp, err := httpClient.Do(httpReq) if err != nil { diff --git a/services/collaboration/pkg/connector/contentconnector_test.go b/services/collaboration/pkg/connector/contentconnector_test.go index a39a29d5866..581bb3b78d6 100644 --- a/services/collaboration/pkg/connector/contentconnector_test.go +++ b/services/collaboration/pkg/connector/contentconnector_test.go @@ -15,6 +15,7 @@ import ( gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + revactx "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/rgrpc/status" "github.com/owncloud/ocis/v2/services/collaboration/pkg/config" "github.com/owncloud/ocis/v2/services/collaboration/pkg/connector" @@ -133,7 +134,7 @@ var _ = Describe("ContentConnector", func() { gatewayClient.On("InitiateFileDownload", mock.Anything, mock.Anything).Times(1).Return(&gateway.InitiateFileDownloadResponse{ Status: status.NewOK(ctx), Protocols: []*gateway.FileDownloadProtocol{ - &gateway.FileDownloadProtocol{ + { Protocol: "simple", DownloadEndpoint: srv.URL + "/download/failed.png", Token: "MyDownloadToken", @@ -156,7 +157,7 @@ var _ = Describe("ContentConnector", func() { gatewayClient.On("InitiateFileDownload", mock.Anything, mock.Anything).Times(1).Return(&gateway.InitiateFileDownloadResponse{ Status: status.NewOK(ctx), Protocols: []*gateway.FileDownloadProtocol{ - &gateway.FileDownloadProtocol{ + { Protocol: "simple", DownloadEndpoint: srv.URL + "/download/test.txt", Token: "MyDownloadToken", @@ -170,6 +171,49 @@ var _ = Describe("ContentConnector", func() { Expect(err).To(Succeed()) Expect(sb.String()).To(Equal(randomContent)) }) + + It("ViewOnlyMode Download request success", func() { + sb := &strings.Builder{} + + wopiCtx = middleware.WopiContext{ + AccessToken: "abcdef123456", + ViewOnlyToken: "view.only.123456", + FileReference: providerv1beta1.Reference{ + ResourceId: &providerv1beta1.ResourceId{ + StorageId: "abc", + OpaqueId: "12345", + SpaceId: "zzz", + }, + Path: ".", + }, + User: &userv1beta1.User{}, // Not used for now + ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_VIEW_ONLY, + EditAppUrl: "http://test.ex.prv/edit", + ViewAppUrl: "http://test.ex.prv/view", + } + + ctx := middleware.WopiContextToCtx(context.Background(), wopiCtx) + + gatewayClient.On("InitiateFileDownload", + mock.MatchedBy(func(ctx context.Context) bool { + return revactx.ContextMustGetToken(ctx) == "view.only.123456" + }), mock.Anything).Times(1).Return(&gateway.InitiateFileDownloadResponse{ + Status: status.NewOK(ctx), + Protocols: []*gateway.FileDownloadProtocol{ + { + Protocol: "simple", + DownloadEndpoint: srv.URL + "/download/test.txt", + Token: "MyDownloadToken", + }, + }, + }, nil) + + err := cc.GetFile(ctx, sb) + Expect(srvReqHeader.Get("X-Access-Token")).To(Equal(wopiCtx.ViewOnlyToken)) + Expect(srvReqHeader.Get("X-Reva-Transfer")).To(Equal("MyDownloadToken")) + Expect(err).To(Succeed()) + Expect(sb.String()).To(Equal(randomContent)) + }) }) Describe("PutFile", func() { @@ -369,7 +413,7 @@ var _ = Describe("ContentConnector", func() { gatewayClient.On("InitiateFileUpload", mock.Anything, mock.Anything).Times(1).Return(&gateway.InitiateFileUploadResponse{ Status: status.NewOK(ctx), Protocols: []*gateway.FileUploadProtocol{ - &gateway.FileUploadProtocol{ + { Protocol: "simple", UploadEndpoint: srv.URL + "/upload/failed.png", }, @@ -402,7 +446,7 @@ var _ = Describe("ContentConnector", func() { gatewayClient.On("InitiateFileUpload", mock.Anything, mock.Anything).Times(1).Return(&gateway.InitiateFileUploadResponse{ Status: status.NewOK(ctx), Protocols: []*gateway.FileUploadProtocol{ - &gateway.FileUploadProtocol{ + { Protocol: "simple", UploadEndpoint: srv.URL + "/upload/test.txt", }, diff --git a/services/collaboration/pkg/middleware/wopicontext.go b/services/collaboration/pkg/middleware/wopicontext.go index 14d86c93038..dfba5540589 100644 --- a/services/collaboration/pkg/middleware/wopicontext.go +++ b/services/collaboration/pkg/middleware/wopicontext.go @@ -24,6 +24,7 @@ const ( // WopiContext wraps all the information we need for WOPI type WopiContext struct { AccessToken string + ViewOnlyToken string FileReference providerv1beta1.Reference User *userv1beta1.User ViewMode appproviderv1beta1.ViewMode diff --git a/services/collaboration/pkg/service/grpc/v0/service.go b/services/collaboration/pkg/service/grpc/v0/service.go index cbdb603ff09..3d29bba2dc3 100644 --- a/services/collaboration/pkg/service/grpc/v0/service.go +++ b/services/collaboration/pkg/service/grpc/v0/service.go @@ -15,6 +15,7 @@ import ( rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/v2/pkg/utils" "github.com/golang-jwt/jwt/v4" "github.com/owncloud/ocis/v2/ocis-pkg/log" @@ -183,6 +184,7 @@ func (s *Service) OpenInApp( wopiContext := middleware.WopiContext{ AccessToken: cryptedReqAccessToken, + ViewOnlyToken: utils.ReadPlainFromOpaque(req.Opaque, "viewOnlyToken"), FileReference: providerFileRef, User: user, ViewMode: req.GetViewMode(),