diff --git a/changelog/unreleased/fix-target-uri-for-webdav-prefix.md b/changelog/unreleased/fix-target-uri-for-webdav-prefix.md new file mode 100644 index 0000000000..7bbad59a50 --- /dev/null +++ b/changelog/unreleased/fix-target-uri-for-webdav-prefix.md @@ -0,0 +1,5 @@ +Bugfix: Fix datatxtarget uri when prefix is used + +When a webdav prefix is used it appears in both host and name parameter of the target uri for data transfer. This PR fixes that. + +https://github.com/cs3org/reva/pull/2973 diff --git a/internal/grpc/services/gateway/ocmshareprovider.go b/internal/grpc/services/gateway/ocmshareprovider.go index 5e8df9efc8..afdb56c459 100644 --- a/internal/grpc/services/gateway/ocmshareprovider.go +++ b/internal/grpc/services/gateway/ocmshareprovider.go @@ -279,22 +279,31 @@ func (s *svc) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceive Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, }, nil } - var srcEndpoint string - var srcEndpointBaseURI string + var srcServiceHost string + var srcEndpointPath string // target URI scheme will be the webdav endpoint scheme var srcEndpointScheme string for _, s := range meshProvider.ProviderInfo.Services { if strings.ToLower(s.Endpoint.Type.Name) == "webdav" { - url, err := url.Parse(s.Endpoint.Path) + endpointURL, err := url.Parse(s.Endpoint.Path) if err != nil { log.Err(err).Msg("gateway: error calling UpdateReceivedShare: unable to parse webdav endpoint " + s.Endpoint.Path) return &ocm.UpdateReceivedOCMShareResponse{ Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, }, nil } - srcEndpoint = url.Host - srcEndpointBaseURI = url.Path - srcEndpointScheme = url.Scheme + urlServiceHostFull, err := url.Parse(s.Host) + if err != nil { + log.Err(err).Msg("gateway: error calling UpdateReceivedShare: unable to parse webdav service host " + s.Host) + return &ocm.UpdateReceivedOCMShareResponse{ + Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, + }, nil + } + srcServiceHost = urlServiceHostFull.Host + urlServiceHostFull.Path + // optional prefix must only appear in target url path: + // http://...token...@reva.eu/prefix/?name=remote.php/webdav/home/... + srcEndpointPath = strings.TrimPrefix(endpointURL.Path, urlServiceHostFull.Path) + srcEndpointScheme = endpointURL.Scheme break } } @@ -316,8 +325,8 @@ func (s *svc) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceive }, nil } - srcPath := path.Join(srcEndpointBaseURI, share.GetShare().Name) - srcTargetURI := fmt.Sprintf("%s://%s@%s?name=%s", srcEndpointScheme, srcToken, srcEndpoint, srcPath) + srcPath := path.Join(srcEndpointPath, share.GetShare().Name) + srcTargetURI := fmt.Sprintf("%s://%s@%s?name=%s", srcEndpointScheme, srcToken, srcServiceHost, srcPath) // get the webdav endpoint of the grantee's idp var granteeIdp string @@ -334,16 +343,32 @@ func (s *svc) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceive Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, }, nil } - url, err := url.Parse(destWebdavEndpoint) + destWebdavEndpointURL, err := url.Parse(destWebdavEndpoint) if err != nil { log.Err(err).Msg("gateway: error calling UpdateReceivedShare: unable to parse webdav endpoint " + destWebdavEndpoint) return &ocm.UpdateReceivedOCMShareResponse{ Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, }, nil } - destEndpoint := url.Host - destEndpointBaseURI := url.Path - destEndpointScheme := url.Scheme + destWebdavHost, err := s.getWebdavHost(ctx, granteeIdp) + if err != nil { + log.Err(err).Msg("gateway: error calling UpdateReceivedShare") + return &ocm.UpdateReceivedOCMShareResponse{ + Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, + }, nil + } + urlServiceHostFull, err := url.Parse(destWebdavHost) + if err != nil { + log.Err(err).Msg("gateway: error calling UpdateReceivedShare: unable to parse webdav service host " + destWebdavHost) + return &ocm.UpdateReceivedOCMShareResponse{ + Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, + }, nil + } + destServiceHost := urlServiceHostFull.Host + urlServiceHostFull.Path + // optional prefix must only appear in target url path: + // http://...token...@reva.eu/prefix/?name=remote.php/webdav/home/... + destEndpointPath := strings.TrimPrefix(destWebdavEndpointURL.Path, urlServiceHostFull.Path) + destEndpointScheme := destWebdavEndpointURL.Scheme destToken := ctxpkg.ContextMustGetToken(ctx) homeRes, err := s.GetHome(ctx, &provider.GetHomeRequest{}) if err != nil { @@ -352,8 +377,8 @@ func (s *svc) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateReceive Status: &rpc.Status{Code: rpc.Code_CODE_INTERNAL}, }, nil } - destPath := path.Join(destEndpointBaseURI, homeRes.Path, s.c.DataTransfersFolder, path.Base(share.GetShare().Name)) - destTargetURI := fmt.Sprintf("%s://%s@%s?name=%s", destEndpointScheme, destToken, destEndpoint, destPath) + destPath := path.Join(destEndpointPath, homeRes.Path, s.c.DataTransfersFolder, path.Base(share.GetShare().Name)) + destTargetURI := fmt.Sprintf("%s://%s@%s?name=%s", destEndpointScheme, destToken, destServiceHost, destPath) opaqueObj := &types.Opaque{ Map: map[string]*types.OpaqueEntry{ diff --git a/internal/grpc/services/gateway/webdavstorageprovider.go b/internal/grpc/services/gateway/webdavstorageprovider.go index 8d98e8688c..c7cdc94077 100644 --- a/internal/grpc/services/gateway/webdavstorageprovider.go +++ b/internal/grpc/services/gateway/webdavstorageprovider.go @@ -252,6 +252,21 @@ func (s *svc) getWebdavEndpoint(ctx context.Context, domain string) (string, err return "", errtypes.NotFound(domain) } +func (s *svc) getWebdavHost(ctx context.Context, domain string) (string, error) { + meshProvider, err := s.GetInfoByDomain(ctx, &ocmprovider.GetInfoByDomainRequest{ + Domain: domain, + }) + if err != nil { + return "", errors.Wrap(err, "gateway: error calling GetInfoByDomain") + } + for _, s := range meshProvider.ProviderInfo.Services { + if strings.ToLower(s.Endpoint.Type.Name) == "webdav" { + return s.Host, nil + } + } + return "", errtypes.NotFound(domain) +} + func normalize(info *gowebdav.File) *provider.ResourceInfo { return &provider.ResourceInfo{ // TODO(ishank011): Add Id, PermissionSet, Owner