From cc5872b94730cdc20cefd642e229526e96038c17 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Tue, 2 Sep 2025 18:43:01 +0200 Subject: [PATCH 1/2] Introduced the Incoming OCM API. Fixes #150. This is a one-on-one replacement of the so-called "Core OCM" API, which is now deprecated and will be removed in a later change. --- cs3/ocm/core/v1beta1/ocm_core_api.proto | 21 +-- .../incoming/v1beta1/ocm_incoming_api.proto | 175 ++++++++++++++++++ .../v1beta1/collaboration_api.proto | 7 +- cs3/sharing/ocm/v1beta1/ocm_api.proto | 36 ++-- 4 files changed, 207 insertions(+), 32 deletions(-) create mode 100644 cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto diff --git a/cs3/ocm/core/v1beta1/ocm_core_api.proto b/cs3/ocm/core/v1beta1/ocm_core_api.proto index b55ca0a..9ace1f7 100644 --- a/cs3/ocm/core/v1beta1/ocm_core_api.proto +++ b/cs3/ocm/core/v1beta1/ocm_core_api.proto @@ -34,12 +34,13 @@ option java_package = "com.cs3.ocm.core.v1beta1"; option objc_class_prefix = "COC"; option php_namespace = "Cs3\\Ocm\\Core\\V1Beta1"; -// OCM Core API +// OCM Core API (deprecated and to be removed, use cs3/ocm/incoming/v1beta1/incoming_api.proto instead) // -// the OCM Core API is the mapping for the local system of the OCM protocol, -// including multi-protocol shares. Implementations are expected to expose -// the `/ocm` endpoints according to the OCM API, and in response to those -// endpoints implement the following API. +// This API is the mapping for the local system of the Open Cloud Mesh +// (OCM) sharing protocol. Implementations are expected to expose the `/ocm` +// endpoints according to the OCM API, and in response to those endpoints call the +// following API. Support for multi-protocol shares is included, if the remote +// sender supplies a multi-protocol share. // // The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL // NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and @@ -53,17 +54,15 @@ option php_namespace = "Cs3\\Ocm\\Core\\V1Beta1"; // Any method MAY return UNKNOWN. // Any method MAY return UNAUTHENTICATED. service OcmCoreAPI { - // Creates a new OCM share, in response to a call from remote to: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1shares/post + // Deprecated. Creates a new OCM share, in response to a call from the remote system rpc CreateOCMCoreShare(CreateOCMCoreShareRequest) returns (CreateOCMCoreShareResponse); - // Updates an OCM share, in response to a notification from the remote system to: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + // Deprecated. Updates an OCM share, in response to a notification from the remote system rpc UpdateOCMCoreShare(UpdateOCMCoreShareRequest) returns (UpdateOCMCoreShareResponse); - // Deletes an OCM share, in response to a notification from the remote system to: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + // Deprecated. Deletes an OCM share, in response to a notification from the remote system rpc DeleteOCMCoreShare(DeleteOCMCoreShareRequest) returns (DeleteOCMCoreShareResponse); } + message CreateOCMCoreShareRequest { // OPTIONAL. // Opaque information. diff --git a/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto b/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto new file mode 100644 index 0000000..c32ae63 --- /dev/null +++ b/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto @@ -0,0 +1,175 @@ +// Copyright 2018-2025 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +syntax = "proto3"; + +package cs3.ocm.incoming.v1beta1; + +import "cs3/identity/user/v1beta1/resources.proto"; +import "cs3/rpc/v1beta1/status.proto"; +import "cs3/sharing/ocm/v1beta1/resources.proto"; +import "cs3/storage/provider/v1beta1/resources.proto"; +import "cs3/types/v1beta1/types.proto"; + +option csharp_namespace = "Cs3.Ocm.Incoming.V1Beta1"; +option go_package = "incomingv1beta1"; +option java_multiple_files = true; +option java_outer_classname = "OcmIncomingApiProto"; +option java_package = "com.cs3.ocm.incoming.v1beta1"; +option objc_class_prefix = "COI"; +option php_namespace = "Cs3\\Ocm\\Incoming\\V1Beta1"; + +// OCM Incoming API +// +// The OCM Incoming API is used to persist in the local system the incoming remote +// shares that are sent via the Open Cloud Mesh (OCM) sharing protocol. +// Implementations are expected to expose the `/ocm` endpoints according to the +// OCM API, and in response to those endpoints call the following API. +// Support for multi-protocol shares is included, if the remote sender supplies +// a multi-protocol share. +// +// The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL +// NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and +// "OPTIONAL" in this document are to be interpreted as described in +// RFC 2119. +// +// The following are global requirements that apply to all methods: +// Any method MUST return CODE_OK on a succesful operation. +// Any method MAY return NOT_IMPLEMENTED. +// Any method MAY return INTERNAL. +// Any method MAY return UNKNOWN. +// Any method MAY return UNAUTHENTICATED. +service OcmIncomingAPI { + // Creates a new OCM share in response to a call from remote to `/ocm/shares`. See: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1shares/post + rpc CreateIncomingOCMShare(CreateIncomingOCMShareRequest) returns (CreateIncomingOCMShareResponse); + // Updates an OCM share in response to a notification from remote to `/ocm/notifications`. See: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + rpc UpdateIncomingOCMShare(UpdateIncomingOCMShareRequest) returns (UpdateIncomingOCMShareResponse); + // Deletes an OCM share in response to a notification from remote to `/ocm/notifications`. See: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + rpc DeleteIncomingOCMShare(DeleteIncomingOCMShareRequest) returns (DeleteIncomingOCMShareResponse); +} + +message CreateIncomingOCMShareRequest { + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 1; + // OPTIONAL. + // Description for the share. + string description = 2; + // REQUIRED. + // Name of the resource (file or folder). + string name = 3; + // REQUIRED. + // Identifier to identify the resource at the provider side. This is unique per provider. + string resource_id = 4; + // REQUIRED. + // Provider specific identifier of the owner of the resource. + cs3.identity.user.v1beta1.UserId owner = 5; + // REQUIRED. + // Provider specific identifier of the user that wants to share the resource. + cs3.identity.user.v1beta1.UserId sender = 6; + // REQUIRED. + // Consumer specific identifier of the user or group the provider wants to share the resource with. + // This is known in advance, for example using the OCM invitation flow. + // Please note that the consumer service endpoint is known in advance as well, so this is no part of the request body. + // TODO: this field needs to represent either a user or group in the future, not only a user. + cs3.identity.user.v1beta1.UserId share_with = 7; + // REQUIRED. + // Resource type. + cs3.storage.provider.v1beta1.ResourceType resource_type = 8; + // REQUIRED. + // Recipient share type. + cs3.sharing.ocm.v1beta1.ShareType share_type = 9; + // OPTIONAL. + // The expiration time for the OCM share. + cs3.types.v1beta1.Timestamp expiration = 10; + // REQUIRED. + // The protocols which are used to establish synchronisation, + // with their access rights. + // See also cs3/sharing/ocm/v1beta1/resources.proto for how to map + // this to the OCM share payload. + repeated cs3.sharing.ocm.v1beta1.Protocol protocols = 11; + // OPTIONAL. + // A nonce to be exchanged for a (potentially short-lived) bearer token. + string code = 12; +} + +message CreateIncomingOCMShareResponse { + // REQUIRED. + // The response status. + cs3.rpc.v1beta1.Status status = 1; + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 2; + // REQUIRED. + // Unique ID to identify the share at the consumer side. + string id = 3; + // REQUIRED. + cs3.types.v1beta1.Timestamp created = 4; +} + +message UpdateIncomingOCMShareRequest { + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 1; + // REQUIRED. + // Unique ID to identify the share at the consumer side. + string ocm_share_id = 2; + // OPTIONAL. + // Description for the share. + string description = 3; + // OPTIONAL. + // Recipient share type. + cs3.sharing.ocm.v1beta1.ShareType share_type = 5; + // OPTIONAL. + // The expiration time for the OCM share. + cs3.types.v1beta1.Timestamp expiration = 6; + // OPTIONAL. + // The protocols which are used to establish synchronisation, + // with their access rights. + repeated cs3.sharing.ocm.v1beta1.Protocol protocols = 7; +} + +message UpdateIncomingOCMShareResponse { + // REQUIRED. + // The response status. + cs3.rpc.v1beta1.Status status = 1; + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 2; +} + +message DeleteIncomingOCMShareRequest { + // REQUIRED. + // Unique ID to identify the share at the consumer side. + string id = 1; + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 2; +} + +message DeleteIncomingOCMShareResponse { + // REQUIRED. + // The response status. + cs3.rpc.v1beta1.Status status = 1; + // OPTIONAL. + // Opaque information. + cs3.types.v1beta1.Opaque opaque = 2; +} diff --git a/cs3/sharing/collaboration/v1beta1/collaboration_api.proto b/cs3/sharing/collaboration/v1beta1/collaboration_api.proto index d47125b..a87decc 100644 --- a/cs3/sharing/collaboration/v1beta1/collaboration_api.proto +++ b/cs3/sharing/collaboration/v1beta1/collaboration_api.proto @@ -37,9 +37,10 @@ option php_namespace = "Cs3\\Sharing\\Collaboration\\V1Beta1"; // User Share Provider API // // The User Share Provider API is meant to manipulate share -// resources for a specific share type (user, group, ocm, ...) -// from the perspective of the creator or the share and -// from the perspective of the receiver of the share. +// resources for a specific share type (user or group) +// from the perspective of the creator of the share and +// from the perspective of the recipient, both known to +// the local system. See OCM for remote shares. // // The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL // NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and diff --git a/cs3/sharing/ocm/v1beta1/ocm_api.proto b/cs3/sharing/ocm/v1beta1/ocm_api.proto index fbd581f..5971e9d 100644 --- a/cs3/sharing/ocm/v1beta1/ocm_api.proto +++ b/cs3/sharing/ocm/v1beta1/ocm_api.proto @@ -36,13 +36,15 @@ option java_package = "com.cs3.sharing.ocm.v1beta1"; option objc_class_prefix = "CSO"; option php_namespace = "Cs3\\Sharing\\Ocm\\V1Beta1"; -// OCM Share Provider API +// OCM API // -// The OCM Share Provider API is meant to manipulate share -// resources from the perspective of the creator or the share and -// from the perspective of the receiver of the share. +// The OCM API is a share API meant for local users to offer local +// resources to remote recipients via the Open Cloud Mesh (OCM) protocol, +// and to manipulate shares received from remote users. +// Implementations are expected to call remote `/ocm` endpoints +// in response to the payloads received via this API. // -// The following APIs match the OCM v1.1 spec including multi-protocol shares. +// The APIs match the OCM v1.2 spec including multi-protocol shares. // // The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL // NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and @@ -56,19 +58,18 @@ option php_namespace = "Cs3\\Sharing\\Ocm\\V1Beta1"; // Any method MAY return UNKNOWN. // Any method MAY return UNAUTHENTICATED. service OcmAPI { - // Creates a new ocm share. + // Creates a new OCM share. // MUST return CODE_NOT_FOUND if the resource reference does not exist. - // MUST return CODE_ALREADY_EXISTS if the share already exists for the 4-tuple consisting of + // MUST return CODE_ALREADY_EXISTS if the share already exists for the 3-tuple consisting of // (owner, shared_resource, grantee). // New shares MUST be created in the state SHARE_STATE_PENDING, and MUST be sent - // to the remote system using the OCM API at: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.1.0&repo=OCM-API&user=cs3org#/paths/~1shares/post + // to the remote system using the `/ocm/shares` OCM API, see: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1shares/post rpc CreateOCMShare(CreateOCMShareRequest) returns (CreateOCMShareResponse); - // Removes a share. + // Removes an OCM share. // MUST return CODE_NOT_FOUND if the share reference does not exist. - // This action SHALL be notified to the remote system - // using the OCM API at: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.1.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + // This action MUST be notified to the remote system using the `/ocm/notifications` OCM API at: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post rpc RemoveOCMShare(RemoveOCMShareRequest) returns (RemoveOCMShareResponse); // Gets share information for a single share. // MUST return CODE_NOT_FOUND if the share reference does not exist. @@ -76,17 +77,16 @@ service OcmAPI { // Gets share information for a single share by its unlisted token. // MUST return CODE_NOT_FOUND if the share does not exist. rpc GetOCMShareByToken(GetOCMShareByTokenRequest) returns (GetOCMShareByTokenResponse); - // List the shares the authenticated principal has created, + // List the shares the currently authenticated user has created, // both as owner and creator. If a filter is specified, only // shares satisfying the filter MUST be returned. rpc ListOCMShares(ListOCMSharesRequest) returns (ListOCMSharesResponse); // Updates a share. // MUST return CODE_NOT_FOUND if the share reference does not exist. - // This action SHALL be notified to the remote system - // using the OCM API at: - // https://cs3org.github.io/OCM-API/docs.html?branch=v1.1.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post + // This action MUST be notified to the remote system using the `/ocm/notifications` OCM API at: + // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post rpc UpdateOCMShare(UpdateOCMShareRequest) returns (UpdateOCMShareResponse); - // List all shares the authenticated principal has received. + // List all shares the currently authenticated user has received. rpc ListReceivedOCMShares(ListReceivedOCMSharesRequest) returns (ListReceivedOCMSharesResponse); // Update the received share to change the share state or the display name. // MUST return CODE_NOT_FOUND if the share reference does not exist. From 14f405333132f01e578209c30489e103193444d7 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Wed, 10 Sep 2025 15:15:28 +0200 Subject: [PATCH 2/2] Added corresponding gateway APIs --- cs3/gateway/v1beta1/gateway_api.proto | 16 ++++++++++++---- .../incoming/v1beta1/ocm_incoming_api.proto | 18 +++++++++--------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/cs3/gateway/v1beta1/gateway_api.proto b/cs3/gateway/v1beta1/gateway_api.proto index 9a6b50e..9e80995 100644 --- a/cs3/gateway/v1beta1/gateway_api.proto +++ b/cs3/gateway/v1beta1/gateway_api.proto @@ -29,6 +29,7 @@ import "cs3/identity/group/v1beta1/group_api.proto"; import "cs3/identity/user/v1beta1/resources.proto"; import "cs3/identity/user/v1beta1/user_api.proto"; import "cs3/ocm/core/v1beta1/ocm_core_api.proto"; +import "cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto"; import "cs3/ocm/invite/v1beta1/invite_api.proto"; import "cs3/ocm/provider/v1beta1/provider_api.proto"; import "cs3/permissions/v1beta1/permissions_api.proto"; @@ -413,14 +414,21 @@ service GatewayAPI { // Get the information of all the providers registered in the mesh. rpc ListAllProviders(cs3.ocm.provider.v1beta1.ListAllProvidersRequest) returns (cs3.ocm.provider.v1beta1.ListAllProvidersResponse); // *****************************************************************/ - // **************************** OCM CORE ***************************/ + // **************************** OCM INCOMING ***********************/ // *****************************************************************/ - // Creates a new OCM share. + // Creates a new incoming OCM share. + rpc CreateOCMIncomingShare(cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareRequest) returns (cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareResponse); + // Updates an incoming OCM share. + rpc UpdateOCMIncomingShare(cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareRequest) returns (cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareResponse); + // Deletes an incoming OCM share. + rpc DeleteOCMIncomingShare(cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareRequest) returns (cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareResponse); + + // Deprecated. Creates a new OCM share. rpc CreateOCMCoreShare(cs3.ocm.core.v1beta1.CreateOCMCoreShareRequest) returns (cs3.ocm.core.v1beta1.CreateOCMCoreShareResponse); - // Updates an OCM share. + // Deprecated. Updates an OCM share. rpc UpdateOCMCoreShare(cs3.ocm.core.v1beta1.UpdateOCMCoreShareRequest) returns (cs3.ocm.core.v1beta1.UpdateOCMCoreShareResponse); - // Deletes an OCM share. + // Deprecated. Deletes an OCM share. rpc DeleteOCMCoreShare(cs3.ocm.core.v1beta1.DeleteOCMCoreShareRequest) returns (cs3.ocm.core.v1beta1.DeleteOCMCoreShareResponse); // *****************************************************************/ // ************************** FILE TRANSFER ************************/ diff --git a/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto b/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto index c32ae63..190f3e7 100644 --- a/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto +++ b/cs3/ocm/incoming/v1beta1/ocm_incoming_api.proto @@ -57,16 +57,16 @@ option php_namespace = "Cs3\\Ocm\\Incoming\\V1Beta1"; service OcmIncomingAPI { // Creates a new OCM share in response to a call from remote to `/ocm/shares`. See: // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1shares/post - rpc CreateIncomingOCMShare(CreateIncomingOCMShareRequest) returns (CreateIncomingOCMShareResponse); + rpc CreateOCMIncomingShare(CreateOCMIncomingShareRequest) returns (CreateOCMIncomingShareResponse); // Updates an OCM share in response to a notification from remote to `/ocm/notifications`. See: // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post - rpc UpdateIncomingOCMShare(UpdateIncomingOCMShareRequest) returns (UpdateIncomingOCMShareResponse); + rpc UpdateOCMIncomingShare(UpdateOCMIncomingShareRequest) returns (UpdateOCMIncomingShareResponse); // Deletes an OCM share in response to a notification from remote to `/ocm/notifications`. See: // https://cs3org.github.io/OCM-API/docs.html?branch=v1.2.0&repo=OCM-API&user=cs3org#/paths/~1notifications/post - rpc DeleteIncomingOCMShare(DeleteIncomingOCMShareRequest) returns (DeleteIncomingOCMShareResponse); + rpc DeleteOCMIncomingShare(DeleteOCMIncomingShareRequest) returns (DeleteOCMIncomingShareResponse); } -message CreateIncomingOCMShareRequest { +message CreateOCMIncomingShareRequest { // OPTIONAL. // Opaque information. cs3.types.v1beta1.Opaque opaque = 1; @@ -111,7 +111,7 @@ message CreateIncomingOCMShareRequest { string code = 12; } -message CreateIncomingOCMShareResponse { +message CreateOCMIncomingShareResponse { // REQUIRED. // The response status. cs3.rpc.v1beta1.Status status = 1; @@ -125,7 +125,7 @@ message CreateIncomingOCMShareResponse { cs3.types.v1beta1.Timestamp created = 4; } -message UpdateIncomingOCMShareRequest { +message UpdateOCMIncomingShareRequest { // OPTIONAL. // Opaque information. cs3.types.v1beta1.Opaque opaque = 1; @@ -147,7 +147,7 @@ message UpdateIncomingOCMShareRequest { repeated cs3.sharing.ocm.v1beta1.Protocol protocols = 7; } -message UpdateIncomingOCMShareResponse { +message UpdateOCMIncomingShareResponse { // REQUIRED. // The response status. cs3.rpc.v1beta1.Status status = 1; @@ -156,7 +156,7 @@ message UpdateIncomingOCMShareResponse { cs3.types.v1beta1.Opaque opaque = 2; } -message DeleteIncomingOCMShareRequest { +message DeleteOCMIncomingShareRequest { // REQUIRED. // Unique ID to identify the share at the consumer side. string id = 1; @@ -165,7 +165,7 @@ message DeleteIncomingOCMShareRequest { cs3.types.v1beta1.Opaque opaque = 2; } -message DeleteIncomingOCMShareResponse { +message DeleteOCMIncomingShareResponse { // REQUIRED. // The response status. cs3.rpc.v1beta1.Status status = 1;