diff --git a/changelog/unreleased/sm-newjson.md b/changelog/unreleased/sm-newjson.md new file mode 100644 index 0000000000..e13d415bd0 --- /dev/null +++ b/changelog/unreleased/sm-newjson.md @@ -0,0 +1,5 @@ +Enhancement: reworked protocol with ScienceMesh NC/OC apps + +This ensures full OCM 1.1 coverage + +https://github.com/cs3org/reva/pull/4240 diff --git a/pkg/ocm/share/repository/nextcloud/nextcloud.go b/pkg/ocm/share/repository/nextcloud/nextcloud.go index 27e70e71b2..fcd66e8be2 100644 --- a/pkg/ocm/share/repository/nextcloud/nextcloud.go +++ b/pkg/ocm/share/repository/nextcloud/nextcloud.go @@ -73,35 +73,51 @@ type Action struct { argS string } -// GranteeAltMap is an alternative map to JSON-unmarshal a Grantee +// EfssGrantee is a helper struct to JSON-unmarshal a Grantee // Grantees are hard to unmarshal, so unmarshalling into a map[string]interface{} first, // see also https://github.com/pondersource/sciencemesh-nextcloud/issues/27 -type GranteeAltMap struct { +type EfssGrantee struct { ID *provider.Grantee_UserId `json:"id"` } -// ShareAltMap is an alternative map to JSON-unmarshal a Share. -type ShareAltMap struct { - ID *ocm.ShareId `json:"id"` +// EfssShare is a representation of a federated share as exchanged with the EFSS. It includes +// all needed fields to represent a received federated share as well, see below. +type EfssShare struct { + ID *ocm.ShareId `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + Token string `json:"token"` ResourceID struct { - OpaqueID string `json:"opaque_id"` - } `json:"resource_id"` - RemoteShareID string `json:"remote_share_id"` - Permissions int `json:"permissions"` - Grantee struct { - ID *userpb.UserId `json:"id"` - } `json:"grantee"` - Owner *userpb.User `json:"owner"` - Creator *userpb.User `json:"creator"` - Ctime *typespb.Timestamp `json:"ctime"` - Mtime *typespb.Timestamp `json:"mtime"` - Token string `json:"token"` + OpaqueID string `json:"opaque_id" validate:"required"` + } `json:"resource_id" validate:"required"` + ResourceType string `json:"resource_type" validate:"omitempty"` + RemoteShareID string `json:"remote_share_id" validate:"required"` + Protocols struct { + WebDAV struct { + URI string `json:"uri"` + Permissions int `json:"permissions" validate:"required"` + } `json:"webdav" validate:"required"` + WebApp struct { + URITemplate string `json:"uri_template"` + ViewMode string `json:"view_mode"` + } `json:"webapp" validate:"omitempty"` + DataTx struct { + SourceURI string `json:"source_uri"` + Size int `json:"size"` + } `json:"transfer" validate:"omitempty"` + } `json:"protocols" validate:"required"` + Grantee struct { + ID *userpb.UserId `json:"id" validate:"required"` + } `json:"grantee" validate:"required"` + Owner *userpb.User `json:"owner" validate:"required"` + Creator *userpb.User `json:"creator" validate:"required"` + Ctime *typespb.Timestamp `json:"ctime" validate:"required"` + Mtime *typespb.Timestamp `json:"mtime" validate:"required"` } -// ReceivedShareAltMap is an alternative map to JSON-unmarshal a ReceivedShare. -type ReceivedShareAltMap struct { - Share *ShareAltMap `json:"share"` - State ocm.ShareState `json:"state"` +// ReceivedEfssShare is a representation of a received federated share as exchanged with the EFSS. +type ReceivedEfssShare struct { + Share *EfssShare `json:"share" validate:"required"` + State ocm.ShareState `json:"state" validate:"required"` } // New returns a share manager implementation that verifies against a Nextcloud backend. @@ -161,20 +177,36 @@ func (sm *Manager) StoreShare(ctx context.Context, share *ocm.Share) (*ocm.Share return share, nil } -func (sm *Manager) efssShareToOcm(resp *ShareAltMap) *ocm.Share { +func (sm *Manager) efssShareToOcm(resp *EfssShare) *ocm.Share { // Parse the JSON struct returned by the PHP SM app into an OCM share object + + // first generate the map of access methods, assuming WebDAV is always present + var am = make([]*ocm.AccessMethod, 0, 3) + am = append(am, share.NewWebDavAccessMethod(conversions.RoleFromOCSPermissions( + conversions.Permissions(resp.Protocols.WebDAV.Permissions)).CS3ResourcePermissions())) + if resp.Protocols.WebApp.ViewMode != "" { + am = append(am, share.NewWebappAccessMethod(utils.GetAppViewMode(resp.Protocols.WebApp.ViewMode))) + } + if resp.Protocols.DataTx.SourceURI != "" { + am = append(am, share.NewTransferAccessMethod()) + } + + // return the OCM Share payload return &ocm.Share{ Id: resp.ID, ResourceId: &provider.ResourceId{ OpaqueId: resp.ResourceID.OpaqueID, StorageId: sm.mountID, }, - Name: "", // FIXME missing from SM app + Name: resp.Name, Token: resp.Token, Grantee: &provider.Grantee{ Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ - UserId: resp.Grantee.ID, + UserId: &userpb.UserId{ + OpaqueId: resp.Grantee.ID.OpaqueId, + Idp: resp.Grantee.ID.Idp, + }, }, }, Owner: &userpb.UserId{ @@ -185,19 +217,10 @@ func (sm *Manager) efssShareToOcm(resp *ShareAltMap) *ocm.Share { OpaqueId: resp.Creator.Id.OpaqueId, Idp: resp.Creator.Id.Idp, }, - Ctime: resp.Ctime, - Mtime: resp.Mtime, - ShareType: ocm.ShareType_SHARE_TYPE_USER, - // FIXME the SM app does not provide methods and does not include permissions, see https://github.com/sciencemesh/nc-sciencemesh/issues/45 - // the correct logic here is to include those access methods that come in the payload - AccessMethods: []*ocm.AccessMethod{ - // FIXME for webdav we should use conversions.RoleFromOCSPermissions(conversions.Permissions(resp.Permissions))).CS3ResourcePermissions() - share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), - // FIXME add if apps are supported - // share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_WRITE), - // FIXME add if datatx are supported - // share.NewTransferAccessMethod(), - }, + Ctime: resp.Ctime, + Mtime: resp.Mtime, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + AccessMethods: am, } } @@ -212,11 +235,11 @@ func (sm *Manager) GetShare(ctx context.Context, user *userpb.User, ref *ocm.Sha return nil, err } - altResult := ShareAltMap{} - if err := json.Unmarshal(body, &altResult); err != nil { + resp := EfssShare{} + if err := json.Unmarshal(body, &resp); err != nil { return nil, err } - return sm.efssShareToOcm(&altResult), nil + return sm.efssShareToOcm(&resp), nil } // DeleteShare deletes the share pointed by ref. @@ -249,11 +272,11 @@ func (sm *Manager) UpdateShare(ctx context.Context, user *userpb.User, ref *ocm. return nil, err } - altResult := ShareAltMap{} - if err := json.Unmarshal(body, &altResult); err != nil { + resp := EfssShare{} + if err := json.Unmarshal(body, &resp); err != nil { return nil, err } - return sm.efssShareToOcm(&altResult), nil + return sm.efssShareToOcm(&resp), nil } // ListShares returns the shares created by the user. If md is provided is not nil, @@ -269,14 +292,14 @@ func (sm *Manager) ListShares(ctx context.Context, user *userpb.User, filters [] return nil, err } - var respArr []ShareAltMap + var respArr []EfssShare if err := json.Unmarshal(respBody, &respArr); err != nil { return nil, err } var lst = make([]*ocm.Share, 0, len(respArr)) - for _, altResult := range respArr { - lst = append(lst, sm.efssShareToOcm(&altResult)) + for _, resp := range respArr { + lst = append(lst, sm.efssShareToOcm(&resp)) } return lst, nil } @@ -298,25 +321,53 @@ func (sm *Manager) StoreReceivedShare(ctx context.Context, share *ocm.ReceivedSh return share, nil } -func efssReceivedShareToOcm(altResultShare *ReceivedShareAltMap) *ocm.ReceivedShare { +func efssReceivedShareToOcm(resp *ReceivedEfssShare) *ocm.ReceivedShare { // Parse the JSON struct returned by the PHP SM app into an OCM received share object + + // first generate the map of protocols, assuming WebDAV is always present + var proto = make([]*ocm.Protocol, 0, 3) + proto = append(proto, share.NewWebDAVProtocol(resp.Share.Protocols.WebDAV.URI, resp.Share.Token, &ocm.SharePermissions{ + Permissions: conversions.RoleFromOCSPermissions(conversions.Permissions(resp.Share.Protocols.WebDAV.Permissions)).CS3ResourcePermissions(), + })) + if resp.Share.Protocols.WebApp.ViewMode != "" { + proto = append(proto, share.NewWebappProtocol(resp.Share.Protocols.WebApp.URITemplate, utils.GetAppViewMode(resp.Share.Protocols.WebApp.ViewMode))) + } + if resp.Share.Protocols.DataTx.SourceURI != "" { + proto = append(proto, share.NewTransferProtocol(resp.Share.Protocols.DataTx.SourceURI, resp.Share.Token, uint64(resp.Share.Protocols.DataTx.Size))) + } + + // return the OCM Received Share payload + rt := provider.ResourceType_RESOURCE_TYPE_FILE + if resp.Share.ResourceType == "folder" { + rt = provider.ResourceType_RESOURCE_TYPE_CONTAINER + } return &ocm.ReceivedShare{ - Id: altResultShare.Share.ID, - Name: "", // FIXME missing on SM app - RemoteShareId: altResultShare.Share.RemoteShareID, // sic, see https://github.com/cs3org/reva/pull/3852#discussion_r1189681465 + Id: resp.Share.ID, + Name: resp.Share.Name, + RemoteShareId: resp.Share.RemoteShareID, // sic, see https://github.com/cs3org/reva/pull/3852#discussion_r1189681465 Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ - UserId: altResultShare.Share.Grantee.ID, + UserId: &userpb.UserId{ + OpaqueId: resp.Share.Grantee.ID.OpaqueId, + Idp: resp.Share.Grantee.ID.Idp, + }, }, }, - Owner: altResultShare.Share.Owner.Id, - Creator: altResultShare.Share.Creator.Id, - Ctime: altResultShare.Share.Ctime, - Mtime: altResultShare.Share.Mtime, - ShareType: ocm.ShareType_SHARE_TYPE_USER, - // ResourceType: provider.ResourceType_RESOURCE_TYPE_FILE or CONTAINER, missing info on SM app - // Protocols: []*ocm.Protocol{} FIXME SM app does not persist multi protocols yet - State: altResultShare.State, + Owner: &userpb.UserId{ + OpaqueId: resp.Share.Owner.Id.OpaqueId, + Idp: resp.Share.Owner.Id.Idp, + }, + Creator: &userpb.UserId{ + OpaqueId: resp.Share.Creator.Id.OpaqueId, + Idp: resp.Share.Creator.Id.Idp, + }, + Ctime: resp.Share.Ctime, + Mtime: resp.Share.Mtime, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + ResourceType: rt, + Protocols: proto, + State: resp.State, } } @@ -327,7 +378,7 @@ func (sm *Manager) ListReceivedShares(ctx context.Context, user *userpb.User) ([ return nil, err } - var respArr []ReceivedShareAltMap + var respArr []ReceivedEfssShare if err := json.Unmarshal(respBody, &respArr); err != nil { return nil, err } @@ -353,15 +404,14 @@ func (sm *Manager) GetReceivedShare(ctx context.Context, user *userpb.User, ref return nil, err } - var altResult ReceivedShareAltMap - if err := json.Unmarshal(respBody, &altResult); err != nil { + var resp ReceivedEfssShare + if err := json.Unmarshal(respBody, &resp); err != nil { return nil, err } - altResultShare := altResult.Share - if altResultShare == nil { + if resp.Share == nil { return nil, errtypes.NotFound("Received share not found from EFSS API") } - return efssReceivedShareToOcm(&altResult), nil + return efssReceivedShareToOcm(&resp), nil } // UpdateReceivedShare updates the received share with share state. @@ -385,16 +435,15 @@ func (sm *Manager) UpdateReceivedShare(ctx context.Context, user *userpb.User, s return nil, err } - var altResult ReceivedShareAltMap - err = json.Unmarshal(respBody, &altResult) + var resp ReceivedEfssShare + err = json.Unmarshal(respBody, &resp) if err != nil { return nil, err } - altResultShare := altResult.Share - if altResultShare == nil { + if resp.Share == nil { return nil, errtypes.NotFound("Received share not found from EFSS API") } - return efssReceivedShareToOcm(&altResult), nil + return efssReceivedShareToOcm(&resp), nil } func getUsername(user *userpb.User) string { diff --git a/pkg/ocm/share/repository/nextcloud/nextcloud_server_mock.go b/pkg/ocm/share/repository/nextcloud/nextcloud_server_mock.go index 0cebb4453a..432a5f4d16 100644 --- a/pkg/ocm/share/repository/nextcloud/nextcloud_server_mock.go +++ b/pkg/ocm/share/repository/nextcloud/nextcloud_server_mock.go @@ -39,29 +39,20 @@ type Response struct { const serverStateError = "ERROR" const serverStateEmpty = "EMPTY" const serverStateHome = "HOME" +const testShare = `{"id":{},"resource_id":{"opaque_id":"fileid-/some/path"},"token":"some-token","name":"test share","protocols":{"webdav":{"uri":"webdav-uri","permissions":15},"webapp":{"uri_template":"app-uri-template","view_mode":"write"},"transfer":{"source_uri":"source-uri","size":1}},"grantee":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}` var serverState = serverStateEmpty var responses = map[string]Response{ `POST /apps/sciencemesh/~tester/api/ocm/addSentShare {"resourceId":{"opaqueId":"fileid-/some/path"},"name":"Some Name","permissions":{"permissions":{"getPath":true}},"grantee":{"userId":{"idp":"0.0.0.0:19000","opaqueId":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":"USER_TYPE_PRIMARY"},"opaque":{"map":{"sharedSecret":{"decoder":"plain","value":"bGdFU1hjR0VtTg=="}}}},"owner":{"idp":"0.0.0.0:19000","opaqueId":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":"USER_TYPE_PRIMARY"},"creator":{"idp":"0.0.0.0:19000","opaqueId":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":"USER_TYPE_PRIMARY"},"shareType":"SHARE_TYPE_REGULAR"}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, `POST /apps/sciencemesh/~tester/api/ocm/addReceivedShare {"md":{"opaque_id":"fileid-/some/path"},"g":{"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"permissions":{"permissions":{"get_path":true}}},"provider_domain":"cern.ch","resource_type":"file","provider_id":2,"owner_opaque_id":"einstein","owner_display_name":"Albert Einstein","protocol":{"name":"webdav","options":{"sharedSecret":"secret","permissions":"webdav-property"}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/GetShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/Unshare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, ``, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/UpdateShare {"ref":{"Spec":{"Id":{"opaque_id":"some-share-id"}}},"p":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/ListShares [{"type":4,"Term":{"Creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}}]`: {200, `[{"id":{},"resource_id":{},"permissions":1,"grantee":{"type":1,"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"token":"some-token"}]`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/ListReceivedShares `: {200, `[{"share":{"id":{},"resource_id":{},"permissions":1,"grantee":{"type":1,"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"token":"some-token"},"state":2}]`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/GetReceivedShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"share":{"id":{},"resource_id":{},"permissions":1,"grantee":{"type":1,"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"token":"some-token"},"state":2}`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/UpdateReceivedShare {"received_share":{"id":{},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"share_type":1,"state":2},"field_mask":{"paths":["state"]}}`: {200, `{"share":{"id":{},"resource_id":{},"name":"","permissions":1,"grantee":{"type":1,"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}},"state":2}`, serverStateHome}, - `POST /apps/sciencemesh/~tester/api/ocm/GetSentShareByToken {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"id":{},"resource_id":{},"permissions":1,"grantee":{"type":1,"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"owner":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"creator":{"id":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"token":"some-token"}`, serverStateHome}, - - `POST /index.php/apps/sciencemesh/~marie/api/ocm/addReceivedShare {"md":{"opaque_id":"fileid-/some/path"},"g":{"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"permissions":{"permissions":{"get_path":true}}},"provider_domain":"cern.ch","resource_type":"file","provider_id":2,"owner_opaque_id":"einstein","owner_display_name":"Albert Einstein","protocol":{"name":"webdav","options":{"sharedSecret":"secret","permissions":"webdav-property"}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/GetShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/Unshare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, ``, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/UpdateShare {"ref":{"Spec":{"Id":{"opaque_id":"some-share-id"}}},"p":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}}}`: {200, `{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/ListShares [{"type":4,"Term":{"Creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}}]`: {200, `[{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}}]`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/ListReceivedShares `: {200, `[{"share":{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}},"state":2}]`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/GetReceivedShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"share":{"id":{},"resource_id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}},"state":2}`, serverStateHome}, - `POST /index.php/apps/sciencemesh/~marie/api/ocm/UpdateReceivedShare {"received_share":{"share":{"id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}},"state":2},"field_mask":{"paths":["state"]}}`: {200, `{"share":{"id":{},"permissions":{"permissions":{"add_grant":true,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":true,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":true,"deny_grant":true}},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890}},"state":2}`, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/Unshare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, ``, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/UpdateShare {"ref":{"Spec":{"Id":{"opaque_id":"some-share-id"}}},"p":{"permissions":{"add_grant":false,"create_container":true,"delete":true,"get_path":true,"get_quota":true,"initiate_file_download":true,"initiate_file_upload":true,"list_grants":true,"list_container":true,"list_file_versions":true,"list_recycle":true,"move":true,"remove_grant":false,"purge_recycle":true,"restore_file_version":true,"restore_recycle_item":true,"stat":true,"update_grant":false,"deny_grant":false}}}`: {200, testShare, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/ListShares [{"type":4,"Term":{"Creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}}]`: {200, `[` + testShare + `]`, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/ListReceivedShares `: {200, `[{"share":` + testShare + `,"state":2}]`, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/GetReceivedShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, `{"share":` + testShare + `,"state":2}`, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/UpdateReceivedShare {"received_share":{"id":{},"name":"test share","grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"share_type":1,"state":2},"field_mask":{"paths":["state"]}}`: {200, `{"share":` + testShare + `,"state":2,"resource_type":1}`, serverStateHome}, + `POST /apps/sciencemesh/~tester/api/ocm/GetSentShareByToken {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`: {200, testShare, serverStateHome}, } // GetNextcloudServerMock returns a handler that pretends to be a remote Nextcloud server. diff --git a/pkg/ocm/share/repository/nextcloud/nextcloud_test.go b/pkg/ocm/share/repository/nextcloud/nextcloud_test.go index b04d1067c6..9e52cbad9b 100644 --- a/pkg/ocm/share/repository/nextcloud/nextcloud_test.go +++ b/pkg/ocm/share/repository/nextcloud/nextcloud_test.go @@ -22,6 +22,7 @@ import ( "context" "os" + appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -30,11 +31,12 @@ import ( "github.com/cs3org/reva/pkg/appctx" "github.com/cs3org/reva/pkg/auth/scope" - masked_share "github.com/cs3org/reva/pkg/ocm/share" + ocmshare "github.com/cs3org/reva/pkg/ocm/share" "github.com/cs3org/reva/pkg/ocm/share/repository/nextcloud" jwt "github.com/cs3org/reva/pkg/token/manager/jwt" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + gomegafmt "github.com/onsi/gomega/format" "google.golang.org/genproto/protobuf/field_mask" "google.golang.org/grpc/metadata" ) @@ -42,11 +44,13 @@ import ( func setUpNextcloudServer() (*nextcloud.Manager, *[]string, func()) { var conf *nextcloud.ShareManagerConfig + gomegafmt.MaxLength = 0 ncHost := os.Getenv("NEXTCLOUD") if len(ncHost) == 0 { conf = &nextcloud.ShareManagerConfig{ EndPoint: "http://mock.com/apps/sciencemesh/", MockHTTP: true, + MountID: "MockMount", } nc, _ := nextcloud.NewShareManager(conf) called := make([]string, 0) @@ -58,6 +62,7 @@ func setUpNextcloudServer() (*nextcloud.Manager, *[]string, func()) { conf = &nextcloud.ShareManagerConfig{ EndPoint: ncHost + "/apps/sciencemesh/", MockHTTP: false, + MountID: "MockMount", } nc, _ := nextcloud.NewShareManager(conf) return nc, nil, func() {} @@ -245,9 +250,9 @@ var _ = Describe("Nextcloud", func() { // }) // }) - // GetShare(ctx context.Context, ref *ocm.ShareReference) (*ocm.Share, error) - Describe("GetShare", func() { - It("calls the GetShare endpoint", func() { + // GetSentShareByToken(ctx context.Context, ref *ocm.ShareReference) (*ocm.Share, error) + Describe("GetSentShareByToken", func() { + It("calls the GetSentShareByToken endpoint", func() { am, called, teardown := setUpNextcloudServer() defer teardown() @@ -260,9 +265,12 @@ var _ = Describe("Nextcloud", func() { }) Expect(err).ToNot(HaveOccurred()) Expect(*share).To(Equal(ocm.Share{ - Id: &ocm.ShareId{}, - ResourceId: &provider.ResourceId{}, - Name: "", + Id: &ocm.ShareId{}, + ResourceId: &provider.ResourceId{ + OpaqueId: "fileid-/some/path", + StorageId: "MockMount", + }, + Name: "test share", Grantee: &provider.Grantee{ Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ @@ -281,9 +289,9 @@ var _ = Describe("Nextcloud", func() { OpaqueId: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c", }, AccessMethods: []*ocm.AccessMethod{ - masked_share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), - // masked_share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_WRITE), - // masked_share.NewTransferAccessMethod(), + ocmshare.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + ocmshare.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_WRITE), + ocmshare.NewTransferAccessMethod(), }, Ctime: &types.Timestamp{ Seconds: 1234567890, @@ -401,11 +409,10 @@ var _ = Describe("Nextcloud", func() { Expect(*shares[0]).To(Equal(ocm.Share{ Id: &ocm.ShareId{}, ResourceId: &provider.ResourceId{ - StorageId: "", - OpaqueId: "", - SpaceId: "", + OpaqueId: "fileid-/some/path", + StorageId: "MockMount", }, - Name: "", + Name: "test share", Grantee: &provider.Grantee{ Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ @@ -439,9 +446,9 @@ var _ = Describe("Nextcloud", func() { }, ShareType: ocm.ShareType_SHARE_TYPE_USER, AccessMethods: []*ocm.AccessMethod{ - masked_share.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), - // masked_share.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_WRITE), - // masked_share.NewTransferAccessMethod(), + ocmshare.NewWebDavAccessMethod(conversions.NewEditorRole().CS3ResourcePermissions()), + ocmshare.NewWebappAccessMethod(appprovider.ViewMode_VIEW_MODE_READ_WRITE), + ocmshare.NewTransferAccessMethod(), }, Token: "some-token", })) @@ -460,9 +467,10 @@ var _ = Describe("Nextcloud", func() { Expect(len(receivedShares)).To(Equal(1)) Expect(*receivedShares[0]).To(Equal(ocm.ReceivedShare{ Id: &ocm.ShareId{}, - Name: "", + Name: "test share", RemoteShareId: "", Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ UserId: &userpb.UserId{ Idp: "0.0.0.0:19000", @@ -492,8 +500,16 @@ var _ = Describe("Nextcloud", func() { XXX_unrecognized: nil, XXX_sizecache: 0, }, - ShareType: ocm.ShareType_SHARE_TYPE_USER, - State: ocm.ShareState_SHARE_STATE_ACCEPTED, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + ResourceType: provider.ResourceType_RESOURCE_TYPE_FILE, + Protocols: []*ocm.Protocol{ + ocmshare.NewWebDAVProtocol("webdav-uri", "some-token", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + ocmshare.NewWebappProtocol("app-uri-template", appprovider.ViewMode_VIEW_MODE_READ_WRITE), + ocmshare.NewTransferProtocol("source-uri", "some-token", 1), + }, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, })) checkCalled(called, `POST /apps/sciencemesh/~tester/api/ocm/ListReceivedShares `) }) @@ -515,9 +531,10 @@ var _ = Describe("Nextcloud", func() { Expect(err).ToNot(HaveOccurred()) Expect(*receivedShare).To(Equal(ocm.ReceivedShare{ Id: &ocm.ShareId{}, - Name: "", + Name: "test share", RemoteShareId: "", Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ UserId: &userpb.UserId{ Idp: "0.0.0.0:19000", @@ -547,8 +564,16 @@ var _ = Describe("Nextcloud", func() { XXX_unrecognized: nil, XXX_sizecache: 0, }, - ShareType: ocm.ShareType_SHARE_TYPE_USER, - State: ocm.ShareState_SHARE_STATE_ACCEPTED, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + ResourceType: provider.ResourceType_RESOURCE_TYPE_FILE, + Protocols: []*ocm.Protocol{ + ocmshare.NewWebDAVProtocol("webdav-uri", "some-token", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + ocmshare.NewWebappProtocol("app-uri-template", appprovider.ViewMode_VIEW_MODE_READ_WRITE), + ocmshare.NewTransferProtocol("source-uri", "some-token", 1), + }, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, })) checkCalled(called, `POST /apps/sciencemesh/~tester/api/ocm/GetReceivedShare {"Spec":{"Id":{"opaque_id":"some-share-id"}}}`) }) @@ -563,7 +588,7 @@ var _ = Describe("Nextcloud", func() { receivedShare, err := am.UpdateReceivedShare(ctx, user, &ocm.ReceivedShare{ Id: &ocm.ShareId{}, - Name: "", + Name: "test share", RemoteShareId: "", Grantee: &provider.Grantee{ Id: &provider.Grantee_UserId{ @@ -607,9 +632,10 @@ var _ = Describe("Nextcloud", func() { Expect(err).ToNot(HaveOccurred()) Expect(*receivedShare).To(Equal(ocm.ReceivedShare{ Id: &ocm.ShareId{}, - Name: "", + Name: "test share", RemoteShareId: "", Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, Id: &provider.Grantee_UserId{ UserId: &userpb.UserId{ Idp: "0.0.0.0:19000", @@ -639,10 +665,18 @@ var _ = Describe("Nextcloud", func() { XXX_unrecognized: nil, XXX_sizecache: 0, }, - ShareType: ocm.ShareType_SHARE_TYPE_USER, - State: ocm.ShareState_SHARE_STATE_ACCEPTED, + ShareType: ocm.ShareType_SHARE_TYPE_USER, + ResourceType: provider.ResourceType_RESOURCE_TYPE_FILE, + Protocols: []*ocm.Protocol{ + ocmshare.NewWebDAVProtocol("webdav-uri", "some-token", &ocm.SharePermissions{ + Permissions: conversions.NewEditorRole().CS3ResourcePermissions(), + }), + ocmshare.NewWebappProtocol("app-uri-template", appprovider.ViewMode_VIEW_MODE_READ_WRITE), + ocmshare.NewTransferProtocol("source-uri", "some-token", 1), + }, + State: ocm.ShareState_SHARE_STATE_ACCEPTED, })) - checkCalled(called, `POST /apps/sciencemesh/~tester/api/ocm/UpdateReceivedShare {"received_share":{"id":{},"grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"share_type":1,"state":2},"field_mask":{"paths":["state"]}}`) + checkCalled(called, `POST /apps/sciencemesh/~tester/api/ocm/UpdateReceivedShare {"received_share":{"id":{},"name":"test share","grantee":{"Id":{"UserId":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1}}},"owner":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"creator":{"idp":"0.0.0.0:19000","opaque_id":"f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c","type":1},"ctime":{"seconds":1234567890},"mtime":{"seconds":1234567890},"share_type":1,"state":2},"field_mask":{"paths":["state"]}}`) }) })