diff --git a/.drone.env b/.drone.env index 895c99c06..7e845b679 100644 --- a/.drone.env +++ b/.drone.env @@ -1,5 +1,5 @@ # The test runner source for API tests -CORE_COMMITID=09d584745d6cbd6aebc557d9b78f6130e9b99e2b +CORE_COMMITID=88dc1fc01b8afd254d59cbface6ef48670848e22 CORE_BRANCH=master # The test runner source for UI tests diff --git a/.drone.star b/.drone.star index 5315f4fc4..54724ed0d 100644 --- a/.drone.star +++ b/.drone.star @@ -1400,7 +1400,6 @@ def notify(ctx): def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): environment = { "OCIS_URL": "https://ocis-server:9200", - "STORAGE_HOME_DRIVER": "%s" % (storage), "STORAGE_USERS_DRIVER": "%s" % (storage), "STORAGE_USERS_DRIVER_LOCAL_ROOT": "/srv/app/tmp/ocis/local/root", "STORAGE_USERS_DRIVER_OWNCLOUD_DATADIR": "/srv/app/tmp/ocis/owncloud/data", @@ -2082,7 +2081,6 @@ def latestOcisServer(): "STORAGE_LDAP_USERFILTER": "(&(objectclass=posixAccount)(objectclass=owncloud)(|(ownclouduuid={{.OpaqueId}})(uid={{.OpaqueId}})))", "STORAGE_LDAP_USERFINDFILTER": "(&(objectclass=posixAccount)(objectclass=owncloud)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))", # ownCloud storage driver - "STORAGE_HOME_DRIVER": "owncloudsql", "STORAGE_USERS_DRIVER": "owncloudsql", "STORAGE_METADATA_DRIVER": "ocis", "STORAGE_USERS_DRIVER_OWNCLOUDSQL_DATADIR": "/mnt/data/files", diff --git a/CHANGELOG.md b/CHANGELOG.md index d2292e090..4fdd3ce67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The following sections list the changes for unreleased. * Enhancement - Add new file url of the app provider to the ocs capabilities: [#2884](https://github.com/owncloud/ocis/pull/2884) * Enhancement - Add spaces capability: [#2931](https://github.com/owncloud/ocis/pull/2931) * Enhancement - Support signature auth in the public share auth middleware: [#2831](https://github.com/owncloud/ocis/pull/2831) +* Enhancement - Update REVA to v1.16.1-0.20220112085026-07451f6cd806: [#2953](https://github.com/owncloud/ocis/pull/2953) +* Enhancement - Add filter by driveType and id to /me/drives: [#2946](https://github.com/owncloud/ocis/pull/2946) * Enhancement - Update REVA to xxx: [#2878](https://github.com/owncloud/ocis/pull/2878) * Enhancement - Update ownCloud Web to v4.8.0: [#2895](https://github.com/owncloud/ocis/pull/2895) @@ -79,10 +81,11 @@ The following sections list the changes for unreleased. * Enhancement - Add spaces capability: [#2931](https://github.com/owncloud/ocis/pull/2931) - We've added the spaces capability with version 0.0.1 and enabled set to true. + We've added the spaces capability with version 0.0.1 and enabled defaulting to true. https://github.com/owncloud/ocis/pull/2931 https://github.com/cs3org/reva/pull/2015 + https://github.com/owncloud/ocis/pull/2965 * Enhancement - Support signature auth in the public share auth middleware: [#2831](https://github.com/owncloud/ocis/pull/2831) @@ -90,6 +93,20 @@ The following sections list the changes for unreleased. https://github.com/owncloud/ocis/pull/2831 +* Enhancement - Update REVA to v1.16.1-0.20220112085026-07451f6cd806: [#2953](https://github.com/owncloud/ocis/pull/2953) + + Update REVA to v1.16.1-0.20220112085026-07451f6cd806 + + https://github.com/owncloud/ocis/pull/2953 + +* Enhancement - Add filter by driveType and id to /me/drives: [#2946](https://github.com/owncloud/ocis/pull/2946) + + We added two possible filter terms (driveType, id) to the /me/drives endpoint on the graph api. + These can be used with the odata query parameter "$filter". We only support the "eq" operator + for now. + + https://github.com/owncloud/ocis/pull/2946 + * Enhancement - Update REVA to xxx: [#2878](https://github.com/owncloud/ocis/pull/2878) Updated REVA to xxx This update includes: diff --git a/accounts/templates/CONFIGURATION.tmpl b/accounts/templates/CONFIGURATION.tmpl deleted file mode 100644 index c180d7a56..000000000 --- a/accounts/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/accounts/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-accounts reads `accounts.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/accounts/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "accounts" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `accounts [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "accounts" -}} -### accounts {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `accounts {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/changelog/unreleased/enhancement-spaces-capability.md b/changelog/unreleased/enhancement-spaces-capability.md index 8129de09c..7b056135d 100644 --- a/changelog/unreleased/enhancement-spaces-capability.md +++ b/changelog/unreleased/enhancement-spaces-capability.md @@ -1,6 +1,7 @@ Enhancement: Add spaces capability -We've added the spaces capability with version 0.0.1 and enabled set to true. +We've added the spaces capability with version 0.0.1 and enabled defaulting to true. https://github.com/owncloud/ocis/pull/2931 https://github.com/cs3org/reva/pull/2015 +https://github.com/owncloud/ocis/pull/2965 diff --git a/changelog/unreleased/reva-update-07451f6cd8067.md b/changelog/unreleased/reva-update-07451f6cd8067.md new file mode 100644 index 000000000..1959d2666 --- /dev/null +++ b/changelog/unreleased/reva-update-07451f6cd8067.md @@ -0,0 +1,5 @@ +Enhancement: update REVA to v1.16.1-0.20220112085026-07451f6cd806 + +Update REVA to v1.16.1-0.20220112085026-07451f6cd806 + +https://github.com/owncloud/ocis/pull/2953 diff --git a/changelog/unreleased/spaces-filters.md b/changelog/unreleased/spaces-filters.md new file mode 100644 index 000000000..7b3f675e3 --- /dev/null +++ b/changelog/unreleased/spaces-filters.md @@ -0,0 +1,6 @@ +Enhancement: Add filter by driveType and id to /me/drives + +We added two possible filter terms (driveType, id) to the /me/drives endpoint on the graph api. These can be used with the odata query parameter "$filter". +We only support the "eq" operator for now. + +https://github.com/owncloud/ocis/pull/2946 diff --git a/deployments/examples/oc10_ocis_parallel/docker-compose.yml b/deployments/examples/oc10_ocis_parallel/docker-compose.yml index ec5185b86..3d7622e04 100644 --- a/deployments/examples/oc10_ocis_parallel/docker-compose.yml +++ b/deployments/examples/oc10_ocis_parallel/docker-compose.yml @@ -91,7 +91,6 @@ services: STORAGE_LDAP_USERFILTER: "(&(objectclass=posixAccount)(objectclass=owncloud)(|(ownclouduuid={{.OpaqueId}})(uid={{.OpaqueId}})))" STORAGE_LDAP_USERFINDFILTER: "(&(objectclass=posixAccount)(objectclass=owncloud)(|(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)))" # ownCloud storage driver - STORAGE_HOME_DRIVER: owncloudsql STORAGE_USERS_DRIVER: owncloudsql STORAGE_METADATA_DRIVER: ocis # keep metadata on ocis storage since this are only small files atm STORAGE_USERS_DRIVER_OWNCLOUDSQL_DATADIR: /mnt/data/files diff --git a/deployments/examples/oc10_ocis_parallel/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/oc10_ocis_parallel/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/oc10_ocis_parallel/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/oc10_ocis_parallel/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_hello/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_hello/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_hello/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_hello/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_keycloak/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_keycloak/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_keycloak/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_keycloak/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_ldap/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_ldap/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_ldap/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_ldap/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_s3/docker-compose.yml b/deployments/examples/ocis_s3/docker-compose.yml index aed2b45f4..a8a168273 100644 --- a/deployments/examples/ocis_s3/docker-compose.yml +++ b/deployments/examples/ocis_s3/docker-compose.yml @@ -60,7 +60,6 @@ services: STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} # activate s3ng storage driver - STORAGE_HOME_DRIVER: s3ng STORAGE_USERS_DRIVER: s3ng STORAGE_METADATA_DRIVER: ocis # keep metadata on ocis storage since this are only small files atm # s3ng specific settings diff --git a/deployments/examples/ocis_s3/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_s3/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_s3/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_s3/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_traefik/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_traefik/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_traefik/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_traefik/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/deployments/examples/ocis_wopi/monitoring_tracing/docker-compose-additions.yml b/deployments/examples/ocis_wopi/monitoring_tracing/docker-compose-additions.yml index 8abdf4e83..705cfccd9 100644 --- a/deployments/examples/ocis_wopi/monitoring_tracing/docker-compose-additions.yml +++ b/deployments/examples/ocis_wopi/monitoring_tracing/docker-compose-additions.yml @@ -23,7 +23,6 @@ services: STORAGE_FRONTEND_DEBUG_ADDR: 0.0.0.0:9141 STORAGE_GATEWAY_DEBUG_ADDR: 0.0.0.0:9143 STORAGE_GROUPPROVIDER_DEBUG_ADDR: 0.0.0.0:9161 - STORAGE_HOME_DEBUG_ADDR: 0.0.0.0:9156 STORAGE_METADATA_DEBUG_ADDR: 0.0.0.0:9217 STORAGE_PUBLIC_LINK_DEBUG_ADDR: 0.0.0.0:9179 STORAGE_USERPROVIDER_DEBUG_ADDR: 0.0.0.0:9145 diff --git a/docs/extensions/storage/storagedrivers.md b/docs/extensions/storage/storagedrivers.md index 936dd9f96..375ffa330 100644 --- a/docs/extensions/storage/storagedrivers.md +++ b/docs/extensions/storage/storagedrivers.md @@ -168,7 +168,6 @@ For a simple docker-compose setup, you can create a volume which will be used by The CERN eos storage has evolved with ownCloud and natively supports id based lookup, ETag propagation, subtree size accounting, sharing, trash and versions. To use it you need to change the default configuration of the `storage storage-home` command (or have a look at the Makefile ̀ eos-start` target): ``` -export STORAGE_HOME_DRIVER=eos export STORAGE_DRIVER_EOS_NAMESPACE=/eos export STORAGE_DRIVER_EOS_MASTER_URL="root://eos-mgm1.eoscluster.cern.ch:1094" export STORAGE_DRIVER_EOS_ENABLE_HOME=true diff --git a/glauth/templates/CONFIGURATION.tmpl b/glauth/templates/CONFIGURATION.tmpl deleted file mode 100644 index ac2fd7974..000000000 --- a/glauth/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/glauth/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-glauth reads `glauth.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/glauth/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "glauth" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `glauth [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "glauth" -}} -### glauth {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `glauth {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/go.mod b/go.mod index c5842f2fe..370309494 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/blevesearch/bleve/v2 v2.3.0 github.com/coreos/go-oidc/v3 v3.1.0 github.com/cs3org/go-cs3apis v0.0.0-20211214102047-7ce3134d7bf8 - github.com/cs3org/reva v1.17.1-0.20220105095955-fa1d1fc01d85 + github.com/cs3org/reva v1.16.1-0.20220112085026-07451f6cd806 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 @@ -243,7 +243,4 @@ require ( stash.kopano.io/kgol/oidc-go v0.3.2 // indirect ) -//replace github.com/cs3org/reva => github.com/cs3org/reva v1.16.1-0.20211208164450-3abd76eecf8b //replace github.com/cs3org/reva => ../reva - -replace github.com/cs3org/reva => github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db diff --git a/go.sum b/go.sum index 3746ae6ea..1c73d4352 100644 --- a/go.sum +++ b/go.sum @@ -324,8 +324,8 @@ github.com/crewjam/saml v0.4.5/go.mod h1:qCJQpUtZte9R1ZjUBcW8qtCNlinbO363ooNl02S github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20211214102047-7ce3134d7bf8 h1:PqOprF37OvwCbAN5W23znknGk6N/LMayqLAeP904FHE= github.com/cs3org/go-cs3apis v0.0.0-20211214102047-7ce3134d7bf8/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db h1:YCzbz8N0OHkO6AcA2SfXHCc02Y/DqSkO+hm8Pj+eDZ4= -github.com/cs3org/reva v1.16.1-0.20220111150347-1b21aefbf8db/go.mod h1:WqO2/NkAmx1qes09G92lGPxxyroQgnZetJrCPItCcDo= +github.com/cs3org/reva v1.16.1-0.20220112085026-07451f6cd806 h1:kwGCQOlC/x0sz4KZ28n7GgZ+aBlmqbKn8CmbkNK6WU4= +github.com/cs3org/reva v1.16.1-0.20220112085026-07451f6cd806/go.mod h1:HisUI5sBYaR3kqqtP+O8MzY7XRjqpV8IgxzK4aK0BtI= 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= @@ -1277,7 +1277,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/studio-b12/gowebdav v0.0.0-20210917133250-a3a86976a1df/go.mod h1:gCcfDlA1Y7GqOaeEKw5l9dOGx1VLdc/HuQSlQAaZ30s= +github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo= diff --git a/graph-explorer/templates/CONFIGURATION.tmpl b/graph-explorer/templates/CONFIGURATION.tmpl deleted file mode 100644 index ba9282bc2..000000000 --- a/graph-explorer/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/graph-explorer/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/graph-explorer/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "graph-explorer" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `graph-explorer [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "graph-explorer" -}} -### graph-explorer {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `graph-explorer {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/graph/pkg/config/config.go b/graph/pkg/config/config.go index 09a00b25c..0b010c4f9 100644 --- a/graph/pkg/config/config.go +++ b/graph/pkg/config/config.go @@ -36,9 +36,11 @@ type Spaces struct { } type LDAP struct { - URI string `ocisConfig:"uri" env:"GRAPH_LDAP_URI"` - BindDN string `ocisConfig:"bind_dn" env:"GRAPH_LDAP_BIND_DN"` - BindPassword string `ocisConfig:"bind_password" env:"GRAPH_LDAP_BIND_PASSWORD"` + URI string `ocisConfig:"uri" env:"GRAPH_LDAP_URI"` + BindDN string `ocisConfig:"bind_dn" env:"GRAPH_LDAP_BIND_DN"` + BindPassword string `ocisConfig:"bind_password" env:"GRAPH_LDAP_BIND_PASSWORD"` + UseServerUUID bool `ocisConfig:"use_server_uuid" env:"GRAPH_LDAP_SERVER_UUID"` + WriteEnabled bool `ocisConfig:"write_enabled" env:"GRAPH_LDAP_SERVER_WRITE_ENABLED"` UserBaseDN string `ocisConfig:"user_base_dn" env:"GRAPH_LDAP_USER_BASE_DN"` UserSearchScope string `ocisConfig:"user_search_scope" env:"GRAPH_LDAP_USER_SCOPE"` diff --git a/graph/pkg/config/defaultconfig.go b/graph/pkg/config/defaultconfig.go index c46d27a39..8f09207a8 100644 --- a/graph/pkg/config/defaultconfig.go +++ b/graph/pkg/config/defaultconfig.go @@ -32,20 +32,22 @@ func DefaultConfig() *Config { URI: "ldap://localhost:9125", BindDN: "", BindPassword: "", + UseServerUUID: false, + WriteEnabled: false, UserBaseDN: "ou=users,dc=ocis,dc=test", UserSearchScope: "sub", - UserFilter: "(objectClass=posixaccount)", + UserFilter: "(objectClass=inetOrgPerson)", UserEmailAttribute: "mail", UserDisplayNameAttribute: "displayName", UserNameAttribute: "uid", // FIXME: switch this to some more widely available attribute by default // ideally this needs to be constant for the lifetime of a users - UserIDAttribute: "ownclouduuid", + UserIDAttribute: "owncloudUUID", GroupBaseDN: "ou=groups,dc=ocis,dc=test", GroupSearchScope: "sub", GroupFilter: "(objectclass=groupOfNames)", GroupNameAttribute: "cn", - GroupIDAttribute: "cn", + GroupIDAttribute: "owncloudUUID", }, }, } diff --git a/graph/pkg/identity/backend.go b/graph/pkg/identity/backend.go index f7b497251..d230a6b13 100644 --- a/graph/pkg/identity/backend.go +++ b/graph/pkg/identity/backend.go @@ -9,6 +9,15 @@ import ( ) type Backend interface { + // CreateUser creates a given user in the identity backend. + CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error) + + // DeleteUser deletes a given user, identified by username or id, from the backend + DeleteUser(ctx context.Context, nameOrId string) error + + // UpdateUser applies changes to given user, identified by username or id + UpdateUser(ctx context.Context, nameOrId string, user libregraph.User) (*libregraph.User, error) + GetUser(ctx context.Context, nameOrId string) (*libregraph.User, error) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) diff --git a/graph/pkg/identity/cs3.go b/graph/pkg/identity/cs3.go index f76da144f..231107d11 100644 --- a/graph/pkg/identity/cs3.go +++ b/graph/pkg/identity/cs3.go @@ -20,6 +20,21 @@ type CS3 struct { Logger *log.Logger } +// CreateUser implements the Backend Interface. It's currently not supported for the CS3 backend +func (i *CS3) CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error) { + return nil, errorcode.New(errorcode.NotSupported, "not implemented") +} + +// DeleteUser implements the Backend Interface. It's currently not supported for the CS3 backend +func (i *CS3) DeleteUser(ctx context.Context, nameOrID string) error { + return errorcode.New(errorcode.NotSupported, "not implemented") +} + +// UpdateUser implements the Backend Interface. It's currently not suported for the CS3 backend +func (i *CS3) UpdateUser(ctx context.Context, nameOrID string, user libregraph.User) (*libregraph.User, error) { + return nil, errorcode.New(errorcode.NotSupported, "not implemented") +} + func (i *CS3) GetUser(ctx context.Context, userID string) (*libregraph.User, error) { client, err := pool.GetGatewayServiceClient(i.Config.Address) if err != nil { diff --git a/graph/pkg/identity/ldap.go b/graph/pkg/identity/ldap.go index 5942c6f99..bf16afe93 100644 --- a/graph/pkg/identity/ldap.go +++ b/graph/pkg/identity/ldap.go @@ -6,6 +6,7 @@ import ( "net/url" "github.com/go-ldap/ldap/v3" + "github.com/gofrs/uuid" libregraph "github.com/owncloud/libre-graph-api-go" "github.com/owncloud/ocis/graph/pkg/config" @@ -14,6 +15,9 @@ import ( ) type LDAP struct { + useServerUUID bool + writeEnabled bool + userBaseDN string userFilter string userScope int @@ -71,6 +75,7 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger) (*LD } return &LDAP{ + useServerUUID: config.UseServerUUID, userBaseDN: config.UserBaseDN, userFilter: config.UserFilter, userScope: userScope, @@ -81,15 +86,180 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger) (*LD groupAttributeMap: gam, logger: logger, conn: lc, + writeEnabled: config.WriteEnabled, }, nil } -func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, error) { - i.logger.Debug().Str("backend", "ldap").Msg("GetUser") - userID = ldap.EscapeFilter(userID) +// CreateUser implements the Backend Interface. It converts the libregraph.User into an +// LDAP User Entry (using the inetOrgPerson LDAP Objectclass) add adds that to the +// configured LDAP server +func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error) { + if !i.writeEnabled { + return nil, errorcode.New(errorcode.NotAllowed, "server is configured read-only") + } + ar := ldap.AddRequest{ + DN: fmt.Sprintf("uid=%s,%s", *user.OnPremisesSamAccountName, i.userBaseDN), + Attributes: []ldap.Attribute{ + // inetOrgPerson requires "cn" + { + Type: "cn", + Vals: []string{*user.OnPremisesSamAccountName}, + }, + { + Type: i.userAttributeMap.mail, + Vals: []string{*user.Mail}, + }, + { + Type: i.userAttributeMap.userName, + Vals: []string{*user.OnPremisesSamAccountName}, + }, + { + Type: i.userAttributeMap.displayName, + Vals: []string{*user.DisplayName}, + }, + }, + } + + objectClasses := []string{"inetOrgPerson", "organizationalPerson", "person", "top"} + + if user.PasswordProfile != nil && user.PasswordProfile.Password != nil { + // TODO? This relies to the LDAP server to properly hash the password. + // We might want to add support for the Password Modify LDAP Extended + // Operation for servers that implement it. (Or implement client-side + // hashing here. + ar.Attribute("userPassword", []string{*user.PasswordProfile.Password}) + } + if !i.useServerUUID { + ar.Attribute("owncloudUUID", []string{uuid.Must(uuid.NewV4()).String()}) + objectClasses = append(objectClasses, "owncloud") + } + ar.Attribute("objectClass", objectClasses) + + // inetOrgPerson requires "sn" to be set. Set it to the Username if + // Surname is not set in the Request + var sn string + if user.Surname != nil && *user.Surname != "" { + sn = *user.Surname + } else { + sn = *user.OnPremisesSamAccountName + } + ar.Attribute("sn", []string{sn}) + + if err := i.conn.Add(&ar); err != nil { + return nil, err + } + + // Read back user from LDAP to get the generated UUID + e, err := i.getUserByDN(ar.DN) + if err != nil { + return nil, err + } + return i.createUserModelFromLDAP(e), nil +} + +// DeleteUser implements the Backend Interface. It permanently deletes a User identified +// by name or id from the LDAP server +func (i *LDAP) DeleteUser(ctx context.Context, nameOrID string) error { + if !i.writeEnabled { + return errorcode.New(errorcode.NotAllowed, "server is configured read-only") + } + e, err := i.getLDAPUserByNameOrID(nameOrID) + if err != nil { + return err + } + dr := ldap.DelRequest{DN: e.DN} + if err = i.conn.Del(&dr); err != nil { + return err + } + return nil +} + +// UpdateUser implements the Backend Interface. It's currently not suported for the CS3 backedn +func (i *LDAP) UpdateUser(ctx context.Context, nameOrID string, user libregraph.User) (*libregraph.User, error) { + if !i.writeEnabled { + return nil, errorcode.New(errorcode.NotAllowed, "server is configured read-only") + } + e, err := i.getLDAPUserByNameOrID(nameOrID) + if err != nil { + return nil, err + } + + // Don't allow updates of the ID + if user.Id != nil && *user.Id != "" { + if e.GetEqualFoldAttributeValue(i.userAttributeMap.id) != *user.Id { + return nil, errorcode.New(errorcode.NotAllowed, "changing the UserId is not allowed") + } + } + // TODO: In order to allow updating the user name we'd need to issue a ModRDN operation + // As we currently using uid as the naming Attribute for the user entries. (Do we even + // want to allow changing the user name?). For now just disallow it. + if user.OnPremisesSamAccountName != nil && *user.OnPremisesSamAccountName != "" { + if e.GetEqualFoldAttributeValue(i.userAttributeMap.userName) != *user.OnPremisesSamAccountName { + return nil, errorcode.New(errorcode.NotSupported, "changing the user name is currently not supported") + } + } + + mr := ldap.ModifyRequest{DN: e.DN} + if user.DisplayName != nil && *user.DisplayName != "" { + if e.GetEqualFoldAttributeValue(i.userAttributeMap.displayName) != *user.DisplayName { + mr.Replace(i.userAttributeMap.displayName, []string{*user.DisplayName}) + } + } + if user.Mail != nil && *user.Mail != "" { + if e.GetEqualFoldAttributeValue(i.userAttributeMap.mail) != *user.Mail { + mr.Replace(i.userAttributeMap.mail, []string{*user.Mail}) + } + } + if user.PasswordProfile != nil && user.PasswordProfile.Password != nil && *user.PasswordProfile.Password != "" { + // password are hashed server side there is no need to check if the new password + // is actually different from the old one. + mr.Replace("userPassword", []string{*user.PasswordProfile.Password}) + } + + if err := i.conn.Modify(&mr); err != nil { + return nil, err + } + + // Read back user from LDAP to get the generated UUID + e, err = i.getUserByDN(e.DN) + if err != nil { + return nil, err + } + return i.createUserModelFromLDAP(e), nil +} + +func (i *LDAP) getUserByDN(dn string) (*ldap.Entry, error) { + searchRequest := ldap.NewSearchRequest( + dn, ldap.ScopeBaseObject, ldap.NeverDerefAliases, 1, 0, false, + "(objectclass=*)", + []string{ + i.userAttributeMap.displayName, + i.userAttributeMap.id, + i.userAttributeMap.mail, + i.userAttributeMap.userName, + }, + nil, + ) + + i.logger.Debug().Str("backend", "ldap").Str("dn", dn).Msg("Search user by DN") + res, err := i.conn.Search(searchRequest) + + if err != nil { + i.logger.Error().Err(err).Str("backend", "ldap").Str("dn", dn).Msg("Search user by DN failed") + return nil, errorcode.New(errorcode.ItemNotFound, err.Error()) + } + if len(res.Entries) == 0 { + return nil, errorcode.New(errorcode.ItemNotFound, "not found") + } + + return res.Entries[0], nil +} + +func (i *LDAP) getLDAPUserByNameOrID(nameOrID string) (*ldap.Entry, error) { + nameOrID = ldap.EscapeFilter(nameOrID) searchRequest := ldap.NewSearchRequest( i.userBaseDN, i.userScope, ldap.NeverDerefAliases, 1, 0, false, - fmt.Sprintf("(&%s(|(%s=%s)(%s=%s)))", i.userFilter, i.userAttributeMap.userName, userID, i.userAttributeMap.id, userID), + fmt.Sprintf("(&%s(|(%s=%s)(%s=%s)))", i.userFilter, i.userAttributeMap.userName, nameOrID, i.userAttributeMap.id, nameOrID), []string{ i.userAttributeMap.displayName, i.userAttributeMap.id, @@ -105,8 +275,9 @@ func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, er var errmsg string if lerr, ok := err.(*ldap.Error); ok { if lerr.ResultCode == ldap.LDAPResultSizeLimitExceeded { - errmsg = fmt.Sprintf("too many results searching for user '%s'", userID) - i.logger.Debug().Str("backend", "ldap").Err(lerr).Msg(errmsg) + errmsg = fmt.Sprintf("too many results searching for user '%s'", nameOrID) + i.logger.Debug().Str("backend", "ldap").Err(lerr). + Str("user", nameOrID).Msg("too many results searching for user") } } return nil, errorcode.New(errorcode.ItemNotFound, errmsg) @@ -115,7 +286,16 @@ func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, er return nil, errorcode.New(errorcode.ItemNotFound, "not found") } - return i.createUserModelFromLDAP(res.Entries[0]), nil + return res.Entries[0], nil +} + +func (i *LDAP) GetUser(ctx context.Context, nameOrID string) (*libregraph.User, error) { + i.logger.Debug().Str("backend", "ldap").Msg("GetUser") + e, err := i.getLDAPUserByNameOrID(nameOrID) + if err != nil { + return nil, err + } + return i.createUserModelFromLDAP(e), nil } func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) { diff --git a/graph/pkg/identity/ldap/reconnect.go b/graph/pkg/identity/ldap/reconnect.go index f929e57a5..b4e868846 100644 --- a/graph/pkg/identity/ldap/reconnect.go +++ b/graph/pkg/identity/ldap/reconnect.go @@ -162,24 +162,49 @@ func (c ConnWithReconnect) ExternalBind() error { return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) } -func (c ConnWithReconnect) Add(*ldap.AddRequest) error { - return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) +func (c ConnWithReconnect) Add(a *ldap.AddRequest) error { + conn, err := c.GetConnection() + if err != nil { + return err + } + + return conn.Add(a) } -func (c ConnWithReconnect) Del(*ldap.DelRequest) error { - return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) +func (c ConnWithReconnect) Del(d *ldap.DelRequest) error { + conn, err := c.GetConnection() + if err != nil { + return err + } + + return conn.Del(d) } -func (c ConnWithReconnect) Modify(*ldap.ModifyRequest) error { - return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) +func (c ConnWithReconnect) Modify(m *ldap.ModifyRequest) error { + conn, err := c.GetConnection() + if err != nil { + return err + } + + return conn.Modify(m) } -func (c ConnWithReconnect) ModifyDN(*ldap.ModifyDNRequest) error { - return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) +func (c ConnWithReconnect) ModifyDN(m *ldap.ModifyDNRequest) error { + conn, err := c.GetConnection() + if err != nil { + return err + } + + return conn.ModifyDN(m) } -func (c ConnWithReconnect) ModifyWithResult(*ldap.ModifyRequest) (*ldap.ModifyResult, error) { - return nil, ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented")) +func (c ConnWithReconnect) ModifyWithResult(m *ldap.ModifyRequest) (*ldap.ModifyResult, error) { + conn, err := c.GetConnection() + if err != nil { + return nil, err + } + + return conn.ModifyWithResult(m) } func (c ConnWithReconnect) Compare(dn, attribute, value string) (bool, error) { diff --git a/graph/pkg/service/v0/drives.go b/graph/pkg/service/v0/drives.go index 20cfa8f1f..e0eddaf95 100644 --- a/graph/pkg/service/v0/drives.go +++ b/graph/pkg/service/v0/drives.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/CiscoM31/godata" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" @@ -35,6 +36,14 @@ import ( // GetDrives implements the Service interface. func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) { + sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/") + // Parse the request with odata parser + odataReq, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query()) + if err != nil { + g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error") + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error()) + return + } g.logger.Info().Msg("Calling GetDrives") ctx := r.Context() @@ -61,6 +70,12 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) return } + filters, err := generateCs3Filters(odataReq) + if err != nil { + g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error") + errorcode.NotSupported.Render(w, r, http.StatusNotImplemented, err.Error()) + return + } res, err := client.ListStorageSpaces(ctx, &storageprovider.ListStorageSpacesRequest{ Opaque: &types.Opaque{Map: map[string]*types.OpaqueEntry{ "permissions": { @@ -68,7 +83,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) { Value: value, }, }}, - // TODO add filters? + Filters: filters, }) switch { case err != nil: @@ -618,3 +633,35 @@ func canSetSpaceQuota(ctx context.Context, user *userv1beta1.User) (bool, error) } return true, nil } + +func generateCs3Filters(request *godata.GoDataRequest) ([]*storageprovider.ListStorageSpacesRequest_Filter, error) { + var filters []*storageprovider.ListStorageSpacesRequest_Filter + if request.Query.Filter != nil { + if request.Query.Filter.Tree.Token.Value == "eq" { + switch request.Query.Filter.Tree.Children[0].Token.Value { + case "driveType": + filter1 := &storageprovider.ListStorageSpacesRequest_Filter{ + Type: storageprovider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE, + Term: &storageprovider.ListStorageSpacesRequest_Filter_SpaceType{ + SpaceType: strings.Trim(request.Query.Filter.Tree.Children[1].Token.Value, "'"), + }, + } + filters = append(filters, filter1) + case "id": + filter2 := &storageprovider.ListStorageSpacesRequest_Filter{ + Type: storageprovider.ListStorageSpacesRequest_Filter_TYPE_ID, + Term: &storageprovider.ListStorageSpacesRequest_Filter_Id{ + Id: &storageprovider.StorageSpaceId{ + OpaqueId: strings.Trim(request.Query.Filter.Tree.Children[1].Token.Value, "'"), + }, + }, + } + filters = append(filters, filter2) + } + } else { + err := fmt.Errorf("unsupported filter operand: %s", request.Query.Filter.Tree.Token.Value) + return nil, err + } + } + return filters, nil +} diff --git a/graph/pkg/service/v0/instrument.go b/graph/pkg/service/v0/instrument.go index 878945f78..a0fb82542 100644 --- a/graph/pkg/service/v0/instrument.go +++ b/graph/pkg/service/v0/instrument.go @@ -34,7 +34,22 @@ func (i instrument) GetUsers(w http.ResponseWriter, r *http.Request) { i.next.GetUsers(w, r) } -// GetUsers implements the Service interface. +// GetUser implements the Service interface. func (i instrument) GetUser(w http.ResponseWriter, r *http.Request) { i.next.GetUser(w, r) } + +// PostUser implements the Service interface. +func (i instrument) PostUser(w http.ResponseWriter, r *http.Request) { + i.next.PostUser(w, r) +} + +// DeleteUser implements the Service interface. +func (i instrument) DeleteUser(w http.ResponseWriter, r *http.Request) { + i.next.DeleteUser(w, r) +} + +// PatchUser implements the Service interface. +func (i instrument) PatchUser(w http.ResponseWriter, r *http.Request) { + i.next.PatchUser(w, r) +} diff --git a/graph/pkg/service/v0/logging.go b/graph/pkg/service/v0/logging.go index 124a54cf3..d5ce3373a 100644 --- a/graph/pkg/service/v0/logging.go +++ b/graph/pkg/service/v0/logging.go @@ -38,3 +38,18 @@ func (l logging) GetUsers(w http.ResponseWriter, r *http.Request) { func (l logging) GetUser(w http.ResponseWriter, r *http.Request) { l.next.GetUser(w, r) } + +// PostUser implements the Service interface. +func (l logging) PostUser(w http.ResponseWriter, r *http.Request) { + l.next.PostUser(w, r) +} + +// DeleteUser implements the Service interface. +func (l logging) DeleteUser(w http.ResponseWriter, r *http.Request) { + l.next.DeleteUser(w, r) +} + +// PatchUser implements the Service interface. +func (l logging) PatchUser(w http.ResponseWriter, r *http.Request) { + l.next.PatchUser(w, r) +} diff --git a/graph/pkg/service/v0/service.go b/graph/pkg/service/v0/service.go index cb1168483..3bd4b810c 100644 --- a/graph/pkg/service/v0/service.go +++ b/graph/pkg/service/v0/service.go @@ -19,6 +19,9 @@ type Service interface { GetMe(http.ResponseWriter, *http.Request) GetUsers(http.ResponseWriter, *http.Request) GetUser(http.ResponseWriter, *http.Request) + PostUser(http.ResponseWriter, *http.Request) + DeleteUser(http.ResponseWriter, *http.Request) + PatchUser(http.ResponseWriter, *http.Request) } // NewService returns a service implementation for Service. @@ -69,8 +72,11 @@ func NewService(opts ...Option) Service { }) r.Route("/users", func(r chi.Router) { r.Get("/", svc.GetUsers) + r.Post("/", svc.PostUser) r.Route("/{userID}", func(r chi.Router) { r.Get("/", svc.GetUser) + r.Delete("/", svc.DeleteUser) + r.Patch("/", svc.PatchUser) }) }) r.Route("/groups", func(r chi.Router) { diff --git a/graph/pkg/service/v0/tracing.go b/graph/pkg/service/v0/tracing.go index 64cbc9708..c1e544214 100644 --- a/graph/pkg/service/v0/tracing.go +++ b/graph/pkg/service/v0/tracing.go @@ -34,3 +34,18 @@ func (t tracing) GetUsers(w http.ResponseWriter, r *http.Request) { func (t tracing) GetUser(w http.ResponseWriter, r *http.Request) { t.next.GetUser(w, r) } + +// PostUser implements the Service interface. +func (t tracing) PostUser(w http.ResponseWriter, r *http.Request) { + t.next.PostUser(w, r) +} + +// DeleteUser implements the Service interface. +func (t tracing) DeleteUser(w http.ResponseWriter, r *http.Request) { + t.next.DeleteUser(w, r) +} + +// PatchUser implements the Service interface. +func (t tracing) PatchUser(w http.ResponseWriter, r *http.Request) { + t.next.PatchUser(w, r) +} diff --git a/graph/pkg/service/v0/users.go b/graph/pkg/service/v0/users.go index c62337cbc..88d87a420 100644 --- a/graph/pkg/service/v0/users.go +++ b/graph/pkg/service/v0/users.go @@ -1,6 +1,7 @@ package svc import ( + "encoding/json" "errors" "net/http" "net/url" @@ -8,9 +9,9 @@ import ( revactx "github.com/cs3org/reva/pkg/ctx" "github.com/go-chi/chi/v5" "github.com/go-chi/render" + libregraph "github.com/owncloud/libre-graph-api-go" "github.com/owncloud/ocis/graph/pkg/identity" "github.com/owncloud/ocis/graph/pkg/service/v0/errorcode" - //msgraph "github.com/owncloud/open-graph-api-go" // FIXME needs OnPremisesSamAccountName, OnPremisesDomainName and AdditionalData ) // GetMe implements the Service interface. @@ -32,7 +33,6 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) { } // GetUsers implements the Service interface. -// TODO use cs3 api to look up user func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { users, err := g.identityBackend.GetUsers(r.Context(), r.URL.Query()) if err != nil { @@ -47,6 +47,36 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, &listResponse{Value: users}) } +func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) { + u := libregraph.NewUser() + err := json.NewDecoder(r.Body).Decode(u) + if err != nil { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error()) + return + } + + if isNilOrEmpty(u.DisplayName) || isNilOrEmpty(u.OnPremisesSamAccountName) || isNilOrEmpty(u.Mail) { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Missing Required Attribute") + return + } + + // Disallow user-supplied IDs. It's supposed to be readonly. We're either + // generating them in the backend ourselves or rely on the Backend's + // storage (e.g. LDAP) to provide a unique ID. + if !isNilOrEmpty(u.Id) { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user id is a read-only attribute") + return + } + + if u, err = g.identityBackend.CreateUser(r.Context(), *u); err != nil { + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) + return + } + + render.Status(r, http.StatusOK) + render.JSON(w, r, u) +} + // GetUser implements the Service interface. func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) { userID := chi.URLParam(r, "userID") @@ -74,3 +104,68 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) { render.Status(r, http.StatusOK) render.JSON(w, r, user) } + +func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) { + userID := chi.URLParam(r, "userID") + userID, err := url.PathUnescape(userID) + if err != nil { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed") + } + + if userID == "" { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id") + return + } + + err = g.identityBackend.DeleteUser(r.Context(), userID) + + if err != nil { + var errcode errorcode.Error + if errors.As(err, &errcode) { + errcode.Render(w, r) + } else { + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) + } + } + render.Status(r, http.StatusNoContent) + render.NoContent(w, r) +} + +// PatchUser implements the Service Interface. Updates the specified attributes of an +// ExistingUser +func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) { + nameOrID := chi.URLParam(r, "userID") + nameOrID, err := url.PathUnescape(nameOrID) + if err != nil { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed") + } + + if nameOrID == "" { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id") + return + } + changes := libregraph.NewUser() + err = json.NewDecoder(r.Body).Decode(changes) + if err != nil { + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error()) + return + } + + u, err := g.identityBackend.UpdateUser(r.Context(), nameOrID, *changes) + if err != nil { + var errcode errorcode.Error + if errors.As(err, &errcode) { + errcode.Render(w, r) + } else { + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) + } + } + + render.Status(r, http.StatusOK) + render.JSON(w, r, u) + +} + +func isNilOrEmpty(s *string) bool { + return s == nil || *s == "" +} diff --git a/graph/templates/CONFIGURATION.tmpl b/graph/templates/CONFIGURATION.tmpl deleted file mode 100644 index 24c1c4a99..000000000 --- a/graph/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/graph/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/graph/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "graph" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `graph [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "graph" -}} -### graph {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `graph {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/idp/templates/CONFIGURATION.tmpl b/idp/templates/CONFIGURATION.tmpl deleted file mode 100644 index a2fbcdad1..000000000 --- a/idp/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/idp/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-idp reads `idp.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/idp/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "idp" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `idp [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "idp" -}} -### idp {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `idp {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/ocis/templates/CONFIGURATION.tmpl b/ocis/templates/CONFIGURATION.tmpl deleted file mode 100644 index 465d32e27..000000000 --- a/ocis/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 2 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/ocis/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -oCIS Single Binary is not responsible for configuring extensions. Instead, each extension could either be configured by environment variables, cli flags or config files. - -Each extension has its dedicated documentation page (e.g. [proxy configuration]({{"{{"}}< relref "../extensions/accounts/configuration.md" >{{"}}"}})) which lists all possible configurations. Config files and environment variables are picked up if you use the `./bin/ocis server` command within the oCIS single binary. Command line flags must be set explicitly on the extensions subcommands. - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/ocis/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "ocis" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `ocis [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if eq $c.Name "server" "health" "kill" "list" "run" -}} -{{- if ne $c.FnName "Simple" -}} -### ocis {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `ocis {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} - -### List of available Extension subcommands - -There are more subcommands to start the individual extensions. Please check the documentation about their usage and options in the dedicated section of the documentation. - -{{ range $com := .Commands }}{{ with $com -}} -{{ if and (ne .Name "health") (ne .Name "server") (ne .Name "ocis") (ne .Name "kill") (ne .Name "list") (ne .Name "run") -}} -#### ocis {{ .Name }} - -{{ .Usage }} - -{{ end -}} -{{- end -}} -{{- end -}} diff --git a/ocs/templates/CONFIGURATION.tmpl b/ocs/templates/CONFIGURATION.tmpl deleted file mode 100644 index 5b58de073..000000000 --- a/ocs/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/ocs/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-ocs reads `ocs.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/ocs/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "ocs" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `ocs [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "ocs" -}} -### ocs {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `ocs {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/proxy/templates/CONFIGURATION.tmpl b/proxy/templates/CONFIGURATION.tmpl deleted file mode 100644 index b944a5892..000000000 --- a/proxy/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/proxy/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/proxy/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "proxy" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `proxy [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "proxy" -}} -### proxy {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `proxy {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/settings/templates/CONFIGURATION.tmpl b/settings/templates/CONFIGURATION.tmpl deleted file mode 100644 index 0bbef699e..000000000 --- a/settings/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/settings/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/settings/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "settings" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `settings [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "settings" -}} -### settings {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `settings {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/storage/pkg/command/frontend.go b/storage/pkg/command/frontend.go index e96d2c147..81eb0a268 100644 --- a/storage/pkg/command/frontend.go +++ b/storage/pkg/command/frontend.go @@ -294,7 +294,7 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s }, "spaces": map[string]interface{}{ "version": "0.0.1", - "enabled": true, + "enabled": cfg.Reva.Frontend.ProjectSpaces, }, }, "version": map[string]interface{}{ diff --git a/storage/pkg/config/config.go b/storage/pkg/config/config.go index 6cd62c35d..a2c738bfc 100644 --- a/storage/pkg/config/config.go +++ b/storage/pkg/config/config.go @@ -155,6 +155,7 @@ type FrontendPort struct { ArchiverPrefix string `ocisConfig:"archiver_prefix"` DatagatewayPrefix string `ocisConfig:"data_gateway_prefix"` Favorites bool `ocisConfig:"favorites"` + ProjectSpaces bool `ocisConfig:"project_spaces"` OCDavInsecure bool `ocisConfig:"ocdav_insecure"` OCDavPrefix string `ocisConfig:"ocdav_prefix"` OCSPrefix string `ocisConfig:"ocs_prefix"` @@ -815,6 +816,10 @@ func structMappings(cfg *Config) []shared.EnvBinding { EnvVars: []string{"STORAGE_FRONTEND_FAVORITES"}, Destination: &cfg.Reva.Frontend.Favorites, }, + { + EnvVars: []string{"STORAGE_FRONTEND_PROJECT_SPACES"}, + Destination: &cfg.Reva.Frontend.ProjectSpaces, + }, { EnvVars: []string{"STORAGE_FRONTEND_OCDAV_PREFIX"}, Destination: &cfg.Reva.Frontend.OCDavPrefix, diff --git a/storage/pkg/config/defaultconfig.go b/storage/pkg/config/defaultconfig.go index 0f266d4d6..23602bbf1 100644 --- a/storage/pkg/config/defaultconfig.go +++ b/storage/pkg/config/defaultconfig.go @@ -239,6 +239,7 @@ func DefaultConfig() *Config { ArchiverPrefix: "archiver", DatagatewayPrefix: "data", Favorites: false, + ProjectSpaces: true, OCDavInsecure: false, // true? OCDavPrefix: "", OCSPrefix: "ocs", diff --git a/storage/templates/CONFIGURATION.tmpl b/storage/templates/CONFIGURATION.tmpl deleted file mode 100644 index ad41b82c7..000000000 --- a/storage/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/storage/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} -{{- define "option"}} -{{- $options := first . }} -{{- $oName := last . }} -{{- range $o := $options }}{{ with (list $o $oName) -}} -{{- $o := first . }} -{{- if eq $o.FnName (last .) -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{- end -}} -{{- end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/storage/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "storage" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `storage [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "ocis-reva" -}} -### storage {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `storage {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} -## Config for the different Storage Drivers - -You can set different storage drivers for the Storage Providers. Please check the storage provider configuration. - -Example: Set the home and users Storage Provider to `ocis` - -`STORAGE_HOME_DRIVER=ocis` -`STORAGE_USERS_DRIVER=ocis` - -### Local Driver - -{{ template "option" (list .Options "DriverLocalWithConfig") -}} - -### Eos Driver - -{{ template "option" (list .Options "DriverEOSWithConfig") -}} - -### owCloud Driver - -{{ template "option" (list .Options "DriverOwnCloudWithConfig") -}} - -### ownCloudSQL Driver - -{{ template "option" (list .Options "DriverOwnCloudSQLWithConfig") -}} - -### Ocis Driver - -{{ template "option" (list .Options "DriverOCISWithConfig") -}} - -### S3ng Driver - -{{ template "option" (list .Options "DriverS3NGWithConfig") -}} diff --git a/store/templates/CONFIGURATION.tmpl b/store/templates/CONFIGURATION.tmpl deleted file mode 100644 index b783d239b..000000000 --- a/store/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/store/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/store/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "store" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `store [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "store" -}} -### store {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `store {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/tests/acceptance/docker/src/ocis-base.yml b/tests/acceptance/docker/src/ocis-base.yml index 837921b58..94e26e0cd 100644 --- a/tests/acceptance/docker/src/ocis-base.yml +++ b/tests/acceptance/docker/src/ocis-base.yml @@ -4,7 +4,6 @@ services: user: root environment: OCIS_URL: "https://ocis-server:9200" - STORAGE_HOME_DRIVER: $STORAGE_DRIVER STORAGE_USERS_DRIVER: $STORAGE_DRIVER STORAGE_USERS_DRIVER_LOCAL_ROOT: /srv/app/tmp/ocis/local/root STORAGE_USERS_DRIVER_OWNCLOUD_DATADIR: /srv/app/tmp/ocis/owncloud/data diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md index f56635878..caf82fa29 100644 --- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md @@ -34,6 +34,8 @@ _ocdav: double check the webdav property parsing when custom namespaces are used - [apiVersions/fileVersionAuthor.feature:101](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionAuthor.feature:#L101) - [apiVersions/fileVersionAuthor.feature:128](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionAuthor.feature:#L128) - [apiVersions/fileVersionAuthor.feature:155](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionAuthor.feature:#L155) +- [apiVersions/fileVersionAuthor.feature:180](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionAuthor.feature:#L180) +- [apiVersions/fileVersionAuthor.feature:220](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiVersions/fileVersionAuthor.feature:#L220) ### Sync Synchronization features like etag propagation, setting mtime and locking files diff --git a/tests/acceptance/features/apiSpaces/listSpaces.feature b/tests/acceptance/features/apiSpaces/listSpaces.feature index 8705184e3..175c562cc 100644 --- a/tests/acceptance/features/apiSpaces/listSpaces.feature +++ b/tests/acceptance/features/apiSpaces/listSpaces.feature @@ -19,6 +19,31 @@ Feature: List and create spaces | name | Alice Hansen | | quota@@@state | normal | | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | + And the json responded should contain a space "Shares Jail" with these key and value pairs: + | key | value | + | driveType | virtual | + | id | %space_id% | + | name | Shares Jail | + | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | + + Scenario: An ordinary user can request information about their Space via the Graph API using a filter + When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'personal'" + Then the HTTP status code should be "200" + And the json responded should contain a space "Alice Hansen" with these key and value pairs: + | key | value | + | driveType | personal | + | id | %space_id% | + | name | Alice Hansen | + | quota@@@state | normal | + | root@@@webDavUrl | %base_url%/dav/spaces/%space_id% | + And the json responded should not contain a space with name "Shares Jail" + And the json responded should only contain spaces of type "personal" + + Scenario: An ordinary user will not see any space when using a filter for project + When user "Alice" lists all available spaces via the GraphApi with query "$filter=driveType eq 'project'" + Then the HTTP status code should be "200" + And the json responded should not contain a space with name "Alice Hansen" + And the json responded should not contain spaces of type "personal" Scenario: An ordinary user can access their Space via the webDav API When user "Alice" lists all available spaces via the GraphApi diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 7de32c7e3..c5d5a220a 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -350,6 +350,26 @@ class SpacesContext implements Context { $this->rememberTheAvailableSpaces(); } + /** + * @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/ + * + * @param string $user + * @param string $query + * + * @return void + * + * @throws GuzzleException + */ + public function theUserListsAllHisAvailableSpacesUsingTheGraphApiWithFilter(string $user, string $query): void { + $this->featureContext->setResponse( + $this->listSpacesRequest( + $user, + $this->featureContext->getPasswordForUser($user), + "?". $query + ) + ); + } + /** * @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with the default quota using the GraphApi$/ * @@ -659,7 +679,7 @@ class SpacesContext implements Context { } /** - * @Then /^the json responded should not contain a space "([^"]*)"$/ + * @Then /^the json responded should not contain a space with name "([^"]*)"$/ * * @param string $spaceName * @@ -672,6 +692,45 @@ class SpacesContext implements Context { Assert::assertEmpty($this->getSpaceByNameFromResponse($spaceName), "space $spaceName should not be available for a user"); } + /** + * @Then /^the json responded should (not|only|)\s?contain spaces of type "([^"]*)"$/ + * + * @param string $shoulOrNot (not|only|) + * @param string $type + * + * @return void + * @throws Exception + */ + public function jsonRespondedShouldNotContainSpaceType( + string $onlyOrNot, + string $type + ): void { + Assert::assertNotEmpty( + $spaces = json_decode( + (string)$this->featureContext + ->getResponse()->getBody(), + true, + 512, + JSON_THROW_ON_ERROR + ) + ); + $matches = []; + foreach($spaces["value"] as $space) { + if($onlyOrNot === "not") { + Assert::assertNotEquals($space["driveType"], $type); + } + if($onlyOrNot === "only") { + Assert::assertEquals($space["driveType"], $type); + } + if($onlyOrNot === "" && $space["driveType"] === $type) { + $matches[] = $space; + } + } + if($onlyOrNot === "") { + Assert::assertNotEmpty($matches); + } + } + /** * @param string $shouldOrNot (not|) * @param TableNode $expectedFiles diff --git a/thumbnails/templates/CONFIGURATION.tmpl b/thumbnails/templates/CONFIGURATION.tmpl deleted file mode 100644 index 02a7f7843..000000000 --- a/thumbnails/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/thumbnails/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/thumbnails/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "thumbnails" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `thumbnails [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "thumbnails" -}} -### thumbnails {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `thumbnails {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/web/templates/CONFIGURATION.tmpl b/web/templates/CONFIGURATION.tmpl deleted file mode 100644 index 066be9045..000000000 --- a/web/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/web/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-web reads `web.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/web/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "web" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `web [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "web" -}} -### web {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `web {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}} diff --git a/webdav/templates/CONFIGURATION.tmpl b/webdav/templates/CONFIGURATION.tmpl deleted file mode 100644 index 6533998dc..000000000 --- a/webdav/templates/CONFIGURATION.tmpl +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Configuration" -date: "{{ date "2006-01-02T15:04:05-0700" now }}" -weight: 20 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/webdav/templates -geekdocFilePath: CONFIGURATION.tmpl ---- -{{- define "options"}} -{{ $fnNames := (last . ).Flags -}} -{{ range $opt := first . }} -{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}} -{{ $o := last . -}} -{{ if eq $o.FnName $fnName -}} --{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }} -: {{ $o.Usage }}. {{- if $o.Default }} Default: `{{ $o.Default }}`.{{ end }} - -{{ end -}} -{{ end -}} -{{ end -}} -{{ end -}} -{{ end }} - -{{`{{< toc >}}`}} - -## Configuration - -### Configuration using config files - -Out of the box extensions will attempt to read configuration details from: - -```console -/etc/ocis -$HOME/.ocis -./config -``` - -For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*. - -So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/webdav/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`. - -### Environment variables - -If you prefer to configure the service with environment variables you can see the available variables below. - -If multiple variables are listed for one option, they are in order of precedence. This means the leftmost variable will always win if given. - -### Command-line flags - -If you prefer to configure the service with command-line flags you can see the available variables below. Command line flags are only working when calling the subcommand directly. - -{{ $options := .Options -}} -{{ range $com := .Commands }}{{ with (list $options $com) -}} -{{ $c := last . -}} -{{ if eq $c.Name "webdav" -}} -## Root Command - -{{ $c.Usage }} - -Usage: `webdav [global options] command [command options] [arguments...]` -{{ template "options" . -}} -## Sub Commands - -{{ end -}} -{{ end -}} -{{ end -}} -{{- range $com := .Commands }}{{ with (list $options $com) -}} -{{- $c := last . }} -{{- if ne $c.Name "webdav" -}} -### webdav {{ $c.Name }} - -{{ $c.Usage }} - -Usage: `webdav {{ $c.Name }} [command options] [arguments...]` -{{ template "options" . }} -{{- end -}} -{{- end -}} -{{- end -}}