Skip to content

Commit

Permalink
enhancement: add graph beta sharedWithMe API
Browse files Browse the repository at this point in the history
  • Loading branch information
fschade committed Oct 31, 2023
1 parent cbfd894 commit ad146ff
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 1 deletion.
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-graph-beta-sharedWithMe-api
@@ -0,0 +1,7 @@
Enhancement: Add graph beta sharedWithMe API

Add graph beta api implementation for the sharedWithMe endpoint.
The implementation is a logical replication of the existing OCS API.

https://github.com/owncloud/ocis/pull/7633
https://github.com/owncloud/ocis/issues/7436
9 changes: 8 additions & 1 deletion services/graph/pkg/service/v0/service.go
Expand Up @@ -17,6 +17,8 @@ import (
ldapv3 "github.com/go-ldap/ldap/v3"
"github.com/jellydator/ttlcache/v3"
libregraph "github.com/owncloud/libre-graph-api-go"
microstore "go-micro.dev/v4/store"

ocisldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/roles"
Expand All @@ -25,7 +27,6 @@ import (
"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
"github.com/owncloud/ocis/v2/services/graph/pkg/identity/ldap"
graphm "github.com/owncloud/ocis/v2/services/graph/pkg/middleware"
microstore "go-micro.dev/v4/store"
)

const (
Expand Down Expand Up @@ -100,6 +101,8 @@ type Service interface {
UpdateDrive(w http.ResponseWriter, r *http.Request)
DeleteDrive(w http.ResponseWriter, r *http.Request)

ListSharedWithMe(w http.ResponseWriter, r *http.Request)

GetRootDriveChildren(w http.ResponseWriter, r *http.Request)
GetDriveItem(w http.ResponseWriter, r *http.Request)
GetDriveItemChildren(w http.ResponseWriter, r *http.Request)
Expand Down Expand Up @@ -199,6 +202,10 @@ func NewService(opts ...Option) (Graph, error) {

m.Route(options.Config.HTTP.Root, func(r chi.Router) {
r.Use(middleware.StripSlashes)
// fixMe, add beta group to the libre graph api
r.Route("/beta", func(r chi.Router) {
r.Get("/me/drive/sharedWithMe", svc.ListSharedWithMe)
})
r.Route("/v1.0", func(r chi.Router) {
r.Route("/extensions/org.libregraph", func(r chi.Router) {
r.Get("/tags", svc.GetTags)
Expand Down
59 changes: 59 additions & 0 deletions services/graph/pkg/service/v0/sharedwithme.go
@@ -0,0 +1,59 @@
package svc

import (
"context"
"errors"
"net/http"

rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/go-chi/render"
libregraph "github.com/owncloud/libre-graph-api-go"

"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
)

var todoErr = errors.New("todo")

// ListSharedWithMe returns a list of all driveItems shared with the user
func (g Graph) ListSharedWithMe(w http.ResponseWriter, r *http.Request) {
driveItems, err := g.sharedWithMeDriveItems(r.Context())
if err != nil {
errorcode.RenderError(w, r, err)
return
}

render.Status(r, http.StatusOK)
render.JSON(w, r, &ListResponse{Value: driveItems})
}

func (g Graph) sharedWithMeDriveItems(ctx context.Context) ([]libregraph.DriveItem, error) {
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
return nil, err
}

filters := []*collaboration.Filter{}
listReceivedSharesResponse, err := gatewayClient.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{Filters: filters})
if err != nil {
return nil, err
}

switch listReceivedSharesResponse.Status.Code {
case rpc.Code_CODE_NOT_FOUND:
return nil, todoErr
}

var driveItems []libregraph.DriveItem
for _, share := range listReceivedSharesResponse.GetShares() {
driveItem, err := g.getDriveItem(ctx, storageprovider.Reference{ResourceId: share.Share.ResourceId})
if err != nil {
continue
}

driveItems = append(driveItems, *driveItem)
}

return driveItems, nil
}
102 changes: 102 additions & 0 deletions services/graph/pkg/service/v0/sharedwithme_test.go
@@ -0,0 +1,102 @@
package svc_test

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"

collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/storagespace"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/stretchr/testify/mock"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
"google.golang.org/grpc"

"github.com/owncloud/ocis/v2/ocis-pkg/shared"
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
)

var _ = Describe("Groups", func() {
var (
svc service.Service
cfg *config.Config
gatewayClient *cs3mocks.GatewayAPIClient
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
identityBackend *identitymocks.Backend
ctx context.Context
rr *httptest.ResponseRecorder
)

BeforeEach(func() {
pool.RemoveSelector("GatewaySelector" + "com.owncloud.api.gateway")
gatewayClient = &cs3mocks.GatewayAPIClient{}
gatewaySelector = pool.GetSelector[gateway.GatewayAPIClient](
"GatewaySelector",
"com.owncloud.api.gateway",
func(cc *grpc.ClientConn) gateway.GatewayAPIClient {
return gatewayClient
},
)

identityBackend = &identitymocks.Backend{}

rr = httptest.NewRecorder()
ctx = context.Background()

cfg = defaults.FullDefaultConfig()
cfg.Identity.LDAP.CACert = "" // skip the startup checks, we don't use LDAP at all in this tests
cfg.TokenManager.JWTSecret = "loremipsum"
cfg.Commons = &shared.Commons{}
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}

svc, _ = service.NewService(
service.Config(cfg),
service.WithGatewaySelector(gatewaySelector),
service.WithIdentityBackend(identityBackend),
)
})

Describe("ListSharedWithMe", func() {
It("returns user shares", func() {
expectedDriveItem := libregraph.DriveItem{
Id: libregraph.PtrString("1$2!3"),
Name: libregraph.PtrString("any"),
Size: libregraph.PtrInt64(123),
}
resourceId, err := storagespace.ParseID(*expectedDriveItem.Id)
Expect(err).To(BeNil())

gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(&providerv1beta1.StatResponse{
Status: status.NewOK(ctx),
Info: &providerv1beta1.ResourceInfo{
Id: &resourceId,
Path: *expectedDriveItem.Name,
Size: uint64(*expectedDriveItem.Size),
},
}, nil)
gatewayClient.On("ListReceivedShares", mock.Anything, mock.Anything).Return(&collaborationv1beta1.ListReceivedSharesResponse{
Status: status.NewOK(ctx),
Shares: []*collaborationv1beta1.ReceivedShare{{Share: &collaborationv1beta1.Share{
ResourceId: &resourceId,
}}},
}, nil)
r := httptest.NewRequest(http.MethodGet, "/graph/beta/me/drive/sharedWithMe", nil)
svc.ListSharedWithMe(rr, r)

expectedBytes, err := json.Marshal(service.ListResponse{Value: []libregraph.DriveItem{expectedDriveItem}})
Expect(err).To(BeNil())
Expect(rr.Body).To(MatchJSON(expectedBytes))
})
})
})

0 comments on commit ad146ff

Please sign in to comment.