diff --git a/Makefile b/Makefile index 8f97b63305e..a34f8a418ee 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,8 @@ test-integration: build-ci # This is needed for osx because this os does not support static linking # Use the build target without the static flag -test-integration-osx: build - cd tests/integration && go test -race ./... +test-integration-osx: off build + cd tests/integration && go test -race -v ./... litmus-test-old: build cd tests/oc-integration-tests/local && ../../../cmd/revad/revad -c frontend.toml & diff --git a/changelog/unreleased/space-id.md b/changelog/unreleased/space-id.md new file mode 100644 index 00000000000..5992f6eebee --- /dev/null +++ b/changelog/unreleased/space-id.md @@ -0,0 +1,5 @@ +Change: Use spaceID on the cs3api + +We introduced a new spaceID field on the cs3api to implement the spaces feature in a cleaner way. + +https://github.com/cs3org/reva/pull/3006 diff --git a/cmd/reva/upload.go b/cmd/reva/upload.go index 0967798806d..a2c4d4efd68 100644 --- a/cmd/reva/upload.go +++ b/cmd/reva/upload.go @@ -218,7 +218,7 @@ func uploadCommand() *command { info := res2.Info - fmt.Printf("File uploaded: %s:%s %d %s\n", info.Id.StorageId, info.Id.OpaqueId, info.Size, info.Path) + fmt.Printf("File uploaded: %s %d %s\n", info.Id, info.Size, info.Path) return nil } diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index 23dfa13e9cd..311957995f7 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -231,11 +231,11 @@ func (s *svc) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSp for _, f := range req.Filters { switch f.Type { case provider.ListStorageSpacesRequest_Filter_TYPE_ID: - sid, oid, err := storagespace.SplitID(f.GetId().OpaqueId) + sid, spid, oid, err := storagespace.SplitID(f.GetId().OpaqueId) if err != nil { continue } - filters["storage_id"], filters["opaque_id"] = sid, oid + filters["storage_id"], filters["space_id"], filters["opaque_id"] = sid, spid, oid case provider.ListStorageSpacesRequest_Filter_TYPE_OWNER: filters["owner_idp"] = f.GetOwner().Idp filters["owner_id"] = f.GetOwner().OpaqueId @@ -318,17 +318,14 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag _, purge = opaque.Map["purge"] } - storageid, opaqeid, err := storagespace.SplitID(req.Id.OpaqueId) + rid, err := storagespace.ParseID(req.Id.OpaqueId) if err != nil { return &provider.DeleteStorageSpaceResponse{ - Status: status.NewStatusFromErrType(ctx, fmt.Sprintf("gateway could not split space id %s", req.GetId().GetOpaqueId()), err), + Status: status.NewStatusFromErrType(ctx, fmt.Sprintf("gateway could not parse space id %s", req.GetId().GetOpaqueId()), err), }, nil } - ref := &provider.Reference{ResourceId: &provider.ResourceId{ - StorageId: storageid, - OpaqueId: opaqeid, - }} + ref := &provider.Reference{ResourceId: &rid} c, _, err := s.find(ctx, ref) if err != nil { return &provider.DeleteStorageSpaceResponse{ @@ -359,7 +356,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag log.Debug().Msg("purging storage space") // List all shares in this storage space lsRes, err := s.ListShares(ctx, &collaborationv1beta1.ListSharesRequest{ - Filters: []*collaborationv1beta1.Filter{share.StorageIDFilter(storageid)}, + Filters: []*collaborationv1beta1.Filter{share.StorageIDFilter(id.SpaceId)}, // FIXME rename the filter? @c0rby }) switch { case err != nil: @@ -384,7 +381,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag // List all public shares in this storage space lpsRes, err := s.ListPublicShares(ctx, &linkv1beta1.ListPublicSharesRequest{ - Filters: []*linkv1beta1.ListPublicSharesRequest_Filter{publicshare.StorageIDFilter(storageid)}, + Filters: []*linkv1beta1.ListPublicSharesRequest_Filter{publicshare.StorageIDFilter(id.SpaceId)}, // FIXME rename the filter? @c0rby }) switch { case err != nil: @@ -1102,7 +1099,9 @@ func (s *svc) findSpaces(ctx context.Context, ref *provider.Reference) ([]*regis case ref == nil: return nil, errtypes.BadRequest("missing reference") case ref.ResourceId != nil: - // no action needed in that case + if ref.ResourceId.OpaqueId == "" { + ref.ResourceId.OpaqueId = ref.ResourceId.SpaceId + } case ref.Path != "": // TODO implement a mount path cache in the registry? // nothing to do here either default: @@ -1115,6 +1114,7 @@ func (s *svc) findSpaces(ctx context.Context, ref *provider.Reference) ([]*regis } if ref.ResourceId != nil { filters["storage_id"] = ref.ResourceId.StorageId + filters["space_id"] = ref.ResourceId.SpaceId filters["opaque_id"] = ref.ResourceId.OpaqueId } @@ -1132,7 +1132,9 @@ func (s *svc) findSingleSpace(ctx context.Context, ref *provider.Reference) ([]* case ref == nil: return nil, errtypes.BadRequest("missing reference") case ref.ResourceId != nil: - // no action needed in that case + if ref.ResourceId.OpaqueId == "" { + ref.ResourceId.OpaqueId = ref.ResourceId.SpaceId + } case ref.Path != "": // TODO implement a mount path cache in the registry? // nothing to do here either default: @@ -1146,6 +1148,7 @@ func (s *svc) findSingleSpace(ctx context.Context, ref *provider.Reference) ([]* } if ref.ResourceId != nil { filters["storage_id"] = ref.ResourceId.StorageId + filters["space_id"] = ref.ResourceId.SpaceId filters["opaque_id"] = ref.ResourceId.OpaqueId } @@ -1208,6 +1211,7 @@ func unwrap(ref *provider.Reference, mountPoint string, root *provider.ResourceI return &provider.Reference{ ResourceId: &provider.ResourceId{ StorageId: ref.ResourceId.StorageId, + SpaceId: ref.ResourceId.SpaceId, OpaqueId: ref.ResourceId.OpaqueId, }, Path: ref.Path, diff --git a/internal/grpc/services/gateway/storageprovidercache.go b/internal/grpc/services/gateway/storageprovidercache.go index 978006fd324..76e121fbd67 100644 --- a/internal/grpc/services/gateway/storageprovidercache.go +++ b/internal/grpc/services/gateway/storageprovidercache.go @@ -105,7 +105,7 @@ func (c Caches) RemoveStat(user *userpb.User, res *provider.ResourceId) { sid := "" oid := "" if res != nil { - sid = "sid:" + res.StorageId + sid = "sid:" + res.SpaceId oid = "oid:" + res.OpaqueId } @@ -133,7 +133,7 @@ func (c Caches) RemoveListStorageProviders(res *provider.ResourceId) { if res == nil { return } - sid := res.StorageId + sid := res.SpaceId cache := c[listproviders] for _, key := range cache.GetKeys() { @@ -182,9 +182,9 @@ func (c *cachedRegistryClient) ListStorageProviders(ctx context.Context, in *reg user := ctxpkg.ContextMustGetUser(ctx) - storageID := sdk.DecodeOpaqueMap(in.Opaque)["storage_id"] + spaceID := sdk.DecodeOpaqueMap(in.Opaque)["space_id"] - key := user.GetId().GetOpaqueId() + "!" + storageID + key := user.GetId().GetOpaqueId() + "!" + spaceID if key != "!" { s := ®istry.ListStorageProvidersResponse{} if err := pullFromCache(cache, key, s); err == nil { @@ -198,9 +198,9 @@ func (c *cachedRegistryClient) ListStorageProviders(ctx context.Context, in *reg return nil, err case resp.Status.Code != rpc.Code_CODE_OK: return resp, nil - case storageID == "": + case spaceID == "": return resp, nil - case storageID == utils.ShareStorageProviderID: // TODO do we need to compare providerid and spaceid separately? + case spaceID == utils.ShareStorageSpaceID: // TODO do we need to compare providerid and spaceid separately? return resp, nil default: return resp, pushToCache(cache, key, resp) @@ -230,7 +230,7 @@ type cachedAPIClient struct { // a key looks like: uid:1234-1233!sid:5678-5677!oid:9923-9934!path:/path/to/source // as you see it adds "uid:"/"sid:"/"oid:" prefixes to the uuids so they can be differentiated func statKey(user *userpb.User, ref *provider.Reference, metaDataKeys, fieldMaskPaths []string) string { - if ref == nil || ref.ResourceId == nil || ref.ResourceId.StorageId == "" { + if ref == nil || ref.ResourceId == nil || ref.ResourceId.SpaceId == "" { return "" } @@ -238,7 +238,7 @@ func statKey(user *userpb.User, ref *provider.Reference, metaDataKeys, fieldMask key.WriteString("uid:") key.WriteString(user.Id.OpaqueId) key.WriteString("!sid:") - key.WriteString(ref.ResourceId.StorageId) + key.WriteString(ref.ResourceId.SpaceId) key.WriteString("!oid:") key.WriteString(ref.ResourceId.OpaqueId) key.WriteString("!path:") diff --git a/internal/grpc/services/gateway/usershareprovider.go b/internal/grpc/services/gateway/usershareprovider.go index 43aaad35de9..872840482bf 100644 --- a/internal/grpc/services/gateway/usershareprovider.go +++ b/internal/grpc/services/gateway/usershareprovider.go @@ -32,7 +32,6 @@ import ( "github.com/cs3org/reva/v2/pkg/rgrpc/status" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" "github.com/cs3org/reva/v2/pkg/storage/utils/grants" - "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/pkg/errors" ) @@ -717,11 +716,11 @@ func refIsSpaceRoot(ref *provider.ResourceId) bool { if ref == nil { return false } - if ref.StorageId == "" || ref.OpaqueId == "" { + if ref.SpaceId == "" || ref.OpaqueId == "" { return false } - _, sid := storagespace.SplitStorageID(ref.GetStorageId()) - return sid == ref.OpaqueId + + return ref.SpaceId == ref.OpaqueId } func shareIsSpaceRoot(key *collaboration.ShareKey) bool { diff --git a/internal/grpc/services/publicstorageprovider/publicstorageprovider.go b/internal/grpc/services/publicstorageprovider/publicstorageprovider.go index e1fb1b66603..6ce279fb737 100644 --- a/internal/grpc/services/publicstorageprovider/publicstorageprovider.go +++ b/internal/grpc/services/publicstorageprovider/publicstorageprovider.go @@ -105,10 +105,6 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { } func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -127,10 +123,6 @@ func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.Unse // SetLock puts a lock on the given reference func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*provider.SetLockResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -145,10 +137,6 @@ func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*p // GetLock returns an existing lock on the given reference func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*provider.GetLockResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -163,10 +151,6 @@ func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*p // RefreshLock refreshes an existing lock on the given reference func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequest) (*provider.RefreshLockResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -181,10 +165,6 @@ func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequ // Unlock removes an existing lock from the given reference func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provider.UnlockResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -198,10 +178,6 @@ func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*pro } func (s *service) InitiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*provider.InitiateFileDownloadResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - statReq := &provider.StatRequest{Ref: req.Ref} statRes, err := s.Stat(ctx, statReq) if err != nil { @@ -325,10 +301,6 @@ func (s *service) initiateFileDownload(ctx context.Context, req *provider.Initia } func (s *service) InitiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*provider.InitiateFileUploadResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - cs3Ref, _, ls, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -413,14 +385,6 @@ func (s *service) CreateStorageSpace(ctx context.Context, req *provider.CreateSt // so id based requests can find the correct storage provider. These spaces // have their root set to the shared resource. func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSpacesRequest) (*provider.ListStorageSpacesResponse, error) { - for i, f := range req.Filters { - if f.Type == provider.ListStorageSpacesRequest_Filter_TYPE_ID { - _, id := storagespace.SplitStorageID(f.GetId().GetOpaqueId()) - req.Filters[i].Term = &provider.ListStorageSpacesRequest_Filter_Id{Id: &provider.StorageSpaceId{OpaqueId: id}} - break - } - } - spaceTypes := map[string]struct{}{} var exists = struct{}{} appendTypes := []string{} @@ -435,17 +399,19 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora } spaceTypes[spaceType] = exists case provider.ListStorageSpacesRequest_Filter_TYPE_ID: - spaceid, shareid, err := storagespace.SplitID(f.GetId().OpaqueId) + resID, err := storagespace.ParseID(f.GetId().GetOpaqueId()) if err != nil { - continue + return &provider.ListStorageSpacesResponse{ + Status: &rpc.Status{Code: rpc.Code_CODE_INVALID_ARGUMENT, Message: err.Error()}, + }, nil } - if spaceid != utils.PublicStorageProviderID { + if resID.SpaceId != utils.PublicStorageSpaceID { return &provider.ListStorageSpacesResponse{ // a specific id was requested, return not found instead of empty list Status: &rpc.Status{Code: rpc.Code_CODE_NOT_FOUND}, }, nil } - spaceID = &provider.ResourceId{StorageId: spaceid, OpaqueId: shareid} + spaceID = &resID } } @@ -480,7 +446,7 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora // we know a grant for this resource space := &provider.StorageSpace{ Id: &provider.StorageSpaceId{ - OpaqueId: root.StorageId + "!" + root.OpaqueId, + OpaqueId: storagespace.FormatResourceID(*root), }, SpaceType: "grant", Owner: &userv1beta1.User{Id: share.Owner}, @@ -508,7 +474,7 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora } space := &provider.StorageSpace{ Id: &provider.StorageSpaceId{ - OpaqueId: root.StorageId + "!" + root.OpaqueId, + OpaqueId: storagespace.FormatResourceID(*root), }, SpaceType: "mountpoint", Owner: &userv1beta1.User{Id: share.Owner}, // FIXME actually, the mount point belongs to no one? @@ -552,10 +518,6 @@ func (s *service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteSt } func (s *service) CreateContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "CreateContainer") defer span.End() @@ -596,10 +558,6 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta } func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ref, _, _, st, err := s.translatePublicRefToCS3Ref(ctx, req.Ref) switch { case err != nil: @@ -613,10 +571,6 @@ func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) } func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Delete") defer span.End() @@ -657,13 +611,6 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provider.MoveResponse, error) { - if req.Source.GetResourceId() != nil { - _, req.Source.ResourceId.StorageId = storagespace.SplitStorageID(req.Source.ResourceId.StorageId) - } - if req.Destination.GetResourceId() != nil { - _, req.Destination.ResourceId.StorageId = storagespace.SplitStorageID(req.Destination.ResourceId.StorageId) - } - ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Move") defer span.End() @@ -727,10 +674,6 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide } func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "Stat") defer span.End() @@ -828,9 +771,6 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, } func (s *service) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } share, ok := extractLinkFromScope(ctx) if !ok { diff --git a/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go index ef108120e37..56b20478c33 100644 --- a/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go +++ b/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go @@ -105,10 +105,6 @@ func New(gateway gateway.GatewayAPIClient, c collaboration.CollaborationAPIClien } func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -131,10 +127,6 @@ func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArb } func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -157,10 +149,6 @@ func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.Unse } func (s *service) InitiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*provider.InitiateFileDownloadResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -213,10 +201,6 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia } func (s *service) InitiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*provider.InitiateFileUploadResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -314,14 +298,6 @@ func (s *service) CreateStorageSpace(ctx context.Context, req *provider.CreateSt // should be found. func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSpacesRequest) (*provider.ListStorageSpacesResponse, error) { - for i, f := range req.Filters { - if f.Type == provider.ListStorageSpacesRequest_Filter_TYPE_ID { - _, id := storagespace.SplitStorageID(f.GetId().GetOpaqueId()) - req.Filters[i].Term = &provider.ListStorageSpacesRequest_Filter_Id{Id: &provider.StorageSpaceId{OpaqueId: id}} - break - } - } - spaceTypes := map[string]struct{}{} var exists = struct{}{} var fetchShares bool @@ -342,18 +318,18 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora } spaceTypes[spaceType] = exists case provider.ListStorageSpacesRequest_Filter_TYPE_ID: - spaceid, shareid, err := storagespace.SplitID(f.GetId().OpaqueId) + storageid, spaceid, shareid, err := storagespace.SplitID(f.GetId().OpaqueId) if err != nil { continue } - if spaceid != utils.ShareStorageProviderID { + if spaceid != utils.ShareStorageSpaceID { return &provider.ListStorageSpacesResponse{ // a specific id was requested, return not found instead of empty list Status: &rpc.Status{Code: rpc.Code_CODE_NOT_FOUND}, }, nil } - spaceID = &provider.ResourceId{StorageId: spaceid, OpaqueId: shareid} + spaceID = &provider.ResourceId{StorageId: storageid, SpaceId: spaceid, OpaqueId: shareid} } } @@ -384,8 +360,9 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora switch k { case "virtual": virtualRootID := &provider.ResourceId{ - StorageId: storagespace.FormatStorageID(utils.ShareStorageProviderID, utils.ShareStorageSpaceID), - OpaqueId: utils.ShareStorageProviderID, + StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, + OpaqueId: utils.ShareStorageSpaceID, } if spaceID == nil || isShareJailRoot(spaceID) { earliestShare, atLeastOneAccepted := findEarliestShare(receivedShares, shareInfo) @@ -444,6 +421,7 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora } root := &provider.ResourceId{ StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: receivedShare.Share.Id.OpaqueId, } // do we filter by id @@ -467,12 +445,13 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora // add the resourceID for the grant if receivedShare.Share.ResourceId != nil { opaque = utils.AppendPlainToOpaque(opaque, "grantStorageID", receivedShare.Share.ResourceId.StorageId) + opaque = utils.AppendPlainToOpaque(opaque, "grantSpaceID", receivedShare.Share.ResourceId.SpaceId) opaque = utils.AppendPlainToOpaque(opaque, "grantOpaqueID", receivedShare.Share.ResourceId.OpaqueId) } // prefix storageid if we are responsible - if root.StorageId == utils.ShareStorageSpaceID { - root.StorageId = storagespace.FormatStorageID(utils.ShareStorageProviderID, root.StorageId) + if root.SpaceId == utils.ShareStorageSpaceID { + root.StorageId = utils.ShareStorageProviderID } space := &provider.StorageSpace{ @@ -511,10 +490,6 @@ func (s *service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteSt } func (s *service) CreateContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -536,10 +511,6 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta } func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -556,7 +527,7 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } // the root of a share always has the path "." - if req.Ref.ResourceId.StorageId == utils.ShareStorageProviderID && req.Ref.Path == "." { + if req.Ref.ResourceId.StorageId == utils.ShareStorageProviderID && req.Ref.ResourceId.SpaceId == utils.ShareStorageSpaceID && req.Ref.Path == "." { err := s.rejectReceivedShare(ctx, receivedShare) if err != nil { return &provider.DeleteResponse{ @@ -575,13 +546,6 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provider.MoveResponse, error) { - if req.Source.GetResourceId() != nil { - _, req.Source.ResourceId.StorageId = storagespace.SplitStorageID(req.Source.ResourceId.StorageId) - } - if req.Destination.GetResourceId() != nil { - _, req.Destination.ResourceId.StorageId = storagespace.SplitStorageID(req.Destination.ResourceId.StorageId) - } - appctx.GetLogger(ctx).Debug(). Interface("source", req.Source). Interface("destination", req.Destination). @@ -634,7 +598,7 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide Status: rpcStatus, }, nil } - if srcReceivedShare.Share.ResourceId.StorageId != dstReceivedShare.Share.ResourceId.StorageId { + if srcReceivedShare.Share.ResourceId.SpaceId != dstReceivedShare.Share.ResourceId.SpaceId { return &provider.MoveResponse{ Status: status.NewInvalid(ctx, "sharesstorageprovider: can not move between shares on different storages"), }, nil @@ -668,10 +632,6 @@ func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*pro } func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - if isVirtualRoot(req.Ref) { owner, ok := ctxpkg.ContextGetUser(ctx) if !ok { @@ -752,10 +712,6 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, return gstatus.Errorf(codes.Unimplemented, "method not implemented") } func (s *service) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - if isVirtualRoot(req.Ref) { // The root is empty, it is filled by mountpoints // so, when accessing the root via /dav/spaces, we need to list the accepted shares with their mountpoint @@ -831,10 +787,6 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer }) } func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVersionsRequest) (*provider.ListFileVersionsResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -857,10 +809,6 @@ func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVe } func (s *service) RestoreFileVersion(ctx context.Context, req *provider.RestoreFileVersionRequest) (*provider.RestoreFileVersionResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - receivedShare, rpcStatus, err := s.resolveAcceptedShare(ctx, req.Ref) appctx.GetLogger(ctx).Debug(). Interface("ref", req.Ref). @@ -932,10 +880,6 @@ func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) // GetQuota returns 0 free quota. It is virtual ... the shares may have a different quota ... func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) (*provider.GetQuotaResponse, error) { - if req.Ref.GetResourceId() != nil { - _, req.Ref.ResourceId.StorageId = storagespace.SplitStorageID(req.Ref.ResourceId.StorageId) - } - // FIXME use req.Ref to get real quota return &provider.GetQuotaResponse{ Status: status.NewOK(ctx), @@ -951,7 +895,7 @@ func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Refere return nil, status.NewInvalidArg(ctx, "sharesstorageprovider: can only handle relative references"), nil } - if ref.ResourceId.StorageId != utils.ShareStorageProviderID { + if ref.ResourceId.SpaceId != utils.ShareStorageSpaceID { return nil, status.NewNotFound(ctx, "sharesstorageprovider: not found "+ref.String()), nil } @@ -1120,13 +1064,12 @@ func isRename(s, d *provider.Reference) bool { } func isShareJailChild(id *provider.ResourceId) bool { - _, space := storagespace.SplitStorageID(id.StorageId) - return space == utils.ShareStorageProviderID && id.OpaqueId != utils.ShareStorageProviderID + return id.SpaceId == utils.ShareStorageProviderID && id.OpaqueId != utils.ShareStorageProviderID } func isShareJailRoot(id *provider.ResourceId) bool { - _, space := storagespace.SplitStorageID(id.StorageId) - return space == utils.ShareStorageProviderID && id.OpaqueId == utils.ShareStorageProviderID + + return id.SpaceId == utils.ShareStorageProviderID && id.OpaqueId == utils.ShareStorageProviderID } func isVirtualRoot(ref *provider.Reference) bool { diff --git a/internal/grpc/services/sharesstorageprovider/sharesstorageprovider_test.go b/internal/grpc/services/sharesstorageprovider/sharesstorageprovider_test.go index 0cf69ea6404..e839a3c58d5 100644 --- a/internal/grpc/services/sharesstorageprovider/sharesstorageprovider_test.go +++ b/internal/grpc/services/sharesstorageprovider/sharesstorageprovider_test.go @@ -75,7 +75,8 @@ var _ = Describe("Sharesstorageprovider", func() { BeforeEach(func() { ShareJail = &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, - OpaqueId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, + OpaqueId: utils.ShareStorageSpaceID, } BaseShare = &collaboration.ReceivedShare{ @@ -86,6 +87,7 @@ var _ = Describe("Sharesstorageprovider", func() { }, ResourceId: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, Permissions: &collaboration.SharePermissions{ @@ -109,6 +111,7 @@ var _ = Describe("Sharesstorageprovider", func() { }, ResourceId: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, Permissions: &collaboration.SharePermissions{ @@ -128,7 +131,8 @@ var _ = Describe("Sharesstorageprovider", func() { Ref: &sprovider.Reference{ ResourceId: &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, - OpaqueId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, + OpaqueId: utils.ShareStorageSpaceID, }, Path: ".", }, @@ -138,6 +142,7 @@ var _ = Describe("Sharesstorageprovider", func() { Ref: &sprovider.Reference{ ResourceId: &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: "shareid", }, Path: ".", @@ -148,6 +153,7 @@ var _ = Describe("Sharesstorageprovider", func() { Ref: &sprovider.Reference{ ResourceId: &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: "shareid", }, Path: ".", @@ -171,6 +177,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-shareddir", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, PermissionSet: &sprovider.ResourcePermissions{ @@ -187,6 +194,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-subdir", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "subdir", }, PermissionSet: &sprovider.ResourcePermissions{ @@ -203,6 +211,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-subdir-file", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "file", }, PermissionSet: &sprovider.ResourcePermissions{ @@ -219,6 +228,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-shareddir", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, PermissionSet: &sprovider.ResourcePermissions{ @@ -251,6 +261,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-shareddir/share1-subdir", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "subdir", }, Size: 1, @@ -261,6 +272,7 @@ var _ = Describe("Sharesstorageprovider", func() { Path: "share1-shareddir/share1-subdir/share1-subdir-file", Id: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "file", }, Size: 1, @@ -425,6 +437,7 @@ var _ = Describe("Sharesstorageprovider", func() { }, ResourceId: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, Permissions: &collaboration.SharePermissions{ @@ -443,6 +456,7 @@ var _ = Describe("Sharesstorageprovider", func() { }, ResourceId: &sprovider.ResourceId{ StorageId: "share1-storageid", + SpaceId: "share1-storageid", OpaqueId: "shareddir", }, Permissions: &collaboration.SharePermissions{ @@ -635,6 +649,7 @@ var _ = Describe("Sharesstorageprovider", func() { Ref: &sprovider.Reference{ ResourceId: &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: BaseShare.Share.Id.OpaqueId, }, Path: ".", @@ -678,6 +693,7 @@ var _ = Describe("Sharesstorageprovider", func() { Source: &sprovider.Reference{ ResourceId: &sprovider.ResourceId{ StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: BaseShare.Share.Id.OpaqueId, }, Path: ".", diff --git a/internal/grpc/services/storageprovider/storageprovider.go b/internal/grpc/services/storageprovider/storageprovider.go index ce34ddcbece..950e55f4412 100644 --- a/internal/grpc/services/storageprovider/storageprovider.go +++ b/internal/grpc/services/storageprovider/storageprovider.go @@ -196,9 +196,6 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { } func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) err := s.storage.SetArbitraryMetadata(ctx, req.Ref, req.ArbitraryMetadata) @@ -209,9 +206,6 @@ func (s *service) SetArbitraryMetadata(ctx context.Context, req *provider.SetArb } func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) err := s.storage.UnsetArbitraryMetadata(ctx, req.Ref, req.ArbitraryMetadataKeys) @@ -223,9 +217,6 @@ func (s *service) UnsetArbitraryMetadata(ctx context.Context, req *provider.Unse // SetLock puts a lock on the given reference func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*provider.SetLockResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - err := s.storage.SetLock(ctx, req.Ref, req.Lock) return &provider.SetLockResponse{ @@ -235,9 +226,6 @@ func (s *service) SetLock(ctx context.Context, req *provider.SetLockRequest) (*p // GetLock returns an existing lock on the given reference func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*provider.GetLockResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - lock, err := s.storage.GetLock(ctx, req.Ref) return &provider.GetLockResponse{ @@ -248,9 +236,6 @@ func (s *service) GetLock(ctx context.Context, req *provider.GetLockRequest) (*p // RefreshLock refreshes an existing lock on the given reference func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequest) (*provider.RefreshLockResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - err := s.storage.RefreshLock(ctx, req.Ref, req.Lock) return &provider.RefreshLockResponse{ @@ -260,9 +245,6 @@ func (s *service) RefreshLock(ctx context.Context, req *provider.RefreshLockRequ // Unlock removes an existing lock from the given reference func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provider.UnlockResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - err := s.storage.Unlock(ctx, req.Ref, req.Lock) return &provider.UnlockResponse{ @@ -271,9 +253,6 @@ func (s *service) Unlock(ctx context.Context, req *provider.UnlockRequest) (*pro } func (s *service) InitiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*provider.InitiateFileDownloadResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // TODO(labkode): maybe add some checks before download starts? eg. check permissions? // TODO(labkode): maybe add short-lived token? // We now simply point the client to the data server. @@ -287,7 +266,7 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia if utils.IsRelativeReference(req.Ref) { protocol.Protocol = "spaces" - u.Path = path.Join(u.Path, "spaces", req.Ref.ResourceId.StorageId+"!"+req.Ref.ResourceId.OpaqueId, req.Ref.Path) + u.Path = path.Join(u.Path, "spaces", storagespace.FormatResourceID(*req.Ref.ResourceId), req.Ref.Path) } else { // Currently, we only support the simple protocol for GET requests // Once we have multiple protocols, this would be moved to the fs layer @@ -304,9 +283,6 @@ func (s *service) InitiateFileDownload(ctx context.Context, req *provider.Initia } func (s *service) InitiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*provider.InitiateFileUploadResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // TODO(labkode): same considerations as download log := appctx.GetLogger(ctx) if req.Ref.GetPath() == "/" { @@ -433,9 +409,6 @@ func (s *service) InitiateFileUpload(ctx context.Context, req *provider.Initiate } func (s *service) GetPath(ctx context.Context, req *provider.GetPathRequest) (*provider.GetPathResponse, error) { - providerID := unwrapProviderID(req.GetResourceId()) - defer rewrapProviderID(req.GetResourceId(), providerID) - // TODO(labkode): check that the storage ID is the same as the storage provider id. fn, err := s.storage.GetPathByID(ctx, req.ResourceId) if err != nil { @@ -503,15 +476,6 @@ func (s *service) CreateStorageSpace(ctx context.Context, req *provider.CreateSt } func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSpacesRequest) (*provider.ListStorageSpacesResponse, error) { - for i, f := range req.Filters { - if f.Type == provider.ListStorageSpacesRequest_Filter_TYPE_ID { - _, id := storagespace.SplitStorageID(f.GetId().GetOpaqueId()) - req.Filters[i].Term = &provider.ListStorageSpacesRequest_Filter_Id{Id: &provider.StorageSpaceId{OpaqueId: id}} - } else if f.Type == provider.ListStorageSpacesRequest_Filter_TYPE_PATH { - req.Filters[i].Term = &provider.ListStorageSpacesRequest_Filter_Path{Path: f.GetPath()} - } - } - log := appctx.GetLogger(ctx) // TODO this is just temporary. Update the API to include this flag. @@ -561,11 +525,6 @@ func (s *service) ListStorageSpaces(ctx context.Context, req *provider.ListStora } func (s *service) UpdateStorageSpace(ctx context.Context, req *provider.UpdateStorageSpaceRequest) (*provider.UpdateStorageSpaceResponse, error) { - if req.GetStorageSpace().GetId() != nil { - _, req.StorageSpace.Id.OpaqueId = storagespace.SplitStorageID(req.StorageSpace.Id.OpaqueId) - _, req.StorageSpace.Root.StorageId = storagespace.SplitStorageID(req.StorageSpace.Root.StorageId) - } - res, err := s.storage.UpdateStorageSpace(ctx, req) if err != nil { appctx.GetLogger(ctx). @@ -582,10 +541,6 @@ func (s *service) UpdateStorageSpace(ctx context.Context, req *provider.UpdateSt } func (s *service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorageSpaceRequest) (*provider.DeleteStorageSpaceResponse, error) { - if req.GetId() != nil { - _, req.Id.OpaqueId = storagespace.SplitStorageID(req.Id.OpaqueId) - } - if err := s.storage.DeleteStorageSpace(ctx, req); err != nil { var st *rpc.Status switch err.(type) { @@ -616,9 +571,6 @@ func (s *service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteSt } func (s *service) CreateContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // FIXME these should be part of the CreateContainerRequest object if req.Opaque != nil { if e, ok := req.Opaque.Map["lockid"]; ok && e.Decoder == "plain" { @@ -634,9 +586,6 @@ func (s *service) CreateContainer(ctx context.Context, req *provider.CreateConta } func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // FIXME these should be part of the TouchFileRequest object if req.Opaque != nil { if e, ok := req.Opaque.Map["lockid"]; ok && e.Decoder == "plain" { @@ -652,9 +601,6 @@ func (s *service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) } func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - if req.Ref.GetPath() == "/" { return &provider.DeleteResponse{ Status: status.NewInternal(ctx, "can't delete mount path"), @@ -692,11 +638,6 @@ func (s *service) Delete(ctx context.Context, req *provider.DeleteRequest) (*pro } func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provider.MoveResponse, error) { - sourceProviderID := unwrapProviderID(req.Source.GetResourceId()) - defer rewrapProviderID(req.Source.GetResourceId(), sourceProviderID) - destProviderID := unwrapProviderID(req.Destination.GetResourceId()) - defer rewrapProviderID(req.Destination.GetResourceId(), destProviderID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) err := s.storage.Move(ctx, req.Source, req.Destination) @@ -707,9 +648,6 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide } func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx, span := rtrace.DefaultProvider().Tracer(tracerName).Start(ctx, "stat") defer span.End() @@ -726,12 +664,8 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide } // The storage driver might set the mount ID by itself, in which case skip this step - if mountID, _ := storagespace.SplitStorageID(md.Id.GetStorageId()); mountID == "" { - if providerID == "" { - providerID = s.conf.MountID - } - - md.Id.StorageId = storagespace.FormatStorageID(providerID, md.Id.GetStorageId()) + if md.Id.GetStorageId() == "" { + md.Id.StorageId = s.conf.MountID } return &provider.StatResponse{ @@ -741,9 +675,6 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide } func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, ss provider.ProviderAPI_ListContainerStreamServer) error { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx := ss.Context() log := appctx.GetLogger(ctx) @@ -789,9 +720,6 @@ func (s *service) ListContainerStream(req *provider.ListContainerStreamRequest, } func (s *service) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - mds, err := s.storage.ListFolder(ctx, req.GetRef(), req.GetArbitraryMetadataKeys(), req.GetFieldMask().GetPaths()) res := &provider.ListContainerResponse{ Status: status.NewStatusFromErrType(ctx, "list container", err), @@ -808,9 +736,6 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer } func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVersionsRequest) (*provider.ListFileVersionsResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - revs, err := s.storage.ListRevisions(ctx, req.Ref) sort.Sort(descendingMtime(revs)) @@ -822,9 +747,6 @@ func (s *service) ListFileVersions(ctx context.Context, req *provider.ListFileVe } func (s *service) RestoreFileVersion(ctx context.Context, req *provider.RestoreFileVersionRequest) (*provider.RestoreFileVersionResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) err := s.storage.RestoreRevision(ctx, req.Ref, req.Key) @@ -835,9 +757,6 @@ func (s *service) RestoreFileVersion(ctx context.Context, req *provider.RestoreF } func (s *service) ListRecycleStream(req *provider.ListRecycleStreamRequest, ss provider.ProviderAPI_ListRecycleStreamServer) error { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx := ss.Context() log := appctx.GetLogger(ctx) @@ -887,9 +806,6 @@ func (s *service) ListRecycleStream(req *provider.ListRecycleStreamRequest, ss p } func (s *service) ListRecycle(ctx context.Context, req *provider.ListRecycleRequest) (*provider.ListRecycleResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - key, itemPath := router.ShiftPath(req.Key) items, err := s.storage.ListRecycle(ctx, req.Ref, key, itemPath) if err != nil { @@ -927,11 +843,6 @@ func (s *service) ListRecycle(ctx context.Context, req *provider.ListRecycleRequ } func (s *service) RestoreRecycleItem(ctx context.Context, req *provider.RestoreRecycleItemRequest) (*provider.RestoreRecycleItemResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - restoreProviderID := unwrapProviderID(req.RestoreRef.GetResourceId()) - defer rewrapProviderID(req.RestoreRef.GetResourceId(), restoreProviderID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) // TODO(labkode): CRITICAL: fill recycle info with storage provider. @@ -945,9 +856,6 @@ func (s *service) RestoreRecycleItem(ctx context.Context, req *provider.RestoreR } func (s *service) PurgeRecycle(ctx context.Context, req *provider.PurgeRecycleRequest) (*provider.PurgeRecycleResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // FIXME these should be part of the PurgeRecycleRequest object if req.Opaque != nil { if e, ok := req.Opaque.Map["lockid"]; ok && e.Decoder == "plain" { @@ -993,9 +901,6 @@ func (s *service) PurgeRecycle(ctx context.Context, req *provider.PurgeRecycleRe } func (s *service) ListGrants(ctx context.Context, req *provider.ListGrantsRequest) (*provider.ListGrantsResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - grants, err := s.storage.ListGrants(ctx, req.Ref) if err != nil { var st *rpc.Status @@ -1026,9 +931,6 @@ func (s *service) ListGrants(ctx context.Context, req *provider.ListGrantsReques } func (s *service) DenyGrant(ctx context.Context, req *provider.DenyGrantRequest) (*provider.DenyGrantResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // check grantee type is valid if req.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_INVALID { return &provider.DenyGrantResponse{ @@ -1070,9 +972,6 @@ func (s *service) DenyGrant(ctx context.Context, req *provider.DenyGrantRequest) } func (s *service) AddGrant(ctx context.Context, req *provider.AddGrantRequest) (*provider.AddGrantResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) // TODO: update CS3 APIs @@ -1099,9 +998,6 @@ func (s *service) AddGrant(ctx context.Context, req *provider.AddGrantRequest) ( } func (s *service) UpdateGrant(ctx context.Context, req *provider.UpdateGrantRequest) (*provider.UpdateGrantResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - // FIXME these should be part of the UpdateGrantRequest object if req.Opaque != nil { if e, ok := req.Opaque.Map["lockid"]; ok && e.Decoder == "plain" { @@ -1124,9 +1020,6 @@ func (s *service) UpdateGrant(ctx context.Context, req *provider.UpdateGrantRequ } func (s *service) RemoveGrant(ctx context.Context, req *provider.RemoveGrantRequest) (*provider.RemoveGrantResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - ctx = ctxpkg.ContextSetLockID(ctx, req.LockId) // check targetType is valid @@ -1144,9 +1037,6 @@ func (s *service) RemoveGrant(ctx context.Context, req *provider.RemoveGrantRequ } func (s *service) CreateReference(ctx context.Context, req *provider.CreateReferenceRequest) (*provider.CreateReferenceResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - log := appctx.GetLogger(ctx) // parse uri is valid @@ -1190,9 +1080,6 @@ func (s *service) CreateSymlink(ctx context.Context, req *provider.CreateSymlink } func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) (*provider.GetQuotaResponse, error) { - providerID := unwrapProviderID(req.Ref.GetResourceId()) - defer rewrapProviderID(req.Ref.GetResourceId(), providerID) - total, used, remaining, err := s.storage.GetQuota(ctx, req.Ref) if err != nil { var st *rpc.Status @@ -1233,10 +1120,12 @@ func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) ( func (s *service) addMissingStorageProviderID(resourceID *provider.ResourceId, spaceID *provider.StorageSpaceId) { // The storage driver might set the mount ID by itself, in which case skip this step - if mountID, _ := storagespace.SplitStorageID(resourceID.GetStorageId()); mountID == "" { - resourceID.StorageId = storagespace.FormatStorageID(s.conf.MountID, resourceID.GetStorageId()) + if resourceID.GetStorageId() == "" { + resourceID.StorageId = s.conf.MountID if spaceID != nil { - spaceID.OpaqueId = storagespace.FormatStorageID(s.conf.MountID, spaceID.GetOpaqueId()) + rid, _ := storagespace.ParseID(spaceID.GetOpaqueId()) + rid.StorageId = s.conf.MountID + spaceID.OpaqueId, _ = storagespace.FormatReference(&provider.Reference{ResourceId: &rid}) } } } @@ -1261,17 +1150,3 @@ func (v descendingMtime) Less(i, j int) bool { func (v descendingMtime) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - -func unwrapProviderID(id *provider.ResourceId) string { - var spid string - if id != nil { - spid, id.StorageId = storagespace.SplitStorageID(id.StorageId) - } - return spid -} - -func rewrapProviderID(id *provider.ResourceId, spid string) { - if id != nil { - id.StorageId = storagespace.FormatStorageID(spid, id.StorageId) - } -} diff --git a/internal/http/services/owncloud/ocdav/ocdav.go b/internal/http/services/owncloud/ocdav/ocdav.go index f107647ee8d..994460a3e5a 100644 --- a/internal/http/services/owncloud/ocdav/ocdav.go +++ b/internal/http/services/owncloud/ocdav/ocdav.go @@ -43,7 +43,6 @@ import ( "github.com/cs3org/reva/v2/pkg/storage/favorite" "github.com/cs3org/reva/v2/pkg/storage/favorite/registry" "github.com/cs3org/reva/v2/pkg/storage/utils/templates" - "github.com/cs3org/reva/v2/pkg/storagespace" rtrace "github.com/cs3org/reva/v2/pkg/trace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/mitchellh/mapstructure" @@ -459,10 +458,7 @@ func (s *svc) sspReferenceIsChildOf(ctx context.Context, client gatewayv1beta1.G } func (s *svc) referenceIsChildOf(ctx context.Context, client gatewayv1beta1.GatewayAPIClient, child, parent *provider.Reference) (bool, error) { - _, csid := storagespace.SplitStorageID(child.ResourceId.StorageId) - _, psid := storagespace.SplitStorageID(parent.ResourceId.StorageId) - - if child.ResourceId.StorageId != parent.ResourceId.StorageId { + if child.ResourceId.SpaceId != parent.ResourceId.SpaceId { return false, nil // Not on the same storage -> not a child } @@ -470,7 +466,7 @@ func (s *svc) referenceIsChildOf(ctx context.Context, client gatewayv1beta1.Gate return strings.HasPrefix(child.Path, parent.Path+"/"), nil // Relative to the same resource -> compare paths } - if csid == utils.ShareStorageProviderID || psid == utils.ShareStorageProviderID { + if child.ResourceId.SpaceId == utils.ShareStorageSpaceID || parent.ResourceId.SpaceId == utils.ShareStorageSpaceID { // the sharesstorageprovider needs some special handling return s.sspReferenceIsChildOf(ctx, client, child, parent) } diff --git a/internal/http/services/owncloud/ocdav/ocdav_test.go b/internal/http/services/owncloud/ocdav/ocdav_test.go index e6108d44235..67f9448d760 100644 --- a/internal/http/services/owncloud/ocdav/ocdav_test.go +++ b/internal/http/services/owncloud/ocdav/ocdav_test.go @@ -25,8 +25,8 @@ import ( ) func TestWrapResourceID(t *testing.T) { - expected := "storageid" + "!" + "opaqueid" - wrapped := storagespace.FormatResourceID(providerv1beta1.ResourceId{StorageId: "storageid", OpaqueId: "opaqueid"}) + expected := "storageid" + "$" + "spaceid" + "!" + "opaqueid" + wrapped := storagespace.FormatResourceID(providerv1beta1.ResourceId{StorageId: "storageid", SpaceId: "spaceid", OpaqueId: "opaqueid"}) if wrapped != expected { t.Errorf("wrapped id doesn't have the expected format: got %s expected %s", wrapped, expected) diff --git a/internal/http/services/owncloud/ocdav/propfind/propfind.go b/internal/http/services/owncloud/ocdav/propfind/propfind.go index df90d295d48..d10bcd0ae51 100644 --- a/internal/http/services/owncloud/ocdav/propfind/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind/propfind.go @@ -960,7 +960,7 @@ func mdToPropResponse(ctx context.Context, pf *XML, md *provider.ResourceInfo, p } // replace fileid of /public/{token} mountpoint with grant fileid - if ls != nil && md.Id != nil && md.Id.StorageId == utils.PublicStorageProviderID && md.Id.OpaqueId == ls.Token { + if ls != nil && md.Id != nil && md.Id.SpaceId == utils.PublicStorageSpaceID && md.Id.OpaqueId == ls.Token { md.Id = ls.ResourceId } @@ -981,7 +981,7 @@ func mdToPropResponse(ctx context.Context, pf *XML, md *provider.ResourceInfo, p propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:id", id), prop.Escaped("oc:fileid", id), - prop.Escaped("oc:spaceid", md.Id.StorageId), + prop.Escaped("oc:spaceid", md.Id.SpaceId), ) } @@ -1093,7 +1093,7 @@ func mdToPropResponse(ctx context.Context, pf *XML, md *provider.ResourceInfo, p } case "spaceid": if md.Id != nil { - propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:spaceid", md.Id.StorageId)) + propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:spaceid", md.Id.SpaceId)) } else { propstatNotFound.Prop = append(propstatNotFound.Prop, prop.Escaped("oc:spaceid", "")) } diff --git a/internal/http/services/owncloud/ocdav/propfind/propfind_test.go b/internal/http/services/owncloud/ocdav/propfind/propfind_test.go index 0816ed7ef64..c7e80d11819 100644 --- a/internal/http/services/owncloud/ocdav/propfind/propfind_test.go +++ b/internal/http/services/owncloud/ocdav/propfind/propfind_test.go @@ -34,6 +34,7 @@ import ( "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind" "github.com/cs3org/reva/v2/pkg/rgrpc/status" + "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/cs3org/reva/v2/tests/cs3mocks/mocks" "github.com/stretchr/testify/mock" @@ -106,8 +107,8 @@ var _ = Describe("Propfind", func() { }, }, }, - Id: &sprovider.StorageSpaceId{OpaqueId: "foospace!root"}, - Root: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, + Id: &sprovider.StorageSpaceId{OpaqueId: storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"})}, + Root: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Name: "foospace", } fooquxspace = &sprovider.StorageSpace{ @@ -119,8 +120,8 @@ var _ = Describe("Propfind", func() { }, }, }, - Id: &sprovider.StorageSpaceId{OpaqueId: "fooquxspace!root"}, - Root: &sprovider.ResourceId{StorageId: "fooquxspace", OpaqueId: "root"}, + Id: &sprovider.StorageSpaceId{OpaqueId: storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "root"})}, + Root: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "root"}, Name: "fooquxspace", } fooFileShareSpace = &sprovider.StorageSpace{ @@ -132,8 +133,8 @@ var _ = Describe("Propfind", func() { }, }, }, - Id: &sprovider.StorageSpaceId{OpaqueId: "fooFileShareSpace!sharedfile"}, - Root: &sprovider.ResourceId{StorageId: "fooFileShareSpace", OpaqueId: "sharedfile"}, + Id: &sprovider.StorageSpaceId{OpaqueId: storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace", OpaqueId: "sharedfile"})}, + Root: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace", OpaqueId: "sharedfile"}, Name: "fooFileShareSpace", } fooFileShare2Space = &sprovider.StorageSpace{ @@ -145,8 +146,8 @@ var _ = Describe("Propfind", func() { }, }, }, - Id: &sprovider.StorageSpaceId{OpaqueId: "fooFileShareSpace2!sharedfile2"}, - Root: &sprovider.ResourceId{StorageId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, + Id: &sprovider.StorageSpaceId{OpaqueId: storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace2", OpaqueId: "sharedfile2"})}, + Root: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, Name: "fooFileShareSpace2", } fooDirShareSpace = &sprovider.StorageSpace{ @@ -158,8 +159,8 @@ var _ = Describe("Propfind", func() { }, }, }, - Id: &sprovider.StorageSpaceId{OpaqueId: "fooDirShareSpace!shareddir"}, - Root: &sprovider.ResourceId{StorageId: "fooDirShareSpace", OpaqueId: "shareddir"}, + Id: &sprovider.StorageSpaceId{OpaqueId: storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddir"})}, + Root: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddir"}, Name: "fooDirShareSpace", } @@ -169,89 +170,89 @@ var _ = Describe("Propfind", func() { // - ./baz, file, 1 byte, opaqueid "baz" // - ./dir, folder, 30 bytes, opaqueid "dir" // - ./dir/entry, file, 30 bytes, opaqueid "direntry" - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: ".", Size: uint64(131), }) - mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "."}, + mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "."}, []*sprovider.ResourceInfo{ { Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "bar"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "bar"}, Path: "bar", Size: 100, }, { Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "baz"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "baz"}, Path: "baz", Size: 1, }, { Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "dir"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "dir"}, Path: "dir", Size: 30, }, }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "./bar"}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "./bar"}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "bar"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "bar"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "./bar", Size: uint64(100), }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "bar"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "bar"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "bar"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "bar"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "./bar", Size: uint64(100), }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "./baz"}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "./baz"}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "baz"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "baz"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "./baz", Size: uint64(1), }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "baz"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "baz"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "baz"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "baz"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "./baz", Size: uint64(1), }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "./dir"}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "./dir"}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "dir"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "dir"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: "./dir", Size: uint64(30), }) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "dir"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "dir"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "dir"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "dir"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: "./dir", Size: uint64(30), }) - mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "root"}, Path: "./dir"}, + mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}, Path: "./dir"}, []*sprovider.ResourceInfo{ { - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "direntry"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "direntry"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "entry", Size: 30, }, }) - mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "dir"}, Path: "."}, + mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "dir"}, Path: "."}, []*sprovider.ResourceInfo{ { - Id: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "direntry"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "direntry"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "entry", Size: 30, @@ -261,28 +262,28 @@ var _ = Describe("Propfind", func() { // For the space mounted a /foo/qux we assign a storageid "foospace" and a root opaqueid "root" // it contains one resource // - ./quux, file, 1000 bytes, opaqueid "quux" - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooquxspace", OpaqueId: "root"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "root"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "fooquxspace", OpaqueId: "root"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "root"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: ".", Size: uint64(1000), }) - mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooquxspace", OpaqueId: "root"}, Path: "."}, + mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "root"}, Path: "."}, []*sprovider.ResourceInfo{ { - Id: &sprovider.ResourceId{StorageId: "fooquxspace", OpaqueId: "quux"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooquxspace", OpaqueId: "quux"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "./quux", Size: 1000, }, }) - // For the space mounted a /foo/Shares/sharedFile we assign a storageid "fooFileShareSpace" and a root opaqueid "sharedfile" + // For the space mounted a /foo/Shares/sharedFile we assign a spaceid "fooFileShareSpace" and a root opaqueid "sharedfile" // it is a file resource, 2000 bytes, opaqueid "sharedfile" - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooFileShareSpace", OpaqueId: "sharedfile"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace", OpaqueId: "sharedfile"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "fooFileShareSpace", OpaqueId: "sharedfile"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace", OpaqueId: "sharedfile"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: ".", Size: uint64(2000), @@ -290,11 +291,11 @@ var _ = Describe("Propfind", func() { Etag: "1", }) - // For the space mounted a /foo/Shares/sharedFile2 we assign a storageid "fooFileShareSpace2" and a root opaqueid "sharedfile2" + // For the space mounted a /foo/Shares/sharedFile2 we assign a spaceid "fooFileShareSpace2" and a root opaqueid "sharedfile2" // it is a file resource, 2500 bytes, opaqueid "sharedfile2" - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooFileShareSpace2", OpaqueId: "sharedfile2"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: ".", Size: uint64(2500), @@ -302,22 +303,22 @@ var _ = Describe("Propfind", func() { Etag: "2", }) - // For the space mounted a /foo/Shares/sharedFile2 we assign a storageid "fooDirShareSpace" and a root opaqueid "shareddir" + // For the space mounted a /foo/Shares/sharedFile2 we assign a spaceid "fooDirShareSpace" and a root opaqueid "shareddir" // it is a folder containing one resource // ./something, file, 1500 bytes, opaqueid "shareddirsomething" - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooDirShareSpace", OpaqueId: "shareddir"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddir"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{StorageId: "fooDirShareSpace", OpaqueId: "shareddir"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddir"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: ".", Size: uint64(1500), Mtime: &typesv1beta1.Timestamp{Seconds: 3}, Etag: "3", }) - mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "fooDirShareSpace", OpaqueId: "shareddir"}, Path: "."}, + mockListContainer(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddir"}, Path: "."}, []*sprovider.ResourceInfo{ { - Id: &sprovider.ResourceId{StorageId: "fooDirShareSpace", OpaqueId: "shareddirsomething"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "fooDirShareSpace", OpaqueId: "shareddirsomething"}, Type: sprovider.ResourceType_RESOURCE_TYPE_FILE, Path: "something", Size: 1500, @@ -337,7 +338,7 @@ var _ = Describe("Propfind", func() { shares = []*link.PublicShare{ { Id: &link.PublicShareId{OpaqueId: "share1"}, - ResourceId: &sprovider.ResourceId{StorageId: "foospace", OpaqueId: "bar"}, + ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "bar"}, }, } default: @@ -371,9 +372,9 @@ var _ = Describe("Propfind", func() { Status: status.NewOK(ctx), StorageSpaces: []*sprovider.StorageSpace{}, }, nil) - mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{OpaqueId: "foospace", StorageId: "foospace"}, Path: "."}, + mockStat(&sprovider.Reference{ResourceId: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "foospace"}, Path: "."}, &sprovider.ResourceInfo{ - Id: &sprovider.ResourceId{OpaqueId: "foospace", StorageId: "foospace"}, + Id: &sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "foospace"}, Type: sprovider.ResourceType_RESOURCE_TYPE_CONTAINER, Path: ".", Size: uint64(131), @@ -733,7 +734,9 @@ var _ = Describe("Propfind", func() { Expect(err).ToNot(HaveOccurred()) req = req.WithContext(ctx) - handler.HandleSpacesPropfind(rr, req, "foospace!root") + spaceID := storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}) + spaceIDUrl := net.EncodePath(spaceID) + handler.HandleSpacesPropfind(rr, req, spaceID) Expect(rr.Code).To(Equal(http.StatusMultiStatus)) res, _, err := readResponse(rr.Result().Body) @@ -741,19 +744,19 @@ var _ = Describe("Propfind", func() { Expect(len(res.Responses)).To(Equal(4)) root := res.Responses[0] - Expect(root.Href).To(Equal("http:/127.0.0.1:3000/foospace%21root/")) + Expect(root.Href).To(Equal("http:/127.0.0.1:3000/" + spaceIDUrl + "/")) Expect(string(root.Propstat[0].Prop[0].InnerXML)).To(ContainSubstring("131")) bar := res.Responses[1] - Expect(bar.Href).To(Equal("http:/127.0.0.1:3000/foospace%21root/bar")) + Expect(bar.Href).To(Equal("http:/127.0.0.1:3000/" + spaceIDUrl + "/bar")) Expect(string(bar.Propstat[0].Prop[0].InnerXML)).To(ContainSubstring("100")) baz := res.Responses[2] - Expect(baz.Href).To(Equal("http:/127.0.0.1:3000/foospace%21root/baz")) + Expect(baz.Href).To(Equal("http:/127.0.0.1:3000/" + spaceIDUrl + "/baz")) Expect(string(baz.Propstat[0].Prop[0].InnerXML)).To(ContainSubstring("1")) dir := res.Responses[3] - Expect(dir.Href).To(Equal("http:/127.0.0.1:3000/foospace%21root/dir/")) + Expect(dir.Href).To(Equal("http:/127.0.0.1:3000/" + spaceIDUrl + "/dir/")) Expect(string(dir.Propstat[0].Prop[0].InnerXML)).To(ContainSubstring("30")) }) @@ -763,7 +766,8 @@ var _ = Describe("Propfind", func() { Expect(err).ToNot(HaveOccurred()) req = req.WithContext(ctx) - handler.HandleSpacesPropfind(rr, req, "foospace!root") + spaceID := storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}) + handler.HandleSpacesPropfind(rr, req, spaceID) Expect(rr.Code).To(Equal(http.StatusMultiStatus)) res, _, err := readResponse(rr.Result().Body) @@ -778,7 +782,8 @@ var _ = Describe("Propfind", func() { Expect(err).ToNot(HaveOccurred()) req = req.WithContext(ctx) - handler.HandleSpacesPropfind(rr, req, "foospace!root") + spaceID := storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}) + handler.HandleSpacesPropfind(rr, req, spaceID) Expect(rr.Code).To(Equal(http.StatusMultiStatus)) res, _, err := readResponse(rr.Result().Body) @@ -795,7 +800,9 @@ var _ = Describe("Propfind", func() { Expect(err).ToNot(HaveOccurred()) req = req.WithContext(ctx) - handler.HandleSpacesPropfind(rr, req, "foospace!root") + spaceID := storagespace.FormatResourceID(sprovider.ResourceId{StorageId: "provider-1", SpaceId: "foospace", OpaqueId: "root"}) + spaceIDUrl := net.EncodePath(spaceID) + handler.HandleSpacesPropfind(rr, req, spaceID) Expect(rr.Code).To(Equal(http.StatusMultiStatus)) res, _, err := readResponse(rr.Result().Body) @@ -807,11 +814,11 @@ var _ = Describe("Propfind", func() { paths = append(paths, r.Href) } Expect(paths).To(ConsistOf( - "http:/127.0.0.1:3000/foospace%21root/", - "http:/127.0.0.1:3000/foospace%21root/bar", - "http:/127.0.0.1:3000/foospace%21root/baz", - "http:/127.0.0.1:3000/foospace%21root/dir/", - "http:/127.0.0.1:3000/foospace%21root/dir/entry", + "http:/127.0.0.1:3000/"+spaceIDUrl+"/", + "http:/127.0.0.1:3000/"+spaceIDUrl+"/bar", + "http:/127.0.0.1:3000/"+spaceIDUrl+"/baz", + "http:/127.0.0.1:3000/"+spaceIDUrl+"/dir/", + "http:/127.0.0.1:3000/"+spaceIDUrl+"/dir/entry", )) }) }) diff --git a/internal/http/services/owncloud/ocdav/trashbin.go b/internal/http/services/owncloud/ocdav/trashbin.go index e7dc3ee49e7..415dad12558 100644 --- a/internal/http/services/owncloud/ocdav/trashbin.go +++ b/internal/http/services/owncloud/ocdav/trashbin.go @@ -191,7 +191,7 @@ func (h *TrashbinHandler) listTrashbin(w http.ResponseWriter, r *http.Request, s if depth == net.DepthZero { rootHref := path.Join(refBase, key, itemPath) - propRes, err := h.formatTrashPropfind(ctx, s, ref.ResourceId.StorageId, refBase, rootHref, nil, nil) + propRes, err := h.formatTrashPropfind(ctx, s, ref.ResourceId.SpaceId, refBase, rootHref, nil, nil) if err != nil { sublog.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError) @@ -276,7 +276,7 @@ func (h *TrashbinHandler) listTrashbin(w http.ResponseWriter, r *http.Request, s } rootHref := path.Join(refBase, key, itemPath) - propRes, err := h.formatTrashPropfind(ctx, s, ref.ResourceId.StorageId, refBase, rootHref, &pf, items) + propRes, err := h.formatTrashPropfind(ctx, s, ref.ResourceId.SpaceId, refBase, rootHref, &pf, items) if err != nil { sublog.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError) diff --git a/internal/http/services/owncloud/ocdav/versions.go b/internal/http/services/owncloud/ocdav/versions.go index 24e4696ff9e..155c3f92eef 100644 --- a/internal/http/services/owncloud/ocdav/versions.go +++ b/internal/http/services/owncloud/ocdav/versions.go @@ -83,6 +83,7 @@ func (h *VersionsHandler) Handler(s *svc, rid *provider.ResourceId) http.Handler ref := &provider.Reference{ ResourceId: &provider.ResourceId{ StorageId: rid.StorageId, + SpaceId: rid.SpaceId, OpaqueId: key, }, Path: utils.MakeRelativePath(r.URL.Path), @@ -94,6 +95,7 @@ func (h *VersionsHandler) Handler(s *svc, rid *provider.ResourceId) http.Handler ref := &provider.Reference{ ResourceId: &provider.ResourceId{ StorageId: rid.StorageId, + SpaceId: rid.SpaceId, OpaqueId: key, }, Path: utils.MakeRelativePath(r.URL.Path), diff --git a/internal/http/services/owncloud/ocs/conversions/main.go b/internal/http/services/owncloud/ocs/conversions/main.go index ef087fdf53a..97d7660312d 100644 --- a/internal/http/services/owncloud/ocs/conversions/main.go +++ b/internal/http/services/owncloud/ocs/conversions/main.go @@ -178,6 +178,7 @@ type TokenInfo struct { // if not password protected StorageID string `json:"storage_id" xml:"storage_id"` + SpaceID string `json:"space_id" xml:"space_id"` OpaqueID string `json:"opaque_id" xml:"opaque_id"` Path string `json:"path" xml:"path"` diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/token.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/token.go index 76b2c670c46..29d36303a4c 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/token.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/sharees/token.go @@ -37,6 +37,7 @@ import ( "github.com/cs3org/reva/v2/pkg/appctx" ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "google.golang.org/grpc/metadata" ) @@ -81,7 +82,7 @@ func handleGetToken(ctx context.Context, tkn string, pw string, c gateway.Gatewa } if protected && !t.PasswordProtected { - space, status, err := spacelookup.LookUpStorageSpaceByID(ctx, c, t.StorageID) + space, status, err := spacelookup.LookUpStorageSpaceByID(ctx, c, storagespace.FormatResourceID(provider.ResourceId{StorageId: t.StorageID, SpaceId: t.SpaceID, OpaqueId: t.OpaqueID})) // add info only if user is able to stat if err == nil && status.Code == rpc.Code_CODE_OK { t.SpacePath = utils.ReadPlainFromOpaque(space.Opaque, "path") @@ -114,6 +115,7 @@ func buildTokenInfo(owner *user.User, tkn string, token string, passProtected bo _ = json.Unmarshal(sRes.Info.Opaque.Map["link-share"].Value, ls) t.StorageID = ls.ResourceId.GetStorageId() + t.SpaceID = ls.ResourceId.GetSpaceId() t.OpaqueID = ls.ResourceId.GetOpaqueId() return t, nil diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 71e767d3ab7..bea2cb13b05 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -863,7 +863,8 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { // first stat mount point, but the shares storage provider only handles accepted shares so we send the try to make the requests for only those if rs.State == collaboration.ShareState_SHARE_STATE_ACCEPTED { mountID := &provider.ResourceId{ - StorageId: storagespace.FormatStorageID(utils.ShareStorageProviderID, utils.ShareStorageSpaceID), + StorageId: utils.ShareStorageProviderID, + SpaceId: utils.ShareStorageSpaceID, OpaqueId: rs.Share.Id.OpaqueId, } info, status, err = h.getResourceInfoByID(ctx, client, mountID) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go index 4274a3d08ce..bf7ce4e2a87 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go @@ -211,6 +211,7 @@ func (h *Handler) findProvider(ctx context.Context, ref *provider.Reference) (*r } if ref.ResourceId != nil { filters["storage_id"] = ref.ResourceId.StorageId + filters["space_id"] = ref.ResourceId.SpaceId filters["opaque_id"] = ref.ResourceId.OpaqueId } diff --git a/pkg/app/provider/demo/demo.go b/pkg/app/provider/demo/demo.go index 5a1672f9f32..a2552364d2c 100644 --- a/pkg/app/provider/demo/demo.go +++ b/pkg/app/provider/demo/demo.go @@ -27,6 +27,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/app" "github.com/cs3org/reva/v2/pkg/app/provider/registry" + "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/mitchellh/mapstructure" ) @@ -39,7 +40,7 @@ type demoProvider struct { } func (p *demoProvider) GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (*appprovider.OpenInAppURL, error) { - url := fmt.Sprintf("