From c9835c66e7b513eee16eb80e2bdd9faffaad92fa Mon Sep 17 00:00:00 2001 From: David Christofas Date: Tue, 24 Aug 2021 15:28:49 +0200 Subject: [PATCH] move unwrapping and wrapping of paths to the gateway temporary change to check CI --- .../unreleased/wrap-unwrap-in-gateway.md | 5 + internal/grpc/interceptors/auth/scope.go | 16 +- .../grpc/services/gateway/ocmshareprovider.go | 18 +- .../grpc/services/gateway/storageprovider.go | 173 +++++++--- .../services/gateway/usershareprovider.go | 42 ++- .../publicstorageprovider.go | 34 +- .../storageprovider/storageprovider.go | 299 +++--------------- pkg/auth/scope/publicshare.go | 2 +- pkg/storage/registry/static/static.go | 15 +- tests/oc-integration-tests/drone/gateway.toml | 6 +- tests/oc-integration-tests/local/gateway.toml | 6 +- 11 files changed, 254 insertions(+), 362 deletions(-) create mode 100644 changelog/unreleased/wrap-unwrap-in-gateway.md diff --git a/changelog/unreleased/wrap-unwrap-in-gateway.md b/changelog/unreleased/wrap-unwrap-in-gateway.md new file mode 100644 index 00000000000..bce2c6263fd --- /dev/null +++ b/changelog/unreleased/wrap-unwrap-in-gateway.md @@ -0,0 +1,5 @@ +Change: move wrapping and unwrapping of paths to the storage gateway + +We've moved the wrapping and unwrapping of reference paths to the storage gateway so that the storageprovider doesn't have to know its mount path. + +https://github.com/cs3org/reva/pull/2016 diff --git a/internal/grpc/interceptors/auth/scope.go b/internal/grpc/interceptors/auth/scope.go index 7cac0416b30..09bd3c570fa 100644 --- a/internal/grpc/interceptors/auth/scope.go +++ b/internal/grpc/interceptors/auth/scope.go @@ -160,11 +160,25 @@ func checkResourcePath(ctx context.Context, ref *provider.Reference, r *provider return false, statuspkg.NewErrorFromCode(statResponse.Status.Code, "auth interceptor") } - if strings.HasPrefix(ref.GetPath(), statResponse.Info.Path) { + resourcePath := statResponse.Info.Path + + if strings.HasPrefix(ref.GetPath(), resourcePath) { // The path corresponds to the resource to which the token has access. // We allow access to it. return true, nil } + + // If we arrived here that could mean that ref.GetPath is not prefixed with the storage mount path but resourcePath is + // because it was returned by the gateway which will prefix it. To fix that we remove the mount path from the resourcePath. + // resourcePath = "/users//some/path" + // After the split we have [" ", "users", "/some/path"]. + trimmedPath := "/" + strings.SplitN(resourcePath, "/", 3)[2] + if strings.HasPrefix(ref.GetPath(), trimmedPath) { + // The path corresponds to the resource to which the token has access. + // We allow access to it. + return true, nil + } + return false, nil } diff --git a/internal/grpc/services/gateway/ocmshareprovider.go b/internal/grpc/services/gateway/ocmshareprovider.go index bd7ebb76bb5..ffad880f517 100644 --- a/internal/grpc/services/gateway/ocmshareprovider.go +++ b/internal/grpc/services/gateway/ocmshareprovider.go @@ -352,19 +352,25 @@ func (s *svc) createOCMReference(ctx context.Context, share *ocm.Share) (*rpc.St } log.Info().Msg("mount path will be:" + refPath) - createRefReq := &provider.CreateReferenceRequest{ - Ref: &provider.Reference{Path: refPath}, - TargetUri: targetURI, - } - c, err := s.findByPath(ctx, refPath) + c, p, err := s.findByPath(ctx, refPath) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found"), nil } return status.NewInternal(ctx, err, "error finding storage provider"), nil } - + pRef, err := unwrap(&provider.Reference{Path: refPath}, p.ProviderPath) + if err != nil { + log.Err(err).Msg("gateway: error unwrapping") + return &rpc.Status{ + Code: rpc.Code_CODE_INTERNAL, + }, nil + } + createRefReq := &provider.CreateReferenceRequest{ + Ref: pRef, + TargetUri: targetURI, + } createRefRes, err := c.CreateReference(ctx, createRefReq) if err != nil { log.Err(err).Msg("gateway: error calling GetHome") diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index 249aac85e6b..0842858defe 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -82,7 +82,7 @@ func (s *svc) CreateHome(ctx context.Context, req *provider.CreateHomeRequest) ( log := appctx.GetLogger(ctx) home := s.getHome(ctx) - c, err := s.findByPath(ctx, home) + c, _, err := s.findByPath(ctx, home) if err != nil { return &provider.CreateHomeResponse{ Status: status.NewStatusFromErrType(ctx, "error finding home", err), @@ -102,7 +102,7 @@ func (s *svc) CreateHome(ctx context.Context, req *provider.CreateHomeRequest) ( func (s *svc) CreateStorageSpace(ctx context.Context, req *provider.CreateStorageSpaceRequest) (*provider.CreateStorageSpaceResponse, error) { log := appctx.GetLogger(ctx) // TODO: needs to be fixed - c, err := s.findByPath(ctx, "/users") + c, _, err := s.findByPath(ctx, "/users") if err != nil { return &provider.CreateStorageSpaceResponse{ Status: status.NewStatusFromErrType(ctx, "error finding path", err), @@ -250,7 +250,7 @@ func (s *svc) listStorageSpacesOnProvider(ctx context.Context, req *provider.Lis func (s *svc) UpdateStorageSpace(ctx context.Context, req *provider.UpdateStorageSpaceRequest) (*provider.UpdateStorageSpaceResponse, error) { log := appctx.GetLogger(ctx) // TODO: needs to be fixed - c, err := s.find(ctx, &provider.Reference{ResourceId: req.StorageSpace.Root}) + c, _, err := s.find(ctx, &provider.Reference{ResourceId: req.StorageSpace.Root}) if err != nil { return &provider.UpdateStorageSpaceResponse{ Status: status.NewStatusFromErrType(ctx, "error finding ID", err), @@ -276,7 +276,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag Status: status.NewInvalidArg(ctx, "space id must be separated by !"), }, nil } - c, err := s.find(ctx, &provider.Reference{ResourceId: &provider.ResourceId{ + c, _, err := s.find(ctx, &provider.Reference{ResourceId: &provider.ResourceId{ StorageId: storageid, OpaqueId: opaqeid, }}) @@ -473,13 +473,15 @@ func (s *svc) InitiateFileDownload(ctx context.Context, req *provider.InitiateFi func (s *svc) initiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*gateway.InitiateFileDownloadResponse, error) { // TODO(ishank011): enable downloading references spread across storage providers, eg. /eos - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &gateway.InitiateFileDownloadResponse{ Status: status.NewStatusFromErrType(ctx, "error initiating download ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } storageRes, err := c.InitiateFileDownload(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling InitiateFileDownload") @@ -671,13 +673,15 @@ func (s *svc) InitiateFileUpload(ctx context.Context, req *provider.InitiateFile } func (s *svc) initiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*gateway.InitiateFileUploadResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &gateway.InitiateFileUploadResponse{ Status: status.NewStatusFromErrType(ctx, "initiateFileUpload ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } storageRes, err := c.InitiateFileUpload(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling InitiateFileUpload") @@ -822,13 +826,15 @@ func (s *svc) CreateContainer(ctx context.Context, req *provider.CreateContainer } func (s *svc) createContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.CreateContainerResponse{ Status: status.NewStatusFromErrType(ctx, "createContainer ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.CreateContainer(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling CreateContainer") @@ -978,13 +984,15 @@ func (s *svc) Delete(ctx context.Context, req *provider.DeleteRequest) (*provide func (s *svc) delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { // TODO(ishank011): enable deleting references spread across storage providers, eg. /eos - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.DeleteResponse{ Status: status.NewStatusFromErrType(ctx, "delete ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.Delete(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling Delete") @@ -1147,19 +1155,27 @@ func (s *svc) move(ctx context.Context, req *provider.MoveRequest) (*provider.Mo Status: status.NewInternal(ctx, err, "error connecting to storage provider="+srcProvider.Address), }, nil } + if req.Source, err = unwrap(req.Source, srcProvider.ProviderPath); err != nil { + return nil, err + } + if req.Destination, err = unwrap(req.Destination, dstProvider.ProviderPath); err != nil { + return nil, err + } return c.Move(ctx, req) } func (s *svc) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { // TODO(ishank011): enable for references spread across storage providers, eg. /eos - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.SetArbitraryMetadataResponse{ Status: status.NewStatusFromErrType(ctx, "SetArbitraryMetadata ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.SetArbitraryMetadata(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling Stat") @@ -1170,13 +1186,15 @@ func (s *svc) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitra func (s *svc) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) { // TODO(ishank011): enable for references spread across storage providers, eg. /eos - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.UnsetArbitraryMetadataResponse{ Status: status.NewStatusFromErrType(ctx, "UnsetArbitraryMetadata ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.UnsetArbitraryMetadata(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling Stat") @@ -1292,10 +1310,23 @@ func (s *svc) stat(ctx context.Context, req *provider.StatRequest) (*provider.St Status: status.NewInternal(ctx, err, "error connecting to storage provider="+providers[0].Address), }, nil } - rsp, err := c.Stat(ctx, req) + ref, err := unwrap(req.Ref, providers[0].ProviderPath) + if err != nil { + return nil, err + } + // We need to copy the request because we don't want to overwrite the original request + sReq := &provider.StatRequest{ + Opaque: req.Opaque, + Ref: ref, + ArbitraryMetadataKeys: req.ArbitraryMetadataKeys, + } + rsp, err := c.Stat(ctx, sReq) if err != nil || rsp.Status.Code != rpc.Code_CODE_OK { return rsp, err } + if rsp.Info != nil && utils.IsAbsoluteReference(req.Ref) { + wrap(rsp.Info, providers[0]) + } return rsp, nil } @@ -1349,20 +1380,35 @@ func (s *svc) statOnProvider(ctx context.Context, req *provider.StatRequest, res return } + // We don't want to change the original request so we copy it here to a temporary variable + newReq := req if utils.IsAbsoluteReference(req.Ref) { resPath := path.Clean(req.Ref.GetPath()) - newPath := req.Ref.GetPath() + ref := &provider.Reference{ + Path: req.Ref.Path, + } if resPath != "." && !strings.HasPrefix(resPath, p.ProviderPath) { - newPath = p.ProviderPath + ref.Path = p.ProviderPath + } + ref, err = unwrap(ref, p.ProviderPath) + if err != nil { + *e = err + return } - req.Ref = &provider.Reference{Path: newPath} + newReq.Ref = ref } - r, err := c.Stat(ctx, req) + r, err := c.Stat(ctx, newReq) if err != nil { *e = errors.Wrap(err, fmt.Sprintf("gateway: error calling Stat %s on %+v", req.Ref, p)) return } + if res == nil { + *res = &provider.ResourceInfo{} + } + if utils.IsAbsoluteReference(req.Ref) { + wrap(r.Info, p) + } *res = r.Info } @@ -1721,6 +1767,7 @@ func (s *svc) listContainerOnProvider(ctx context.Context, req *provider.ListCon return } + ref := req.Ref if utils.IsAbsoluteReference(req.Ref) { resPath := path.Clean(req.Ref.GetPath()) if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) { @@ -1747,13 +1794,23 @@ func (s *svc) listContainerOnProvider(ctx context.Context, req *provider.ListCon } return } + ref, err = unwrap(ref, p.ProviderPath) + if err != nil { + *e = err + return + } } - r, err := c.ListContainer(ctx, req) + r, err := c.ListContainer(ctx, &provider.ListContainerRequest{Ref: ref}) if err != nil { *e = errors.Wrap(err, "gateway: error calling ListContainer") return } + if utils.IsAbsoluteReference(req.Ref) { + for i := range r.Infos { + wrap(r.Infos[i], p) + } + } *res = r.Infos } @@ -2034,13 +2091,16 @@ func (s *svc) CreateSymlink(ctx context.Context, req *provider.CreateSymlinkRequ } func (s *svc) ListFileVersions(ctx context.Context, req *provider.ListFileVersionsRequest) (*provider.ListFileVersionsResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.ListFileVersionsResponse{ Status: status.NewStatusFromErrType(ctx, "ListFileVersions ref="+req.Ref.String(), err), }, nil } - + req.Ref, err = unwrap(req.Ref, p.ProviderPath) + if err != nil { + return nil, err + } res, err := c.ListFileVersions(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling ListFileVersions") @@ -2050,13 +2110,15 @@ func (s *svc) ListFileVersions(ctx context.Context, req *provider.ListFileVersio } func (s *svc) RestoreFileVersion(ctx context.Context, req *provider.RestoreFileVersionRequest) (*provider.RestoreFileVersionResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.RestoreFileVersionResponse{ Status: status.NewStatusFromErrType(ctx, "RestoreFileVersion ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.RestoreFileVersion(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling RestoreFileVersion") @@ -2071,13 +2133,15 @@ func (s *svc) ListRecycleStream(_ *gateway.ListRecycleStreamRequest, _ gateway.G // TODO use the ListRecycleRequest.Ref to only list the trash of a specific storage func (s *svc) ListRecycle(ctx context.Context, req *gateway.ListRecycleRequest) (*provider.ListRecycleResponse, error) { - c, err := s.find(ctx, req.GetRef()) + c, p, err := s.find(ctx, req.GetRef()) if err != nil { return &provider.ListRecycleResponse{ Status: status.NewStatusFromErrType(ctx, "ListFileVersions ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.ListRecycle(ctx, &provider.ListRecycleRequest{ Opaque: req.Opaque, FromTs: req.FromTs, @@ -2092,13 +2156,15 @@ func (s *svc) ListRecycle(ctx context.Context, req *gateway.ListRecycleRequest) } func (s *svc) RestoreRecycleItem(ctx context.Context, req *provider.RestoreRecycleItemRequest) (*provider.RestoreRecycleItemResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.RestoreRecycleItemResponse{ Status: status.NewStatusFromErrType(ctx, "RestoreRecycleItem ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.RestoreRecycleItem(ctx, req) if err != nil { return nil, errors.Wrap(err, "gateway: error calling RestoreRecycleItem") @@ -2108,13 +2174,15 @@ func (s *svc) RestoreRecycleItem(ctx context.Context, req *provider.RestoreRecyc } func (s *svc) PurgeRecycle(ctx context.Context, req *gateway.PurgeRecycleRequest) (*provider.PurgeRecycleResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.PurgeRecycleResponse{ Status: status.NewStatusFromErrType(ctx, "PurgeRecycle ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.PurgeRecycle(ctx, &provider.PurgeRecycleRequest{ Opaque: req.GetOpaque(), Ref: req.GetRef(), @@ -2126,13 +2194,15 @@ func (s *svc) PurgeRecycle(ctx context.Context, req *gateway.PurgeRecycleRequest } func (s *svc) GetQuota(ctx context.Context, req *gateway.GetQuotaRequest) (*provider.GetQuotaResponse, error) { - c, err := s.find(ctx, req.Ref) + c, p, err := s.find(ctx, req.Ref) if err != nil { return &provider.GetQuotaResponse{ Status: status.NewStatusFromErrType(ctx, "GetQuota ref="+req.Ref.String(), err), }, nil } - + if req.Ref, err = unwrap(req.Ref, p.ProviderPath); err != nil { + return nil, err + } res, err := c.GetQuota(ctx, &provider.GetQuotaRequest{ Opaque: req.GetOpaque(), // Ref: req.GetRef(), // TODO send which storage space ... or root @@ -2143,17 +2213,19 @@ func (s *svc) GetQuota(ctx context.Context, req *gateway.GetQuotaRequest) (*prov return res, nil } -func (s *svc) findByPath(ctx context.Context, path string) (provider.ProviderAPIClient, error) { +func (s *svc) findByPath(ctx context.Context, path string) (provider.ProviderAPIClient, *registry.ProviderInfo, error) { ref := &provider.Reference{Path: path} return s.find(ctx, ref) } -func (s *svc) find(ctx context.Context, ref *provider.Reference) (provider.ProviderAPIClient, error) { +func (s *svc) find(ctx context.Context, ref *provider.Reference) (provider.ProviderAPIClient, *registry.ProviderInfo, error) { p, err := s.findProviders(ctx, ref) if err != nil { - return nil, err + return nil, nil, err } - return s.getStorageProviderClient(ctx, p[0]) + + client, err := s.getStorageProviderClient(ctx, p[0]) + return client, p[0], err } func (s *svc) getStorageProviderClient(_ context.Context, p *registry.ProviderInfo) (provider.ProviderAPIClient, error) { @@ -2206,3 +2278,28 @@ type etagWithTS struct { Etag string Timestamp time.Time } + +func unwrap(ref *provider.Reference, providerPath string) (*provider.Reference, error) { + // all references with an id can be passed on to the driver + // there are two cases: + // 1. absolute id references (resource_id is set, path is empty) + // 2. relative references (resource_id is set, path starts with a `.`) + if ref.GetResourceId() != nil { + return ref, nil + } + + if !strings.HasPrefix(ref.GetPath(), "/") { + // abort, absolute path references must start with a `/` + return nil, errtypes.BadRequest("ref is invalid: " + ref.String()) + } + + p := strings.TrimPrefix(ref.Path, providerPath) + if p == "" { + p = "/" + } + return &provider.Reference{Path: p}, nil +} + +func wrap(ri *provider.ResourceInfo, providerInfo *registry.ProviderInfo) { + ri.Path = path.Join(providerInfo.ProviderPath, ri.Path) +} diff --git a/internal/grpc/services/gateway/usershareprovider.go b/internal/grpc/services/gateway/usershareprovider.go index 7511e0a5817..de268a9e0ac 100644 --- a/internal/grpc/services/gateway/usershareprovider.go +++ b/internal/grpc/services/gateway/usershareprovider.go @@ -369,7 +369,7 @@ func (s *svc) removeReference(ctx context.Context, resourceID *provider.Resource log := appctx.GetLogger(ctx) idReference := &provider.Reference{ResourceId: resourceID} - storageProvider, err := s.find(ctx, idReference) + storageProvider, _, err := s.find(ctx, idReference) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found") @@ -397,13 +397,18 @@ func (s *svc) removeReference(ctx context.Context, resourceID *provider.Resource sharePath := path.Join(homeRes.Path, s.c.ShareFolder, path.Base(statRes.Info.Path)) log.Debug().Str("share_path", sharePath).Msg("remove reference of share") - homeProvider, err := s.find(ctx, &provider.Reference{Path: sharePath}) + sharePathRef := &provider.Reference{Path: sharePath} + homeProvider, providerInfo, err := s.find(ctx, sharePathRef) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found") } return status.NewInternal(ctx, err, "error finding storage provider") } + ref, err := unwrap(sharePathRef, providerInfo.ProviderPath) + if err != nil { + return status.NewInternal(ctx, err, "could not unwrap share path reference") + } deleteReq := &provider.DeleteRequest{ Opaque: &typesv1beta1.Opaque{ @@ -412,7 +417,7 @@ func (s *svc) removeReference(ctx context.Context, resourceID *provider.Resource "deleting_shared_resource": {}, }, }, - Ref: &provider.Reference{Path: sharePath}, + Ref: ref, } deleteResp, err := homeProvider.Delete(ctx, deleteReq) @@ -443,7 +448,7 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource log := appctx.GetLogger(ctx) // get the metadata about the share - c, err := s.find(ctx, ref) + c, _, err := s.find(ctx, ref) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found") @@ -485,20 +490,25 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource refPath := path.Join(homeRes.Path, s.c.ShareFolder, path.Base(statRes.Info.Path)) log.Info().Msg("mount path will be:" + refPath) - createRefReq := &provider.CreateReferenceRequest{ - Ref: &provider.Reference{Path: refPath}, - // cs3 is the Scheme and %s/%s is the Opaque parts of a net.URL. - TargetUri: fmt.Sprintf("cs3:%s/%s", resourceID.GetStorageId(), resourceID.GetOpaqueId()), - } - - c, err = s.findByPath(ctx, refPath) + c, p, err := s.findByPath(ctx, refPath) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found") } return status.NewInternal(ctx, err, "error finding storage provider") } - + pRef, err := unwrap(&provider.Reference{Path: refPath}, p.ProviderPath) + if err != nil { + log.Err(err).Msg("gateway: error unwrapping reference") + return &rpc.Status{ + Code: rpc.Code_CODE_INTERNAL, + } + } + createRefReq := &provider.CreateReferenceRequest{ + Ref: pRef, + // cs3 is the Scheme and %s/%s is the Opaque parts of a net.URL. + TargetUri: fmt.Sprintf("cs3:%s/%s", resourceID.GetStorageId(), resourceID.GetOpaqueId()), + } createRefRes, err := c.CreateReference(ctx, createRefReq) if err != nil { log.Err(err).Msg("gateway: error calling GetHome") @@ -525,7 +535,7 @@ func (s *svc) denyGrant(ctx context.Context, id *provider.ResourceId, g *provide Grantee: g, } - c, err := s.find(ctx, ref) + c, _, err := s.find(ctx, ref) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found"), nil @@ -558,7 +568,7 @@ func (s *svc) addGrant(ctx context.Context, id *provider.ResourceId, g *provider }, } - c, err := s.find(ctx, ref) + c, _, err := s.find(ctx, ref) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found"), nil @@ -590,7 +600,7 @@ func (s *svc) updateGrant(ctx context.Context, id *provider.ResourceId, g *provi }, } - c, err := s.find(ctx, ref) + c, _, err := s.find(ctx, ref) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found"), nil @@ -623,7 +633,7 @@ func (s *svc) removeGrant(ctx context.Context, id *provider.ResourceId, g *provi }, } - c, err := s.find(ctx, ref) + c, _, err := s.find(ctx, ref) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { return status.NewNotFound(ctx, "storage provider not found"), nil diff --git a/internal/grpc/services/publicstorageprovider/publicstorageprovider.go b/internal/grpc/services/publicstorageprovider/publicstorageprovider.go index 9132811bb10..c3552933e97 100644 --- a/internal/grpc/services/publicstorageprovider/publicstorageprovider.go +++ b/internal/grpc/services/publicstorageprovider/publicstorageprovider.go @@ -49,14 +49,12 @@ func init() { } type config struct { - MountPath string `mapstructure:"mount_path"` GatewayAddr string `mapstructure:"gateway_addr"` } type service struct { - conf *config - mountPath string - gateway gateway.GatewayAPIClient + conf *config + gateway gateway.GatewayAPIClient } func (s *service) Close() error { @@ -87,17 +85,14 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { return nil, err } - mountPath := c.MountPath - gateway, err := pool.GetGatewayServiceClient(c.GatewayAddr) if err != nil { return nil, err } service := &service{ - conf: c, - mountPath: mountPath, - gateway: gateway, + conf: c, + gateway: gateway, } return service, nil @@ -495,7 +490,7 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide if err := addShare(statResponse.Info, ls); err != nil { appctx.GetLogger(ctx).Error().Err(err).Interface("share", ls).Interface("info", statResponse.Info).Msg("error when adding share") } - statResponse.Info.Path = path.Join(s.mountPath, "/", tkn, relativePath) + statResponse.Info.Path = path.Join("/", tkn, relativePath) filterPermissions(statResponse.Info.PermissionSet, ls.GetPermissions().Permissions) } @@ -554,7 +549,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer for i := range listContainerR.Infos { filterPermissions(listContainerR.Infos[i].PermissionSet, ls.GetPermissions().Permissions) - listContainerR.Infos[i].Path = path.Join(s.mountPath, "/", tkn, relativePath, path.Base(listContainerR.Infos[i].Path)) + listContainerR.Infos[i].Path = path.Join("/", tkn, relativePath, path.Base(listContainerR.Infos[i].Path)) if err := addShare(listContainerR.Infos[i], ls); err != nil { appctx.GetLogger(ctx).Error().Err(err).Interface("share", ls).Interface("info", listContainerR.Infos[i]).Msg("error when adding share") } @@ -594,15 +589,7 @@ func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (token st return "", "", errtypes.BadRequest("invalid ref: " + ref.String()) } - // i.e path: /public/{token}/path/to/subfolders - fn := ref.GetPath() - // fsfn: /{token}/path/to/subfolders - fsfn, err := s.trimMountPrefix(fn) - if err != nil { - return "", "", err - } - - parts := strings.SplitN(fsfn, "/", 3) + parts := strings.SplitN(ref.Path, "/", 3) token = parts[1] if len(parts) > 2 { relativePath = parts[2] @@ -667,13 +654,6 @@ func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) ( return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") } -func (s *service) trimMountPrefix(fn string) (string, error) { - if strings.HasPrefix(fn, s.mountPath) { - return path.Join("/", strings.TrimPrefix(fn, s.mountPath)), nil - } - return "", errors.Errorf("path=%q does not belong to this storage provider mount path=%q"+fn, s.mountPath) -} - // resolveToken returns the path and share for the publicly shared resource. func (s *service) resolveToken(ctx context.Context, token string) (string, *link.PublicShare, *provider.ResourceInfo, *rpc.Status, error) { driver, err := pool.GetGatewayServiceClient(s.conf.GatewayAddr) diff --git a/internal/grpc/services/storageprovider/storageprovider.go b/internal/grpc/services/storageprovider/storageprovider.go index 0560c2278d9..ad13e0dd2bf 100644 --- a/internal/grpc/services/storageprovider/storageprovider.go +++ b/internal/grpc/services/storageprovider/storageprovider.go @@ -26,7 +26,6 @@ import ( "path" "sort" "strconv" - "strings" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -51,7 +50,6 @@ func init() { } type config struct { - MountPath string `mapstructure:"mount_path" docs:"/;The path where the file system would be mounted."` MountID string `mapstructure:"mount_id" docs:"-;The ID of the mounted file system."` Driver string `mapstructure:"driver" docs:"localhome;The storage driver to be used."` Drivers map[string]map[string]interface{} `mapstructure:"drivers" docs:"url:pkg/storage/fs/localhome/localhome.go"` @@ -67,10 +65,6 @@ func (c *config) init() { c.Driver = "localhome" } - if c.MountPath == "" { - c.MountPath = "/" - } - if c.MountID == "" { c.MountID = "00000000-0000-0000-0000-000000000000" } @@ -99,12 +93,12 @@ func (c *config) init() { } type service struct { - conf *config - storage storage.FS - mountPath, mountID string - tmpFolder string - dataServerURL *url.URL - availableXS []*provider.ResourceChecksumPriority + conf *config + storage storage.FS + mountID string + tmpFolder string + dataServerURL *url.URL + availableXS []*provider.ResourceChecksumPriority } func (s *service) Close() error { @@ -156,7 +150,6 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { return nil, err } - mountPath := c.MountPath mountID := c.MountID fs, err := getFS(c) @@ -186,7 +179,6 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { conf: c, storage: fs, tmpFolder: c.TmpFolder, - mountPath: mountPath, mountID: mountID, dataServerURL: u, availableXS: xsTypes, @@ -202,15 +194,7 @@ func registerMimeTypes(mimes map[string]string) { } func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - err := errors.Wrap(err, "storageprovidersvc: error unwrapping path") - return &provider.SetArbitraryMetadataResponse{ - Status: status.NewInternal(ctx, err, "error setting arbitrary metadata"), - }, nil - } - - if err := s.storage.SetArbitraryMetadata(ctx, newRef, req.ArbitraryMetadata); err != nil { + if err := s.storage.SetArbitraryMetadata(ctx, req.Ref, req.ArbitraryMetadata); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -232,15 +216,7 @@ func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArb } func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - err := errors.Wrap(err, "storageprovidersvc: error unwrapping path") - return &provider.UnsetArbitraryMetadataResponse{ - Status: status.NewInternal(ctx, err, "error unsetting arbitrary metadata"), - }, nil - } - - if err := s.storage.UnsetArbitraryMetadata(ctx, newRef, req.ArbitraryMetadataKeys); err != nil { + if err := s.storage.UnsetArbitraryMetadata(ctx, req.Ref, req.ArbitraryMetadataKeys); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -277,16 +253,10 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia protocol.Protocol = "spaces" u.Path = path.Join(u.Path, "spaces", req.Ref.ResourceId.StorageId+"!"+req.Ref.ResourceId.OpaqueId, req.Ref.Path) } else { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.InitiateFileDownloadResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } // Currently, we only support the simple protocol for GET requests // Once we have multiple protocols, this would be moved to the fs layer protocol.Protocol = "simple" - u.Path = path.Join(u.Path, "simple", newRef.GetPath()) + u.Path = path.Join(u.Path, "simple", req.Ref.GetPath()) } protocol.DownloadEndpoint = u.String() @@ -300,13 +270,7 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia func (s *service) InitiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*provider.InitiateFileUploadResponse, error) { // TODO(labkode): same considerations as download log := appctx.GetLogger(ctx) - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.InitiateFileUploadResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - if newRef.GetPath() == "/" { + if req.Ref.GetPath() == "/" { return &provider.InitiateFileUploadResponse{ Status: status.NewInternal(ctx, errtypes.BadRequest("can't upload to mount path"), "can't upload to mount path"), }, nil @@ -333,7 +297,7 @@ func (s *service) InitiateFileUpload(ctx context.Context, req *provider.Initiate metadata["mtime"] = string(req.Opaque.Map["X-OC-Mtime"].Value) } } - uploadIDs, err := s.storage.InitiateUpload(ctx, newRef, uploadLength, metadata) + uploadIDs, err := s.storage.InitiateUpload(ctx, req.Ref, uploadLength, metadata) if err != nil { var st *rpc.Status switch err.(type) { @@ -395,8 +359,6 @@ func (s *service) GetPath(ctx context.Context, req *provider.GetPathRequest) (*p Status: status.NewInternal(ctx, err, "error getting path by id"), }, nil } - - fn = path.Join(s.mountPath, path.Clean(fn)) res := &provider.GetPathResponse{ Path: fn, Status: status.NewOK(ctx), @@ -405,11 +367,9 @@ func (s *service) GetPath(ctx context.Context, req *provider.GetPathRequest) (*p } func (s *service) GetHome(ctx context.Context, req *provider.GetHomeRequest) (*provider.GetHomeResponse, error) { - home := path.Join(s.mountPath) - res := &provider.GetHomeResponse{ Status: status.NewOK(ctx), - Path: home, + Path: "/", } return res, nil @@ -501,13 +461,7 @@ func (s *service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteSt } func (s *service) CreateContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.CreateContainerResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - if err := s.storage.CreateDir(ctx, newRef); err != nil { + if err := s.storage.CreateDir(ctx, req.Ref); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -531,13 +485,7 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta } func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.DeleteResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - if newRef.GetPath() == "/" { + if req.Ref.GetPath() == "/" { return &provider.DeleteResponse{ Status: status.NewInternal(ctx, errtypes.BadRequest("can't delete mount path"), "can't delete mount path"), }, nil @@ -552,7 +500,7 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } } - if err := s.storage.Delete(ctx, newRef); err != nil { + if err := s.storage.Delete(ctx, req.Ref); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -574,20 +522,7 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provider.MoveResponse, error) { - sourceRef, err := s.unwrap(ctx, req.Source) - if err != nil { - return &provider.MoveResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping source path"), - }, nil - } - targetRef, err := s.unwrap(ctx, req.Destination) - if err != nil { - return &provider.MoveResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping destination path"), - }, nil - } - - if err := s.storage.Move(ctx, sourceRef, targetRef); err != nil { + if err := s.storage.Move(ctx, req.Source, req.Destination); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -595,7 +530,7 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide case errtypes.PermissionDenied: st = status.NewPermissionDenied(ctx, err, "permission denied") default: - st = status.NewInternal(ctx, err, "error moving: "+sourceRef.String()) + st = status.NewInternal(ctx, err, "error moving: "+req.Source.String()) } return &provider.MoveResponse{ Status: st, @@ -617,14 +552,7 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide Value: attribute.StringValue(req.Ref.String()), }) - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.StatResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - md, err := s.storage.GetMD(ctx, newRef, req.ArbitraryMetadataKeys) + md, err := s.storage.GetMD(ctx, req.Ref, req.ArbitraryMetadataKeys) if err != nil { var st *rpc.Status switch err.(type) { @@ -639,12 +567,8 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide Status: st, }, nil } + md.Id.StorageId = s.mountID - if err := s.wrap(ctx, md, utils.IsAbsoluteReference(req.Ref)); err != nil { - return &provider.StatResponse{ - Status: status.NewInternal(ctx, err, "error wrapping path"), - }, nil - } res := &provider.StatResponse{ Status: status.NewOK(ctx), Info: md, @@ -656,19 +580,7 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, ctx := ss.Context() log := appctx.GetLogger(ctx) - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - res := &provider.ListContainerStreamResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - } - if err := ss.Send(res); err != nil { - log.Error().Err(err).Msg("ListContainerStream: error sending response") - return err - } - return nil - } - - mds, err := s.storage.ListFolder(ctx, newRef, req.ArbitraryMetadataKeys) + mds, err := s.storage.ListFolder(ctx, req.Ref, req.ArbitraryMetadataKeys) if err != nil { var st *rpc.Status switch err.(type) { @@ -689,18 +601,8 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, return nil } - prefixMountpoint := utils.IsAbsoluteReference(req.Ref) for _, md := range mds { - if err := s.wrap(ctx, md, prefixMountpoint); err != nil { - res := &provider.ListContainerStreamResponse{ - Status: status.NewInternal(ctx, err, "error wrapping path"), - } - if err := ss.Send(res); err != nil { - log.Error().Err(err).Msg("ListContainerStream: error sending response") - return err - } - return nil - } + md.Id.StorageId = s.mountID res := &provider.ListContainerStreamResponse{ Info: md, Status: status.NewOK(ctx), @@ -715,14 +617,7 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, } func (s *service) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.ListContainerResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - mds, err := s.storage.ListFolder(ctx, newRef, req.ArbitraryMetadataKeys) + mds, err := s.storage.ListFolder(ctx, req.Ref, req.ArbitraryMetadataKeys) if err != nil { var st *rpc.Status switch err.(type) { @@ -738,32 +633,19 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer }, nil } - var infos = make([]*provider.ResourceInfo, 0, len(mds)) - prefixMountpoint := utils.IsAbsoluteReference(req.Ref) - for _, md := range mds { - if err := s.wrap(ctx, md, prefixMountpoint); err != nil { - return &provider.ListContainerResponse{ - Status: status.NewInternal(ctx, err, "error wrapping path"), - }, nil - } - infos = append(infos, md) + for i := range mds { + mds[i].Id.StorageId = s.mountID } + res := &provider.ListContainerResponse{ Status: status.NewOK(ctx), - Infos: infos, + Infos: mds, } return res, nil } func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVersionsRequest) (*provider.ListFileVersionsResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.ListFileVersionsResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - revs, err := s.storage.ListRevisions(ctx, newRef) + revs, err := s.storage.ListRevisions(ctx, req.Ref) if err != nil { var st *rpc.Status switch err.(type) { @@ -789,14 +671,7 @@ func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVe } func (s *service) RestoreFileVersion(ctx context.Context, req *provider.RestoreFileVersionRequest) (*provider.RestoreFileVersionResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.RestoreFileVersionResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - if err := s.storage.RestoreRevision(ctx, newRef, req.Key); err != nil { + if err := s.storage.RestoreRevision(ctx, req.Ref, req.Key); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -821,12 +696,7 @@ func (s *service) ListRecycleStream(req *provider.ListRecycleStreamRequest, ss p ctx := ss.Context() log := appctx.GetLogger(ctx) - ref, err := s.unwrap(ctx, req.Ref) - if err != nil { - return err - } - - items, err := s.storage.ListRecycle(ctx, ref.ResourceId.OpaqueId, ref.Path) + items, err := s.storage.ListRecycle(ctx, req.Ref.ResourceId.OpaqueId, req.Ref.Path) if err != nil { var st *rpc.Status switch err.(type) { @@ -862,11 +732,7 @@ func (s *service) ListRecycleStream(req *provider.ListRecycleStreamRequest, ss p } func (s *service) ListRecycle(ctx context.Context, req *provider.ListRecycleRequest) (*provider.ListRecycleResponse, error) { - ref, err := s.unwrap(ctx, req.Ref) - if err != nil { - return nil, err - } - key, itemPath := router.ShiftPath(ref.Path) + key, itemPath := router.ShiftPath(req.Ref.Path) items, err := s.storage.ListRecycle(ctx, key, itemPath) // TODO(labkode): CRITICAL: fill recycle info with storage provider. if err != nil { @@ -893,11 +759,7 @@ func (s *service) ListRecycle(ctx context.Context, req *provider.ListRecycleRequ func (s *service) RestoreRecycleItem(ctx context.Context, req *provider.RestoreRecycleItemRequest) (*provider.RestoreRecycleItemResponse, error) { // TODO(labkode): CRITICAL: fill recycle info with storage provider. - ref, err := s.unwrap(ctx, req.Ref) - if err != nil { - return nil, err - } - if err := s.storage.RestoreRecycleItem(ctx, req.Key, ref.Path, req.RestoreRef); err != nil { + if err := s.storage.RestoreRecycleItem(ctx, req.Key, req.Ref.Path, req.RestoreRef); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -958,14 +820,7 @@ func (s *service) PurgeRecycle(ctx context.Context, req *provider.PurgeRecycleRe } func (s *service) ListGrants(ctx context.Context, req *provider.ListGrantsRequest) (*provider.ListGrantsResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.ListGrantsResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - grants, err := s.storage.ListGrants(ctx, newRef) + grants, err := s.storage.ListGrants(ctx, req.Ref) if err != nil { var st *rpc.Status switch err.(type) { @@ -989,13 +844,6 @@ func (s *service) ListGrants(ctx context.Context, req *provider.ListGrantsReques } func (s *service) DenyGrant(ctx context.Context, req *provider.DenyGrantRequest) (*provider.DenyGrantResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.DenyGrantResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - // check grantee type is valid if req.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_INVALID { return &provider.DenyGrantResponse{ @@ -1003,7 +851,7 @@ func (s *service) DenyGrant(ctx context.Context, req *provider.DenyGrantRequest) }, nil } - err = s.storage.DenyGrant(ctx, newRef, req.Grantee) + err := s.storage.DenyGrant(ctx, req.Ref, req.Grantee) if err != nil { var st *rpc.Status switch err.(type) { @@ -1026,13 +874,6 @@ func (s *service) DenyGrant(ctx context.Context, req *provider.DenyGrantRequest) } func (s *service) AddGrant(ctx context.Context, req *provider.AddGrantRequest) (*provider.AddGrantResponse, error) { - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.AddGrantResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - // check grantee type is valid if req.Grant.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_INVALID { return &provider.AddGrantResponse{ @@ -1040,7 +881,7 @@ func (s *service) AddGrant(ctx context.Context, req *provider.AddGrantRequest) ( }, nil } - err = s.storage.AddGrant(ctx, newRef, req.Grant) + err := s.storage.AddGrant(ctx, req.Ref, req.Grant) if err != nil { var st *rpc.Status switch err.(type) { @@ -1070,14 +911,7 @@ func (s *service) UpdateGrant(ctx context.Context, req *provider.UpdateGrantRequ }, nil } - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.UpdateGrantResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - if err := s.storage.UpdateGrant(ctx, newRef, req.Grant); err != nil { + if err := s.storage.UpdateGrant(ctx, req.Ref, req.Grant); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -1106,14 +940,7 @@ func (s *service) RemoveGrant(ctx context.Context, req *provider.RemoveGrantRequ }, nil } - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.RemoveGrantResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - if err := s.storage.RemoveGrant(ctx, newRef, req.Grant); err != nil { + if err := s.storage.RemoveGrant(ctx, req.Ref, req.Grant); err != nil { var st *rpc.Status switch err.(type) { case errtypes.IsNotFound: @@ -1146,14 +973,7 @@ func (s *service) CreateReference(ctx context.Context, req *provider.CreateRefer }, nil } - newRef, err := s.unwrap(ctx, req.Ref) - if err != nil { - return &provider.CreateReferenceResponse{ - Status: status.NewInternal(ctx, err, "error unwrapping path"), - }, nil - } - - if err := s.storage.CreateReference(ctx, newRef.GetPath(), u); err != nil { + if err := s.storage.CreateReference(ctx, req.Ref.GetPath(), u); err != nil { log.Err(err).Msg("error calling CreateReference") var st *rpc.Status switch err.(type) { @@ -1212,51 +1032,6 @@ func getFS(c *config) (storage.FS, error) { return nil, errtypes.NotFound("driver not found: " + c.Driver) } -func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (*provider.Reference, error) { - // all references with an id can be passed on to the driver - // there are two cases: - // 1. absolute id references (resource_id is set, path is empty) - // 2. relative references (resource_id is set, path starts with a `.`) - if ref.GetResourceId() != nil { - return ref, nil - } - - if !strings.HasPrefix(ref.GetPath(), "/") { - // abort, absolute path references must start with a `/` - return nil, errtypes.BadRequest("ref is invalid: " + ref.String()) - } - - // TODO move mount path trimming to the gateway - fn := ref.GetPath() - fsfn, err := s.trimMountPrefix(fn) - if err != nil { - return nil, err - } - - pathRef := &provider.Reference{Path: fsfn} - - return pathRef, nil -} - -func (s *service) trimMountPrefix(fn string) (string, error) { - if strings.HasPrefix(fn, s.mountPath) { - return path.Join("/", strings.TrimPrefix(fn, s.mountPath)), nil - } - return "", errtypes.BadRequest(fmt.Sprintf("path=%q does not belong to this storage provider mount path=%q", fn, s.mountPath)) -} - -func (s *service) wrap(ctx context.Context, ri *provider.ResourceInfo, prefixMountpoint bool) error { - if ri.Id.StorageId == "" { - // For wrapper drivers, the storage ID might already be set. In that case, skip setting it - ri.Id.StorageId = s.mountID - } - if prefixMountpoint { - // TODO move mount path prefixing to the gateway - ri.Path = path.Join(s.mountPath, ri.Path) - } - return nil -} - type descendingMtime []*provider.FileVersion func (v descendingMtime) Len() int { diff --git a/pkg/auth/scope/publicshare.go b/pkg/auth/scope/publicshare.go index 7c6314c26f7..aa895c7cddf 100644 --- a/pkg/auth/scope/publicshare.go +++ b/pkg/auth/scope/publicshare.go @@ -77,7 +77,7 @@ func checkStorageRef(s *link.PublicShare, r *provider.Reference) bool { } // r: - if strings.HasPrefix(r.GetPath(), "/public/"+s.Token) { + if strings.HasPrefix(r.GetPath(), "/public/"+s.Token) || strings.HasPrefix(r.GetPath(), "/"+s.Token) { return true } return false diff --git a/pkg/storage/registry/static/static.go b/pkg/storage/registry/static/static.go index 58d3845013e..8a9650dda85 100644 --- a/pkg/storage/registry/static/static.go +++ b/pkg/storage/registry/static/static.go @@ -43,9 +43,11 @@ func init() { var bracketRegex = regexp.MustCompile(`\[(.*?)\]`) type rule struct { - Mapping string `mapstructure:"mapping"` - Address string `mapstructure:"address"` - Aliases map[string]string `mapstructure:"aliases"` + Mapping string `mapstructure:"mapping"` + Address string `mapstructure:"address"` + ProviderID string `mapstructure:"provider_id"` + ProviderPath string `mapstructure:"provider_path"` + Aliases map[string]string `mapstructure:"aliases"` } type config struct { @@ -155,8 +157,9 @@ func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*re // TODO(labkode): fill path info based on provider id, if path and storage id points to same id, take that. if m := r.FindString(ref.ResourceId.StorageId); m != "" { return []*registrypb.ProviderInfo{{ - ProviderId: ref.ResourceId.StorageId, - Address: addr, + ProviderId: ref.ResourceId.StorageId, + Address: addr, + ProviderPath: rule.ProviderPath, }}, nil } } @@ -184,6 +187,7 @@ func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*re continue } match = ®istrypb.ProviderInfo{ + ProviderId: rule.ProviderID, ProviderPath: m, Address: addr, } @@ -193,6 +197,7 @@ func (b *reg) FindProviders(ctx context.Context, ref *provider.Reference) ([]*re combs := generateRegexCombinations(prefix) for _, c := range combs { shardedMatches = append(shardedMatches, ®istrypb.ProviderInfo{ + ProviderId: rule.ProviderID, ProviderPath: c, Address: addr, }) diff --git a/tests/oc-integration-tests/drone/gateway.toml b/tests/oc-integration-tests/drone/gateway.toml index 916ad90e01a..1bbe78ff7ee 100644 --- a/tests/oc-integration-tests/drone/gateway.toml +++ b/tests/oc-integration-tests/drone/gateway.toml @@ -64,11 +64,11 @@ home_provider = "/home" # mount a home storage provider that uses a context based path wrapper # to jail users into their home dir -"/home" = {"address" = "localhost:12000"} +"/home" = {"address" = "localhost:12000", "provider_id" = "123e4567-e89b-12d3-a456-426655440000"} # mount a storage provider without a path wrapper for direct access to users. -"/users" = {"address" = "localhost:11000"} -"123e4567-e89b-12d3-a456-426655440000" = {"address" = "localhost:11000"} +"/users" = {"address" = "localhost:11000", "provider_id" = "123e4567-e89b-12d3-a456-426655440000"} +"123e4567-e89b-12d3-a456-426655440000" = {"address" = "localhost:11000", "provider_id" = "123e4567-e89b-12d3-a456-426655440000", "provider_path" = "/users"} # another mount point might be "/projects/" "/public" = {"address" = "localhost:13000"} diff --git a/tests/oc-integration-tests/local/gateway.toml b/tests/oc-integration-tests/local/gateway.toml index 71289e93088..dda93419927 100644 --- a/tests/oc-integration-tests/local/gateway.toml +++ b/tests/oc-integration-tests/local/gateway.toml @@ -57,11 +57,11 @@ home_provider = "/home" # mount a home storage provider that uses a context based path wrapper # to jail users into their home dir -"/home" = {"address" = "localhost:12000"} +"/home" = {"address" = "localhost:12000", "provider_id" = "123e4567-e89b-12d3-a456-426655440000"} # mount a storage provider without a path wrapper for direct access to users. -"/users" = {"address" = "localhost:11000"} -"123e4567-e89b-12d3-a456-426655440000" = {"address" = "localhost:11000"} +"/users" = {"address" = "localhost:11000","provider_id" = "123e4567-e89b-12d3-a456-426655440000"} +"123e4567-e89b-12d3-a456-426655440000" = {"address" = "localhost:11000", "provider_id" = "123e4567-e89b-12d3-a456-426655440000", "provider_path" = "/users"} # another mount point might be "/projects/" "/public" = {"address" = "localhost:13000"}