diff --git a/docs/services/ocm/configuration.md b/docs/services/ocm/configuration.md new file mode 100644 index 000000000..eab0de782 --- /dev/null +++ b/docs/services/ocm/configuration.md @@ -0,0 +1,15 @@ +--- +title: Service Configuration +date: 2018-05-02T00:00:00+00:00 +weight: 20 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/services/ocm +geekdocFilePath: configuration.md +geekdocCollapseSection: true +--- + +## Example YAML Config + +{{< include file="services/_includes/ocm-config-example.yaml" language="yaml" >}} + +{{< include file="services/_includes/ocm.md" >}} diff --git a/docs/services/ocm/create_share_flow.md b/docs/services/ocm/create_share_flow.md new file mode 100644 index 000000000..6474ab0e5 --- /dev/null +++ b/docs/services/ocm/create_share_flow.md @@ -0,0 +1,65 @@ +--- +title: Create Share Flow +date: 2018-05-02T00:00:00+00:00 +weight: 40 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/services/ocm +geekdocFilePath: create_share_flow.md +geekdocCollapseSection: true +--- + +## OCM Create Share Flow + +{{< mermaid class="text-center">}} +sequenceDiagram + box Instance A + participant osp as ocmsharesprovider + participant gwa as Gateway A + participant httpa as ocs + end + actor usera as User A + box Instance B + participant httpb as ocmd + participant gwb as Gateway B + participant ocmc as OCMCore + end + + Note over usera: A shares a resource with B + usera->>+httpa: CreateShare + httpa->>+gwa: GetInfoByDomain + Note left of gwa: GetInfoByDomain
(ocmproviderauthorizer) + gwa-->>-httpa: return + + httpa->>+gwa: GetAcceptedUser + Note left of gwa: GetAcceptedUser
(ocminvitemanager) + gwa-->>-httpa: return + + httpa->>+gwa: CreateOCMShare + gwa->>+osp: CreateOCMShare + osp->>+gwa: Stat + gwa-->>-osp: return + + Note left of osp: store share in repo + + osp->>+httpb: POST /shares + httpb->>+gwb: IsProviderAllowed + Note right of gwb: IsProviderAllowed
(ocmproviderauthorizer) + gwb-->>-httpb: return + + httpb->>+gwb: GetUser + Note right of gwb: GetUser
(userprovider) + gwb-->>-httpb: return + + httpb->>+gwb: CreateOCMCoreShare + gwb->>+ocmc: CreateOCMCoreShare + Note right of ocmc: StoreReceivedShare + ocmc-->>-gwb: return + gwb-->>-httpb: return + httpb-->>-osp: return + osp-->>-gwa: return + gwa-->>-httpa: return + httpa->>+gwa: Stat + Note left of gwa: Stat
(storageprovider) + gwa-->>-httpa: return + httpa-->>-usera: return +{{< /mermaid >}} \ No newline at end of file diff --git a/docs/services/ocm/invitation_flow.md b/docs/services/ocm/invitation_flow.md new file mode 100644 index 000000000..58744c2c5 --- /dev/null +++ b/docs/services/ocm/invitation_flow.md @@ -0,0 +1,55 @@ +--- +title: Invitation flow +date: 2018-05-02T00:00:00+00:00 +weight: 30 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/services/ocm +geekdocFilePath: invitation_flow.md +geekdocCollapseSection: true +--- + +## OCM Invitation Flow + +{{< mermaid class="text-center">}} +sequenceDiagram + box Instance A + participant ima as InviteManager A + participant gwa as Gateway A + participant httpa as HTTP Api A (ocm, sm) + end + actor usera as User A + actor userb as User B + box Instance B + participant httpb as HTTP Api B (ocm, sm) + participant gwb as Gateway B + participant imb as InviteManager B + end + + Note over usera: A creates invitation token + usera->>+httpa: POST /generate-invite (sciencemesh) + httpa->>+gwa: GenerateInviteToken + gwa->>+ima: GenerateInviteToken + Note left of ima: store token in repo + ima-->>-gwa: return token + gwa-->>-httpa: return token + httpa-->>-usera: return token + + Note over usera,userb: A passes token to B + + Note over userb: B accepts invitation + userb->>+httpb: POST /accept-invite (sciencemesh) + httpb->>+gwb: ForwardInvite + gwb->>+imb: ForwardInvite + imb->>+httpa: POST /invite-accepted (ocm) + httpa->>+gwa: AcceptInvite + gwa->>+ima: AcceptInvite + Note left of ima: get token from repo + Note left of ima: add remote user + ima-->>-gwa: return + gwa-->>-httpa: return remote user + httpa->>-imb: return remote user + Note right of imb: add remote user + imb-->>-gwb: return + gwb-->>-httpb: return + httpb-->>-userb: return +{{< /mermaid >}} \ No newline at end of file diff --git a/services/ocm/README.md b/services/ocm/README.md index 434070361..30b727896 100644 --- a/services/ocm/README.md +++ b/services/ocm/README.md @@ -1,3 +1,64 @@ # OCM -The `ocm` service provides federated sharing functionality based on [sciencemesh](https://sciencemesh.io/) and [ocm](https://github.com/cs3org/OCM-API). \ No newline at end of file +The `ocm` service provides federated sharing functionality based on the [sciencemesh](https://sciencemesh.io/) and [ocm](https://github.com/cs3org/OCM-API) HTTP APIs. Internally the `ocm` service consists of the following services and endpoints: + +External HTTP APIs: +* sciencemesh: serves the API for the invitation workflow +* ocmd: serves the API for managing federated shares + +Internal GRPC APIs: +* ocmproviderauthorizer: manages the list of trusted providers and verifies requests +* ocminvitemanager: manages the list and state of invite tokens +* ocmshareprovider: manages ocm shares on the sharer +* ocmcore: used for creating federated shares on the receiver side +* authprovider: authenticates webdav requests using the ocm share tokens + +## Trust Between Instances + +The `ocm` services implements an invitation workflow which needs to be followed before creating federated shares. Invitations are limited to trusted instances, however. + +The list of trusted instances is managed by the `ocmproviderauthorizer` service. The only supported backend currently is `json` which stores the list in a json file on disk. + +Example `providers.json` file: +``` +[ + { + "name": "Example", + "full_name": "Example provider", + "organization": "Owncloud", + "domain": "example.com", + "homepage": "https://example.com.com", + "services": [ + { + "endpoint": { + "type": { + "name": "OCM", + "description": "example.com Open Cloud Mesh API" + }, + "name": "example.com - OCM API", + "path": "https://example.com/ocm/", + "is_monitored": true + }, + "api_version": "0.0.1", + "host": "example.com" + } + ] + }, +] +``` + +## Invitation Workflow + +Before sharing a resource with a remote user this user has to be invited by the sharer. + +In order to do so a POST request is sent to the `generate-invite` endpoint of the sciencemesh API. The generated token is passed on to the receiver, who will then use the `accept-invite` endpoint to accept the invitation. As a result remote users will be added to the `ocminvitemanager` on both sides. See [invitation flow](invitation_flow) for the according sequence diagram. + +The data backend of the `ocminvitemanager` is configurable. The only supported backend currently is `json` which stores the data in a json file on disk. + +## Creating Shares + +OCM Shares are currently created using the ocs API, just like regular shares. The difference is the share type, which is 6 (ShareTypeFederatedCloudShare) in this case, and a few additional parameters required for identifying the remote user. + +See [Create share flow](create_share_flow) for the according sequence diagram. + +The data backends of the `ocmshareprovider` and `ocmcore` services are configurable. The only supported backend currently is `json` which stores the data in a json file on disk. diff --git a/services/ocm/pkg/config/config.go b/services/ocm/pkg/config/config.go index 17e53a2fd..f78d0bc6a 100644 --- a/services/ocm/pkg/config/config.go +++ b/services/ocm/pkg/config/config.go @@ -100,7 +100,7 @@ type OCMProviderAuthorizerDrivers struct { type OCMProviderAuthorizerJSONDriver struct { Providers string `yaml:"providers" env:"OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE" desc:"Path to the JSON file where ocm invites data will be stored. If not defined, the root directory derives from $OCIS_BASE_DATA_PATH:/storage."` - VerifyRequestHostname bool `yaml:"verify_request_hostname" env:"OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE"` + VerifyRequestHostname bool `yaml:"verify_request_hostname" env:"OCM_OCM_PROVIDER_AUTHORIZER_VERIFY_REQUEST_HOSTNAME" desc:"Verify the hostname of the incoming request against the hostname of the OCM provider."` } type OCMCore struct {