Skip to content

Commit

Permalink
Merge pull request #3365 from owncloud/fix-shares-graph
Browse files Browse the repository at this point in the history
[full-ci] Fix shares graph
  • Loading branch information
micbar authored Mar 29, 2022
2 parents 4a0592d + f3e02e0 commit c523ae8
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .drone.env
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 5 additions & 0 deletions changelog/unreleased/add-remote-item-fix-spaceID.md
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down Expand Up @@ -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=
Expand Down
62 changes: 59 additions & 3 deletions graph/pkg/service/v0/driveitems.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package svc

import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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})
Expand Down Expand Up @@ -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
}
32 changes: 27 additions & 5 deletions graph/pkg/service/v0/drives.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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")
}
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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
}

Expand Down
103 changes: 85 additions & 18 deletions graph/pkg/service/v0/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
},
Expand All @@ -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"
}
}
]
Expand All @@ -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{
Expand All @@ -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{
Expand Down Expand Up @@ -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),
Expand Down
Loading

0 comments on commit c523ae8

Please sign in to comment.