Repository: owncloud/ocis
Pull request #3365 (2022-03-22 15:37:30)

[full-ci] Fix shares graph
<!--
Thanks for submitting a change to ownCloud!

This is the bug tracker for the oCIS component. Find other components at https://github.com/owncloud/core/blob/master/.github/CONTRIBUTING.md#guidelines

For fixing potential security issues please see https://owncloud.org/security/

To make it possible for us to get your change reviewed and merged please carefully fill out the requested information below.

Please note that any kind of change needs first be submitted to the master branch which holds the next version of oCIS.

Please set the following labels:

- Set label "Status:Needs-Review" for review or "Status:In-Progress" if the PR still has open tasks.
- Assignment: assign to self
- Reviewers: pick at least one
-->

## Description

Change: Add remote item to mountpoint and fix spaceID

A mountpoint represents the mounted share on the share receivers side. The original resource is located where the grant has been set. This item is now shown as libregraph remoteItem on the mountpoint. While adding this, we fixed the spaceID for mountpoints.

```json
{
            "driveAlias": "mountpoint/test",
            "driveType": "mountpoint",
            "id": "a0ca6a90-a365-4782-871e-d44447bbc668!28430982-37ee-4492-9cef-dc94a7807211",
            "name": "Test",
            "owner": {
                "user": {
                    "id": "ddc2004c-0977-11eb-9d3f-a793888cd0f8"
                }
            },
            "quota": {
                "remaining": 0,
                "state": "normal",
                "total": 0,
                "used": 0
            },
            "root": {
                "eTag": "\"3cacbbbd2838ff0996d4723f049a2c9e\"",
                "id": "a0ca6a90-a365-4782-871e-d44447bbc668!28430982-37ee-4492-9cef-dc94a7807211",
                "remoteItem": {
                    "eTag": "\"3cacbbbd2838ff0996d4723f049a2c9e\"",
                    "folder": {},
                    "id": "ddc2004c-0977-11eb-9d3f-a793888cd0f8!fb5963b0-7dfc-48cc-ac69-daed96fcfa41",
                    "lastModifiedDateTime": "2022-03-25T11:33:22.051056+01:00",
                    "name": "Test",
                    "size": 629,
                    "webDavUrl": "https://localhost:9200/dav/spaces/ddc2004c-0977-11eb-9d3f-a793888cd0f8!fb5963b0-7dfc-48cc-ac69-daed96fcfa41"
                },
                "webDavUrl": "https://localhost:9200/dav/spaces/a0ca6a90-a365-4782-871e-d44447bbc668!28430982-37ee-4492-9cef-dc94a7807211"
            }
        },
```

## Related Issue

- Needs https://github.com/cs3org/reva/pull/2664/

## Motivation and Context

- Needed for using the share jail

## How Has This Been Tested?
- manually

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [x] Code changes
- [x] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 


sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; ![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [![C](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/C-16px.png 'C')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [1 Bug](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL)

[![12.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '12.7%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list) [12.7% Coverage](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list)  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [2 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL)

[![10.3%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/0-16px.png '10.3%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list) [10.3% Coverage](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list)  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=3365&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL) [5 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=3365&resolved=false&types=CODE_SMELL)

[![79.3%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/60-16px.png '79.3%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list) [79.3% Coverage](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_coverage&view=list)  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=3365&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/.drone.env b/.drone.env
index 9911e34e3c9..00e65a19990 100644
--- a/.drone.env
+++ b/.drone.env
@@ -3,5 +3,5 @@ CORE_COMMITID=df1a1eb2816775fe9c202c50ec8e8a1e01ecb256
 CORE_BRANCH=master
 
 # The test runner source for UI tests
-WEB_COMMITID=77faf9890974083c0c555fd83586c2448845b11d
-WEB_BRANCH=master
+WEB_COMMITID=80d9bb6962cb034dc861116f59ae25f39fb3a52c
+WEB_BRANCH=no-shares-folder
diff --git a/changelog/unreleased/add-remote-item-fix-spaceID.md b/changelog/unreleased/add-remote-item-fix-spaceID.md
new file mode 100644
index 00000000000..3af08384b1a
--- /dev/null
+++ b/changelog/unreleased/add-remote-item-fix-spaceID.md
@@ -0,0 +1,5 @@
+Change: Add remote item to mountpoint and fix spaceID
+
+A mountpoint represents the mounted share on the share receivers side. The original resource is located where the grant has been set. This item is now shown as libregraph remoteItem on the mountpoint. While adding this, we fixed the spaceID for mountpoints.
+
+https://github.com/owncloud/ocis/pull/3365
diff --git a/go.mod b/go.mod
index cf943b3e041..fc233af889d 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
 	github.com/blevesearch/bleve/v2 v2.3.2
 	github.com/coreos/go-oidc/v3 v3.1.0
 	github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19
-	github.com/cs3org/reva/v2 v2.0.0-20220328125240-96279f215b6e
+	github.com/cs3org/reva/v2 v2.0.0-20220329061810-7810180b5c04
 	github.com/disintegration/imaging v1.6.2
 	github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733
 	github.com/go-chi/chi/v5 v5.0.7
diff --git a/go.sum b/go.sum
index 58b379583d0..6a5f54743a2 100644
--- a/go.sum
+++ b/go.sum
@@ -337,12 +337,8 @@ github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD9
 github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ=
 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
-github.com/cs3org/reva/v2 v2.0.0-20220324071614-82800d7ef768 h1:9QNIi4oyHyv1ua8oPyeBdLcMU6hKDyNmGuSxWmf01BM=
-github.com/cs3org/reva/v2 v2.0.0-20220324071614-82800d7ef768/go.mod h1:kFqm3iwrRHyEnP606H+wSWmJzjk0nj2kPShsowriqxg=
-github.com/cs3org/reva/v2 v2.0.0-20220328094822-506516e945eb h1:cAj77j0jVtZlrTUue8pT/wFDKrt0oEppLHg+0QkD6gQ=
-github.com/cs3org/reva/v2 v2.0.0-20220328094822-506516e945eb/go.mod h1:kFqm3iwrRHyEnP606H+wSWmJzjk0nj2kPShsowriqxg=
-github.com/cs3org/reva/v2 v2.0.0-20220328125240-96279f215b6e h1:ciwo9RflVAQmgkIhhtuwJdfSKIrqg9fdj/lWJ53fm/k=
-github.com/cs3org/reva/v2 v2.0.0-20220328125240-96279f215b6e/go.mod h1:kFqm3iwrRHyEnP606H+wSWmJzjk0nj2kPShsowriqxg=
+github.com/cs3org/reva/v2 v2.0.0-20220329061810-7810180b5c04 h1:5SVtdnihJ9zFBLPpD98XlXPVkotWAgBpXz7F/+CN7Jg=
+github.com/cs3org/reva/v2 v2.0.0-20220329061810-7810180b5c04/go.mod h1:kFqm3iwrRHyEnP606H+wSWmJzjk0nj2kPShsowriqxg=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
 github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
@@ -992,6 +988,8 @@ github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZy
 github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE=
 github.com/mennanov/fieldmask-utils v0.5.0 h1:8em4akN0NM3hmmrg8VbvOPfdS4SSBdbFd53m9VtfOg0=
 github.com/mennanov/fieldmask-utils v0.5.0/go.mod h1:lah2lHczE2ff+7SqnNKpB+YzaO7M3h5iNO4LgPTJheM=
+github.com/micbar/reva/v2 v2.0.0-20220325152342-12eabed07d4b h1:5oWofosj7SRMGSjGdMgaIc4ASyYtvct2XZH6Hfyeh2A=
+github.com/micbar/reva/v2 v2.0.0-20220325152342-12eabed07d4b/go.mod h1:kFqm3iwrRHyEnP606H+wSWmJzjk0nj2kPShsowriqxg=
 github.com/micbar/xattr v0.4.6-0.20220215112335-88e74d648fb7 h1:M0R40eUlyqxMuZn3Knx4DJTwHE3TiPFzcWUA/BKtDMM=
 github.com/micbar/xattr v0.4.6-0.20220215112335-88e74d648fb7/go.mod h1:sBD3RAqlr8Q+RC3FutZcikpT8nyDrIEEBw2J744gVWs=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
diff --git a/graph/pkg/service/v0/driveitems.go b/graph/pkg/service/v0/driveitems.go
index a5eb21a65f9..6f72fe7b4cd 100644
--- a/graph/pkg/service/v0/driveitems.go
+++ b/graph/pkg/service/v0/driveitems.go
@@ -2,6 +2,7 @@ package svc
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -92,6 +93,30 @@ func (g Graph) getDriveItem(ctx context.Context, root *storageprovider.ResourceI
 	return cs3ResourceToDriveItem(res.Info)
 }
 
+func (g Graph) getRemoteItem(ctx context.Context, root *storageprovider.ResourceId, baseURL *url.URL) (*libregraph.RemoteItem, error) {
+	client := g.GetGatewayClient()
+
+	ref := &storageprovider.Reference{
+		ResourceId: root,
+	}
+	res, err := client.Stat(ctx, &storageprovider.StatRequest{Ref: ref})
+	if err != nil {
+		return nil, err
+	}
+	if res.Status.Code != cs3rpc.Code_CODE_OK {
+		// Only log this, there could be mountpoints which have no grant
+		g.logger.Debug().Msg(res.Status.Message)
+		return nil, errors.New("could not fetch grant resource for the mountpoint")
+	}
+	item, err := cs3ResourceToRemoteItem(res.Info)
+	if err != nil {
+		return nil, err
+	}
+
+	item.WebDavUrl = libregraph.PtrString(baseURL.String() + resourceid.OwnCloudResourceIDWrap(root))
+	return item, nil
+}
+
 func formatDriveItems(mds []*storageprovider.ResourceInfo) ([]*libregraph.DriveItem, error) {
 	responses := make([]*libregraph.DriveItem, 0, len(mds))
 	for i := range mds {
@@ -140,7 +165,38 @@ func cs3ResourceToDriveItem(res *storageprovider.ResourceInfo) (*libregraph.Driv
 	return driveItem, nil
 }
 
-func (g Graph) getPathForDriveItem(ctx context.Context, ID *storageprovider.ResourceId) (*string, error) {
+func cs3ResourceToRemoteItem(res *storageprovider.ResourceInfo) (*libregraph.RemoteItem, error) {
+	size := new(int64)
+	*size = int64(res.Size) // TODO lurking overflow: make size of libregraph drive item use uint64
+
+	remoteItem := &libregraph.RemoteItem{
+		Id:   libregraph.PtrString(resourceid.OwnCloudResourceIDWrap(res.Id)),
+		Size: size,
+	}
+
+	if name := path.Base(res.Path); name != "" {
+		remoteItem.Name = &name
+	}
+	if res.Etag != "" {
+		remoteItem.ETag = &res.Etag
+	}
+	if res.Mtime != nil {
+		lastModified := cs3TimestampToTime(res.Mtime)
+		remoteItem.LastModifiedDateTime = &lastModified
+	}
+	if res.Type == storageprovider.ResourceType_RESOURCE_TYPE_FILE && res.MimeType != "" {
+		// We cannot use a libregraph.File here because the openapi codegenerator autodetects 'File' as a go type ...
+		remoteItem.File = &libregraph.OpenGraphFile{
+			MimeType: &res.MimeType,
+		}
+	}
+	if res.Type == storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER {
+		remoteItem.Folder = &libregraph.Folder{}
+	}
+	return remoteItem, nil
+}
+
+func (g Graph) getPathForResource(ctx context.Context, ID *storageprovider.ResourceId) (*string, error) {
 	client := g.GetGatewayClient()
 	var path *string
 	res, err := client.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: ID})
@@ -185,13 +241,13 @@ func (g Graph) getSpecialDriveItem(ctx context.Context, ID *storageprovider.Reso
 		g.logger.Error().Err(err).Str("ID", ID.OpaqueId).Msg("Could not get readme Item")
 		return nil
 	}
-	itemPath, err := g.getPathForDriveItem(ctx, ID)
+	itemPath, err := g.getPathForResource(ctx, ID)
 	if err != nil {
 		g.logger.Error().Err(err).Str("ID", ID.OpaqueId).Msg("Could not get readme path")
 		return nil
 	}
 	spaceItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(itemName)}
-	spaceItem.WebDavUrl = libregraph.PtrString(baseURL.String() + path.Join(space.Root.OpaqueId, *itemPath))
+	spaceItem.WebDavUrl = libregraph.PtrString(baseURL.String() + path.Join(space.Id.String(), *itemPath))
 
 	return spaceItem
 }
diff --git a/graph/pkg/service/v0/drives.go b/graph/pkg/service/v0/drives.go
index 63e7e47216e..c2abdc43679 100644
--- a/graph/pkg/service/v0/drives.go
+++ b/graph/pkg/service/v0/drives.go
@@ -240,7 +240,7 @@ func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	newDrive, err := g.cs3StorageSpaceToDrive(wdu, resp.StorageSpace)
+	newDrive, err := g.cs3StorageSpaceToDrive(r.Context(), wdu, resp.StorageSpace)
 	if err != nil {
 		g.logger.Error().Err(err).Msg("error parsing space")
 		errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
@@ -382,7 +382,7 @@ func (g Graph) UpdateDrive(w http.ResponseWriter, r *http.Request) {
 func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces []*storageprovider.StorageSpace) ([]*libregraph.Drive, error) {
 	responses := make([]*libregraph.Drive, 0, len(storageSpaces))
 	for _, storageSpace := range storageSpaces {
-		res, err := g.cs3StorageSpaceToDrive(baseURL, storageSpace)
+		res, err := g.cs3StorageSpaceToDrive(ctx, baseURL, storageSpace)
 		if err != nil {
 			return nil, err
 		}
@@ -429,7 +429,7 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
 	return res, err
 }
 
-func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
+func (g Graph) cs3StorageSpaceToDrive(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {
 	if space.Root == nil {
 		return nil, fmt.Errorf("space has no root")
 	}
@@ -491,8 +491,12 @@ func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.S
 		}
 	}
 
+	spaceID := space.Root.StorageId
+	if space.Root.OpaqueId != space.Root.StorageId {
+		spaceID = rootID
+	}
 	drive := &libregraph.Drive{
-		Id:   &space.Root.StorageId,
+		Id:   &spaceID,
 		Name: &space.Name,
 		//"createdDateTime": "string (timestamp)", // TODO read from StorageSpace ... needs Opaque for now
 		//"description": "string", // TODO read from StorageSpace ... needs Opaque for now
@@ -502,6 +506,24 @@ func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.S
 			Permissions: permissions,
 		},
 	}
+	if space.SpaceType == "mountpoint" {
+		var remoteItem *libregraph.RemoteItem
+		grantID := storageprovider.ResourceId{
+			StorageId: utils.ReadPlainFromOpaque(space.Opaque, "grantStorageID"),
+			OpaqueId:  utils.ReadPlainFromOpaque(space.Opaque, "grantOpaqueID"),
+		}
+		if grantID.StorageId != "" && grantID.OpaqueId != "" {
+			var err error
+			remoteItem, err = g.getRemoteItem(ctx, &grantID, baseURL)
+			if err != nil {
+				g.logger.Debug().Err(err).Msg(err.Error())
+			}
+		}
+		if remoteItem != nil {
+			drive.Root.RemoteItem = remoteItem
+		}
+	}
+
 	if space.Opaque != nil {
 		if description, ok := space.Opaque.Map["description"]; ok {
 			drive.Description = libregraph.PtrString(string(description.Value))
@@ -526,7 +548,7 @@ func (g Graph) cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.S
 		// TODO read from StorageSpace ... needs Opaque for now
 		// TODO how do we build the url?
 		// for now: read from request
-		webDavURL := baseURL.String() + space.Root.StorageId
+		webDavURL := baseURL.String() + spaceID
 		drive.Root.WebDavUrl = &webDavURL
 	}
 
diff --git a/web/pkg/config/defaults/defaultconfig.go b/web/pkg/config/defaults/defaultconfig.go
index 8e921bbaad6..89559525a08 100644
--- a/web/pkg/config/defaults/defaultconfig.go
+++ b/web/pkg/config/defaults/defaultconfig.go
@@ -50,7 +50,7 @@ func DefaultConfig() *config.Config {
 					ResponseType: "code",
 					Scope:        "openid profile email",
 				},
-				Apps: []string{"files", "search", "media-viewer", "external"},
+				Apps: []string{"files", "search", "media-viewer", "pdf-viewer", "external"},
 			},
 		},
 	}


Test patch:
diff --git a/graph/pkg/service/v0/graph_test.go b/graph/pkg/service/v0/graph_test.go
index 30c1160772d..bd07a5cde8a 100644
--- a/graph/pkg/service/v0/graph_test.go
+++ b/graph/pkg/service/v0/graph_test.go
@@ -7,6 +7,7 @@ import (
 	"io"
 	"net/http"
 	"net/http/httptest"
+	"time"
 
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
 	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -65,11 +66,11 @@ var _ = Describe("Graph", func() {
 				Status: status.NewOK(ctx),
 				StorageSpaces: []*provider.StorageSpace{
 					{
-						Id:        &provider.StorageSpaceId{OpaqueId: "aspaceid"},
+						Id:        &provider.StorageSpaceId{OpaqueId: "sameID"},
 						SpaceType: "aspacetype",
 						Root: &provider.ResourceId{
-							StorageId: "aspaceid",
-							OpaqueId:  "anopaqueid",
+							StorageId: "sameID",
+							OpaqueId:  "sameID",
 						},
 						Name: "aspacename",
 					},
@@ -94,11 +95,11 @@ var _ = Describe("Graph", func() {
 				"value":[
 					{
 						"driveType":"aspacetype",
-						"id":"aspaceid",
+						"id":"sameID",
 						"name":"aspacename",
 						"root":{
-							"id":"aspaceid!anopaqueid",
-							"webDavUrl":"https://localhost:9200/dav/spaces/aspaceid"
+							"id":"sameID!sameID",
+							"webDavUrl":"https://localhost:9200/dav/spaces/sameID"
 						}
 					}
 				]
@@ -110,11 +111,11 @@ var _ = Describe("Graph", func() {
 				Status: status.NewOK(ctx),
 				StorageSpaces: []*provider.StorageSpace{
 					{
-						Id:        &provider.StorageSpaceId{OpaqueId: "bspaceid"},
+						Id:        &provider.StorageSpaceId{OpaqueId: "bsameID"},
 						SpaceType: "bspacetype",
 						Root: &provider.ResourceId{
-							StorageId: "bspaceid",
-							OpaqueId:  "bopaqueid",
+							StorageId: "bsameID",
+							OpaqueId:  "bsameID",
 						},
 						Name: "bspacename",
 						Opaque: &typesv1beta1.Opaque{
@@ -125,11 +126,11 @@ var _ = Describe("Graph", func() {
 						},
 					},
 					{
-						Id:        &provider.StorageSpaceId{OpaqueId: "aspaceid"},
+						Id:        &provider.StorageSpaceId{OpaqueId: "asameID"},
 						SpaceType: "aspacetype",
 						Root: &provider.ResourceId{
-							StorageId: "aspaceid",
-							OpaqueId:  "anopaqueid",
+							StorageId: "asameID",
+							OpaqueId:  "asameID",
 						},
 						Name: "aspacename",
 						Opaque: &typesv1beta1.Opaque{
@@ -161,29 +162,95 @@ var _ = Describe("Graph", func() {
 					{
 						"driveAlias":"aspacetype/aspacename",
 						"driveType":"aspacetype",
-						"id":"aspaceid",
+						"id":"asameID",
 						"name":"aspacename",
 						"root":{
 							"eTag":"101112131415",
-							"id":"aspaceid!anopaqueid",
-							"webDavUrl":"https://localhost:9200/dav/spaces/aspaceid"
+							"id":"asameID!asameID",
+							"webDavUrl":"https://localhost:9200/dav/spaces/asameID"
 						}
 					},
 					{
 						"driveAlias":"bspacetype/bspacename",
 						"driveType":"bspacetype",
-						"id":"bspaceid",
+						"id":"bsameID",
 						"name":"bspacename",
 						"root":{
 							"eTag":"123456789",
-							"id":"bspaceid!bopaqueid",
-							"webDavUrl":"https://localhost:9200/dav/spaces/bspaceid"
+							"id":"bsameID!bsameID",
+							"webDavUrl":"https://localhost:9200/dav/spaces/bsameID"
 						}
 					}
 				]
 			}
 			`))
 		})
+		It("can list a spaces type mountpoint", func() {
+			gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
+				Status: status.NewOK(ctx),
+				StorageSpaces: []*provider.StorageSpace{
+					{
+						Id:        &provider.StorageSpaceId{OpaqueId: "aID!differentID"},
+						SpaceType: "mountpoint",
+						Root: &provider.ResourceId{
+							StorageId: "aID",
+							OpaqueId:  "differentID",
+						},
+						Name: "New Folder",
+						Opaque: &typesv1beta1.Opaque{
+							Map: map[string]*typesv1beta1.OpaqueEntry{
+								"spaceAlias":     {Decoder: "plain", Value: []byte("mountpoint/new-folder")},
+								"etag":           {Decoder: "plain", Value: []byte("101112131415")},
+								"grantStorageID": {Decoder: "plain", Value: []byte("ownerStorageID")},
+								"grantOpaqueID":  {Decoder: "plain", Value: []byte("opaqueID")},
+							},
+						},
+					},
+				},
+			}, nil)
+			gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(&provider.StatResponse{
+				Status: status.NewOK(ctx),
+				Info: &provider.ResourceInfo{
+					Etag:  "123456789",
+					Type:  provider.ResourceType_RESOURCE_TYPE_CONTAINER,
+					Id:    &provider.ResourceId{StorageId: "ownerStorageID", OpaqueId: "opaqueID"},
+					Path:  "New Folder",
+					Mtime: &typesv1beta1.Timestamp{Seconds: 1648327606, Nanos: 0},
+					Size:  uint64(1234),
+				},
+			}, nil)
+			gatewayClient.On("GetQuota", mock.Anything, mock.Anything).Return(&provider.GetQuotaResponse{
+				Status: status.NewUnimplemented(ctx, fmt.Errorf("not supported"), "not supported"),
+			}, nil)
+
+			r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/drives", nil)
+			rr := httptest.NewRecorder()
+			svc.GetDrives(rr, r)
+
+			Expect(rr.Code).To(Equal(http.StatusOK))
+
+			body, _ := io.ReadAll(rr.Body)
+
+			var response map[string][]libregraph.Drive
+			err := json.Unmarshal(body, &response)
+			Expect(err).ToNot(HaveOccurred())
+			Expect(len(response["value"])).To(Equal(1))
+			value := response["value"][0]
+			Expect(*value.DriveAlias).To(Equal("mountpoint/new-folder"))
+			Expect(*value.DriveType).To(Equal("mountpoint"))
+			Expect(*value.Id).To(Equal("aID!differentID"))
+			Expect(*value.Name).To(Equal("New Folder"))
+			Expect(*value.Root.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/aID!differentID"))
+			Expect(*value.Root.ETag).To(Equal("101112131415"))
+			Expect(*value.Root.Id).To(Equal("aID!differentID"))
+			Expect(*value.Root.RemoteItem.ETag).To(Equal("123456789"))
+			Expect(*value.Root.RemoteItem.Id).To(Equal("ownerStorageID!opaqueID"))
+			Expect(value.Root.RemoteItem.LastModifiedDateTime.UTC()).To(Equal(time.Unix(1648327606, 0).UTC()))
+			Expect(*value.Root.RemoteItem.Folder).To(Equal(libregraph.Folder{}))
+			Expect(*value.Root.RemoteItem.Name).To(Equal("New Folder"))
+			Expect(*value.Root.RemoteItem.Size).To(Equal(int64(1234)))
+			Expect(*value.Root.RemoteItem.WebDavUrl).To(Equal("https://localhost:9200/dav/spaces/ownerStorageID!opaqueID"))
+		})
 		It("can not list spaces with wrong sort parameter", func() {
 			gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
 				Status:        status.NewOK(ctx),
diff --git a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
index b0abde88428..269ce9e1b5d 100644
--- a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
@@ -63,8 +63,8 @@ Other free text and markdown formatting can be used elsewhere in the document if
 - [webUISharingInternalUsersCollaborator/shareWithUsers.feature:35](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersCollaborator/shareWithUsers.feature#L35)
 - [webUISharingInternalUsersCollaborator/shareWithUsers.feature:36](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersCollaborator/shareWithUsers.feature#L36)
 - [webUISharingInternalUsersCollaborator/shareWithUsers.feature:37](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersCollaborator/shareWithUsers.feature#L37)
-- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:156](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L156)
-- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:199](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L199)
+- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:155](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L155)
+- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:198](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L198)
 - [webUISharingPermissionsUsers/sharePermissionsUsers.feature:21](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPermissionsUsers/sharePermissionsUsers.feature#L21)
 - [webUISharingPermissionsUsers/sharePermissionsUsers.feature:36](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPermissionsUsers/sharePermissionsUsers.feature#L36)
 - [webUISharingPermissionsUsers/sharePermissionsUsers.feature:52](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPermissionsUsers/sharePermissionsUsers.feature#L52)
@@ -199,7 +199,7 @@ Other free text and markdown formatting can be used elsewhere in the document if
 - [webUIFilesActionMenu/versions.feature:93](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesActionMenu/versions.feature#L93)
 
 ### [Accepting different shares with same filename from different users overwrites one file](https://github.com/owncloud/ocis/issues/713)
-- [webUISharingAcceptShares/acceptShares.feature:228](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L228)
+- [webUISharingAcceptShares/acceptShares.feature:225](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L225)
 
 ### [Deletion of a selected user/group as a collaborator has unusual behavior in UI](https://github.com/owncloud/web/issues/5857)
 - [webUISharingFolderAdvancedPermissionsGroups/shareAdvancePermissionsGroup.feature:63](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingFolderAdvancedPermissionsGroups/shareAdvancePermissionsGroup.feature#L63)
@@ -359,7 +359,7 @@ Other free text and markdown formatting can be used elsewhere in the document if
 - [webUITrashbinDelete/trashbinDelete.feature:48](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUITrashbinDelete/trashbinDelete.feature#L48)
 
 ### [Tags page not implemented yet](https://github.com/owncloud/web/issues/5017)
-- [webUIDeleteFilesFolders/deleteFilesFolders.feature:145](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIDeleteFilesFolders/deleteFilesFolders.feature#L145)
+- [webUIDeleteFilesFolders/deleteFilesFolders.feature:136](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIDeleteFilesFolders/deleteFilesFolders.feature#L136)
 - [webUIFilesSearch/search.feature:63](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesSearch/search.feature#L63)
 - [webUIFilesSearch/search.feature:71](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesSearch/search.feature#L71)
 - [webUIFilesSearch/search.feature:84](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesSearch/search.feature#L84)
@@ -484,8 +484,8 @@ Other free text and markdown formatting can be used elsewhere in the document if
 
 ### [[oCIS] Received share cannot be deleted/unshared if not shared with full permissions](https://github.com/owncloud/web/issues/5531)
 - [webUISharingAcceptShares/acceptShares.feature:50](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L50)
-- [webUISharingAcceptShares/acceptShares.feature:162](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L162)
-- [webUISharingAcceptShares/acceptShares.feature:201](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L201)
+- [webUISharingAcceptShares/acceptShares.feature:159](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L159)
+- [webUISharingAcceptShares/acceptShares.feature:198](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L198)
 
 ### [not possible to overwrite a received shared file](https://github.com/owncloud/ocis/issues/2267)
 - [webUISharingInternalGroups/shareWithGroups.feature:77](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroups/shareWithGroups.feature#L77)
@@ -496,3 +496,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
 
 ### [empty subfolder inside a folder to be uploaded is not created on the server](https://github.com/owncloud/web/issues/6348)
 - [webUIUpload/upload.feature:42](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIUpload/upload.feature#L42)
+
+### Unreleased changes in web master branch
+- [webUIFilesActionMenu/fileFolderActionMenu.feature:14](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesActionMenu/fileFolderActionMenu.feature#L14)
diff --git a/tests/acceptance/features/apiSpaces/listSpaces.feature b/tests/acceptance/features/apiSpaces/listSpaces.feature
index 7c6a01f3392..392900a7ac8 100644
--- a/tests/acceptance/features/apiSpaces/listSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/listSpaces.feature
@@ -20,12 +20,6 @@ Feature: List and create spaces
       | name             | Alice Hansen |
       | quota@@@state    | normal       |
       | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
-    And the json responded should contain a space "Shares Jail" with these key and value pairs:
-      | key              | value        |
-      | driveType        | virtual     |
-      | id               | %space_id%   |
-      | name             | Shares Jail |
-      | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
 
   Scenario: An ordinary user can request information about their Space via the Graph API using a filter
     When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'personal'"
diff --git a/tests/config/drone/ocis-config.json b/tests/config/drone/ocis-config.json
index de2ead136c9..eefe2050a5a 100644
--- a/tests/config/drone/ocis-config.json
+++ b/tests/config/drone/ocis-config.json
@@ -17,6 +17,7 @@
     "draw-io",
     "markdown-editor",
     "media-viewer",
+    "pdf-viewer",
     "search"
   ],
   "external_apps": [