mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-06 16:26:52 -05:00
Merge branch 'master' into toggle-unified-roles
This commit is contained in:
142
.drone.star
142
.drone.star
@@ -154,6 +154,20 @@ config = {
|
||||
"OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE": "%s" % dirs["ocmProviders"],
|
||||
},
|
||||
},
|
||||
"apiWopi": {
|
||||
"suites": [
|
||||
"apiCollaboration",
|
||||
],
|
||||
"skip": False,
|
||||
"collaborationServiceNeeded": True,
|
||||
"extraCollaborationEnvironment": {
|
||||
"COLLABORATION_APP_NAME": "FakeOffice",
|
||||
"COLLABORATION_APP_ADDR": "http://fakeoffice:8080",
|
||||
},
|
||||
"extraServerEnvironment": {
|
||||
"GATEWAY_GRPC_ADDR": "0.0.0.0:9142",
|
||||
},
|
||||
},
|
||||
"cli": {
|
||||
"suites": [
|
||||
"cliCommands",
|
||||
@@ -855,6 +869,8 @@ def localApiTestPipeline(ctx):
|
||||
"antivirusNeeded": False,
|
||||
"tikaNeeded": False,
|
||||
"federationServer": False,
|
||||
"collaborationServiceNeeded": False,
|
||||
"extraCollaborationEnvironment": {},
|
||||
}
|
||||
|
||||
if "localApiTests" in config:
|
||||
@@ -880,9 +896,10 @@ def localApiTestPipeline(ctx):
|
||||
(waitForClamavService() if params["antivirusNeeded"] else []) +
|
||||
(waitForEmailService() if params["emailNeeded"] else []) +
|
||||
(ocisServer(storage, params["accounts_hash_difficulty"], deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"]) if params["federationServer"] else []) +
|
||||
(collaborationService(params["extraCollaborationEnvironment"]) if params["collaborationServiceNeeded"] else []) +
|
||||
localApiTests(suite, storage, params["extraEnvironment"]) +
|
||||
logRequests(),
|
||||
"services": emailService() if params["emailNeeded"] else [] + clamavService() if params["antivirusNeeded"] else [],
|
||||
"services": emailService() if params["emailNeeded"] else [] + clamavService() if params["antivirusNeeded"] else [] + fakeOffice() if params["collaborationServiceNeeded"] else [],
|
||||
"depends_on": getPipelineNames(buildOcisBinaryForTesting(ctx)),
|
||||
"trigger": {
|
||||
"ref": [
|
||||
@@ -987,38 +1004,25 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
|
||||
"/app/wopiserver.py",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "wait-for-wopi-server",
|
||||
"image": OC_CI_WAIT_FOR,
|
||||
"commands": [
|
||||
"wait-for -it wopiserver:9300 -t 300",
|
||||
],
|
||||
},
|
||||
]
|
||||
else:
|
||||
extra_server_environment = {
|
||||
"OCIS_EXCLUDE_RUN_SERVICES": "app-provider",
|
||||
}
|
||||
|
||||
wopiServer = [
|
||||
{
|
||||
"name": "wopiserver",
|
||||
"image": OC_CI_GOLANG,
|
||||
"detach": True,
|
||||
"environment": {
|
||||
"MICRO_REGISTRY": "nats-js-kv",
|
||||
"MICRO_REGISTRY_ADDRESS": "ocis-server:9233",
|
||||
"COLLABORATION_LOG_LEVEL": "debug",
|
||||
"COLLABORATION_HTTP_ADDR": "0.0.0.0:9300",
|
||||
"COLLABORATION_GRPC_ADDR": "0.0.0.0:9301",
|
||||
# no proof keys available in the FakeOffice
|
||||
"COLLABORATION_APP_PROOF_DISABLE": "true",
|
||||
"COLLABORATION_APP_NAME": "FakeOffice",
|
||||
"COLLABORATION_APP_ADDR": "http://fakeoffice:8080",
|
||||
"COLLABORATION_APP_INSECURE": "true",
|
||||
"COLLABORATION_WOPI_SRC": "http://wopiserver:9300",
|
||||
"COLLABORATION_WOPI_SECRET": "some-wopi-secret",
|
||||
"COLLABORATION_CS3API_DATAGATEWAY_INSECURE": "true",
|
||||
"OCIS_JWT_SECRET": "some-ocis-jwt-secret",
|
||||
},
|
||||
"commands": [
|
||||
"%s collaboration server" % ocis_bin,
|
||||
],
|
||||
},
|
||||
]
|
||||
extra_environment = {
|
||||
"COLLABORATION_APP_NAME": "FakeOffice",
|
||||
"COLLABORATION_APP_ADDR": "http://fakeoffice:8080",
|
||||
}
|
||||
|
||||
wopiServer = collaborationService(extra_environment)
|
||||
|
||||
wopiTestCases = dirs["base"] + "/tests/config/drone/wopiValidatorCustomTestCases.xml"
|
||||
for testgroup in testgroups:
|
||||
@@ -1063,34 +1067,10 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
|
||||
},
|
||||
"steps": skipIfUnchanged(ctx, "acceptance-tests") +
|
||||
restoreBuildArtifactCache(ctx, "ocis-binary-amd64", "ocis/bin") +
|
||||
[
|
||||
{
|
||||
"name": "fakeoffice",
|
||||
"image": OC_CI_ALPINE,
|
||||
"detach": True,
|
||||
"environment": {},
|
||||
"commands": [
|
||||
"sh %s/tests/config/drone/serve-hosting-discovery.sh" % (dirs["base"]),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "wait-for-fakeoffice",
|
||||
"image": OC_CI_WAIT_FOR,
|
||||
"commands": [
|
||||
"wait-for -it fakeoffice:8080 -t 300",
|
||||
],
|
||||
},
|
||||
] +
|
||||
fakeOffice() +
|
||||
ocisServer(storage, accounts_hash_difficulty, deploy_type = "wopi_validator", extra_server_environment = extra_server_environment) +
|
||||
wopiServer +
|
||||
[
|
||||
{
|
||||
"name": "wait-for-wopi-server",
|
||||
"image": OC_CI_WAIT_FOR,
|
||||
"commands": [
|
||||
"wait-for -it wopiserver:9300 -t 300",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "prepare-test-file",
|
||||
"image": OC_CI_ALPINE,
|
||||
@@ -2177,6 +2157,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on =
|
||||
"commands": [
|
||||
"%s init --insecure true" % ocis_bin,
|
||||
"cat $OCIS_CONFIG_DIR/ocis.yaml",
|
||||
"cp tests/config/drone/app-registry.yaml /root/.ocis/config/app-registry.yaml",
|
||||
] + (wrapper_commands),
|
||||
"volumes": volumes,
|
||||
"depends_on": depends_on,
|
||||
@@ -2895,6 +2876,63 @@ def waitForClamavService():
|
||||
],
|
||||
}]
|
||||
|
||||
def fakeOffice():
|
||||
return [
|
||||
{
|
||||
"name": "fakeoffice",
|
||||
"image": OC_CI_ALPINE,
|
||||
"detach": True,
|
||||
"environment": {},
|
||||
"commands": [
|
||||
"sh %s/tests/config/drone/serve-hosting-discovery.sh" % (dirs["base"]),
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "wait-for-fakeoffice",
|
||||
"image": OC_CI_WAIT_FOR,
|
||||
"commands": [
|
||||
"wait-for -it fakeoffice:8080 -t 300",
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
def collaborationService(extra_environment = {}):
|
||||
environment = {
|
||||
"MICRO_REGISTRY": "nats-js-kv",
|
||||
"MICRO_REGISTRY_ADDRESS": "ocis-server:9233",
|
||||
"COLLABORATION_LOG_LEVEL": "debug",
|
||||
"COLLABORATION_HTTP_ADDR": "0.0.0.0:9300",
|
||||
"COLLABORATION_GRPC_ADDR": "0.0.0.0:9301",
|
||||
"COLLABORATION_APP_PROOF_DISABLE": "true",
|
||||
"COLLABORATION_APP_INSECURE": "true",
|
||||
"COLLABORATION_WOPI_SRC": "http://wopiserver:9300",
|
||||
"COLLABORATION_WOPI_SECRET": "some-wopi-secret",
|
||||
"COLLABORATION_CS3API_DATAGATEWAY_INSECURE": "true",
|
||||
"OCIS_JWT_SECRET": "some-ocis-jwt-secret",
|
||||
}
|
||||
|
||||
for item in extra_environment:
|
||||
environment[item] = extra_environment[item]
|
||||
|
||||
return [
|
||||
{
|
||||
"name": "wopiserver",
|
||||
"image": OC_CI_GOLANG,
|
||||
"detach": True,
|
||||
"environment": environment,
|
||||
"commands": [
|
||||
"ocis/bin/ocis collaboration server",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "wait-for-wopi-server",
|
||||
"image": OC_CI_WAIT_FOR,
|
||||
"commands": [
|
||||
"wait-for -it wopiserver:9300 -t 300",
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
def tikaService():
|
||||
return [{
|
||||
"name": "tika",
|
||||
|
||||
85
CHANGELOG.md
85
CHANGELOG.md
@@ -56,6 +56,16 @@ The following sections list the changes for unreleased.
|
||||
* Bugfix - Set capability response `disable_self_password_change` correctly: [#9853](https://github.com/owncloud/ocis/pull/9853)
|
||||
* Bugfix - Activity Translations: [#9856](https://github.com/owncloud/ocis/pull/9856)
|
||||
* Bugfix - The user attributes `userType` and `memberOf` are readonly: [#9867](https://github.com/owncloud/ocis/pull/9867)
|
||||
* Bugfix - Use key to get specific trash item: [#9879](https://github.com/owncloud/ocis/pull/9879)
|
||||
* Bugfix - Fix response code when upload a file over locked: [#9894](https://github.com/owncloud/ocis/pull/9894)
|
||||
* Bugfix - List OCM permissions as graph drive item permissions: [#9905](https://github.com/owncloud/ocis/pull/9905)
|
||||
* Bugfix - Fix listing ocm shares: [#9925](https://github.com/owncloud/ocis/pull/9925)
|
||||
* Change - Remove store service: [#9890](https://github.com/owncloud/ocis/pull/9890)
|
||||
* Enhancement - We now set the configured protocol transport for service metadata: [#9490](https://github.com/owncloud/ocis/pull/9490)
|
||||
* Enhancement - Improve revisions purge: [#9891](https://github.com/owncloud/ocis/pull/9891)
|
||||
* Enhancement - Allow setting default locale of activitylog: [#9892](https://github.com/owncloud/ocis/pull/9892)
|
||||
* Enhancement - Graph translation path: [#9902](https://github.com/owncloud/ocis/pull/9902)
|
||||
* Enhancement - Bump reva: [#9920](https://github.com/owncloud/ocis/pull/9920)
|
||||
|
||||
## Details
|
||||
|
||||
@@ -81,6 +91,81 @@ The following sections list the changes for unreleased.
|
||||
https://github.com/owncloud/ocis/issues/9858
|
||||
https://github.com/owncloud/ocis/pull/9867
|
||||
|
||||
* Bugfix - Use key to get specific trash item: [#9879](https://github.com/owncloud/ocis/pull/9879)
|
||||
|
||||
The activitylog and clientlog services now only fetch the specific trash item
|
||||
instead of getting all items in trash and filtering them on their side. This
|
||||
reduces the load on the storage users service because it no longer has to
|
||||
assemble a full trash listing.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9879
|
||||
|
||||
* Bugfix - Fix response code when upload a file over locked: [#9894](https://github.com/owncloud/ocis/pull/9894)
|
||||
|
||||
We fixed a bug where the response code was incorrect when uploading a file over
|
||||
a locked file.
|
||||
|
||||
https://github.com/owncloud/ocis/issues/7638
|
||||
https://github.com/owncloud/ocis/pull/9894
|
||||
|
||||
* Bugfix - List OCM permissions as graph drive item permissions: [#9905](https://github.com/owncloud/ocis/pull/9905)
|
||||
|
||||
The libre graph API now returns OCM shares when listing driveItem permissions.
|
||||
|
||||
https://github.com/owncloud/ocis/issues/9898
|
||||
https://github.com/owncloud/ocis/pull/9905
|
||||
|
||||
* Bugfix - Fix listing ocm shares: [#9925](https://github.com/owncloud/ocis/pull/9925)
|
||||
|
||||
The libre graph API now returns an etag, the role and the creation time for ocm
|
||||
shares. It also includes ocm shares in the sharedByMe endpoint.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9925
|
||||
https://github.com/owncloud/ocis/pull/9920
|
||||
|
||||
* Change - Remove store service: [#9890](https://github.com/owncloud/ocis/pull/9890)
|
||||
|
||||
We have removed the unused store service.
|
||||
|
||||
https://github.com/owncloud/ocis/issues/1357
|
||||
https://github.com/owncloud/ocis/pull/9890
|
||||
|
||||
* Enhancement - We now set the configured protocol transport for service metadata: [#9490](https://github.com/owncloud/ocis/pull/9490)
|
||||
|
||||
This allows configuring services to listan on `tcp` or `unix` sockets and
|
||||
clients to use the `dns`, `kubernetes` or `unix` protocol URIs instead of
|
||||
service names.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9490
|
||||
https://github.com/cs3org/reva/pull/4744
|
||||
|
||||
* Enhancement - Improve revisions purge: [#9891](https://github.com/owncloud/ocis/pull/9891)
|
||||
|
||||
The `revisions purge` command would time out on big spaces. We have improved
|
||||
performance by parallelizing the process.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9891
|
||||
|
||||
* Enhancement - Allow setting default locale of activitylog: [#9892](https://github.com/owncloud/ocis/pull/9892)
|
||||
|
||||
Allows setting the default locale via `OCIS_DEFAULT_LANGUAGE` envvar
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9892
|
||||
|
||||
* Enhancement - Graph translation path: [#9902](https://github.com/owncloud/ocis/pull/9902)
|
||||
|
||||
Add `GRAPH_TRANSLATION_PATH` envvar like in other l10n services
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9902
|
||||
|
||||
* Enhancement - Bump reva: [#9920](https://github.com/owncloud/ocis/pull/9920)
|
||||
|
||||
Bumps reva version
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9920
|
||||
https://github.com/owncloud/ocis/pull/9879
|
||||
https://github.com/owncloud/ocis/pull/9860
|
||||
|
||||
# Changelog for [6.3.0] (2024-08-20)
|
||||
|
||||
The following sections list the changes for 6.3.0.
|
||||
|
||||
3
Makefile
3
Makefile
@@ -57,7 +57,6 @@ OCIS_MODULES = \
|
||||
services/storage-publiclink \
|
||||
services/storage-shares \
|
||||
services/storage-users \
|
||||
services/store \
|
||||
services/thumbnails \
|
||||
services/userlog \
|
||||
services/users \
|
||||
@@ -221,7 +220,7 @@ go-coverage:
|
||||
|
||||
.PHONY: protobuf
|
||||
protobuf:
|
||||
@for mod in ./services/thumbnails ./services/store ./services/settings; do \
|
||||
@for mod in ./services/thumbnails ./services/settings; do \
|
||||
echo -n "% protobuf $$mod: "; $(MAKE) --no-print-directory -C $$mod protobuf || exit 1; \
|
||||
done
|
||||
|
||||
|
||||
7
changelog/unreleased/bump-reva.md
Normal file
7
changelog/unreleased/bump-reva.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Enhancement: Bump reva
|
||||
|
||||
Bumps reva version
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9920
|
||||
https://github.com/owncloud/ocis/pull/9879
|
||||
https://github.com/owncloud/ocis/pull/9860
|
||||
5
changelog/unreleased/default-locale-activitylog.md
Normal file
5
changelog/unreleased/default-locale-activitylog.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Allow setting default locale of activitylog
|
||||
|
||||
Allows setting the default locale via `OCIS_DEFAULT_LANGUAGE` envvar
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9892
|
||||
6
changelog/unreleased/fix-upload-response-code.md
Normal file
6
changelog/unreleased/fix-upload-response-code.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Bugfix: Fix response code when upload a file over locked
|
||||
|
||||
We fixed a bug where the response code was incorrect when uploading a file over a locked file.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9894
|
||||
https://github.com/owncloud/ocis/issues/7638
|
||||
5
changelog/unreleased/graph-translation-path.md
Normal file
5
changelog/unreleased/graph-translation-path.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Graph translation path
|
||||
|
||||
Add `GRAPH_TRANSLATION_PATH` envvar like in other l10n services
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9902
|
||||
5
changelog/unreleased/improve-revisions-purge.md
Normal file
5
changelog/unreleased/improve-revisions-purge.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Improve revisions purge
|
||||
|
||||
The `revisions purge` command would time out on big spaces. We have improved performance by parallelizing the process.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9891
|
||||
6
changelog/unreleased/list-ocm-permissions.md
Normal file
6
changelog/unreleased/list-ocm-permissions.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Bugfix: List OCM permissions as graph drive item permissions
|
||||
|
||||
The libre graph API now returns OCM shares when listing driveItem permissions.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9905
|
||||
https://github.com/owncloud/ocis/issues/9898
|
||||
7
changelog/unreleased/ocm-listing-fixes.md
Normal file
7
changelog/unreleased/ocm-listing-fixes.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Bugfix: fix listing ocm shares
|
||||
|
||||
The libre graph API now returns an etag, the role and the creation time for ocm shares.
|
||||
It also includes ocm shares in the sharedByMe endpoint.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9925
|
||||
https://github.com/owncloud/ocis/pull/9920
|
||||
6
changelog/unreleased/remove-store-service.md
Normal file
6
changelog/unreleased/remove-store-service.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Change: Remove store service
|
||||
|
||||
We have removed the unused store service.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9890
|
||||
https://github.com/owncloud/ocis/issues/1357
|
||||
6
changelog/unreleased/set-service-transport.md
Normal file
6
changelog/unreleased/set-service-transport.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Enhancement: We now set the configured protocol transport for service metadata
|
||||
|
||||
This allows configuring services to listan on `tcp` or `unix` sockets and clients to use the `dns`, `kubernetes` or `unix` protocol URIs instead of service names.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9490
|
||||
https://github.com/cs3org/reva/pull/4744
|
||||
@@ -0,0 +1,5 @@
|
||||
Bugfix: Use key to get specific trash item
|
||||
|
||||
The activitylog and clientlog services now only fetch the specific trash item instead of getting all items in trash and filtering them on their side. This reduces the load on the storage users service because it no longer has to assemble a full trash listing.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/9879
|
||||
@@ -274,6 +274,17 @@ ACTIVITYLOG_TRACING_TYPE:
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
ACTIVITYLOG_TRANSLATION_PATH:
|
||||
name: OCIS_TRANSLATION_PATH;ACTIVITYLOG_TRANSLATION_PATH
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: (optional) Set this to a path with custom translations to overwrite
|
||||
the builtin translations. Note that file and folder naming rules apply, see the
|
||||
documentation for more details.
|
||||
introductionVersion: '%%NEXT%%'
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
ACTIVITYOG_SERVICE_ACCOUNT_SECRET:
|
||||
name: OCIS_SERVICE_ACCOUNT_SECRET;ACTIVITYOG_SERVICE_ACCOUNT_SECRET
|
||||
defaultValue: ""
|
||||
@@ -7711,28 +7722,28 @@ OCIS_ASYNC_UPLOADS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_AUTH_PASSWORD:
|
||||
name: OCIS_CACHE_AUTH_PASSWORD;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_AUTH_PASSWORD
|
||||
name: OCIS_CACHE_AUTH_PASSWORD;FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to authenticate with the store. Only applies when store
|
||||
type 'nats-js-kv' is configured.
|
||||
description: The password to use for authentication. Only applies when using the
|
||||
'nats-js-kv' store type.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_AUTH_USERNAME:
|
||||
name: OCIS_CACHE_AUTH_USERNAME;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_AUTH_USERNAME
|
||||
name: OCIS_CACHE_AUTH_USERNAME;FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to authenticate with the store. Only applies when store
|
||||
type 'nats-js-kv' is configured.
|
||||
description: The username to use for authentication. Only applies when using the
|
||||
'nats-js-kv' store type.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_DATABASE:
|
||||
name: OCIS_CACHE_DATABASE
|
||||
defaultValue: cache-userinfo
|
||||
defaultValue: cache-stat
|
||||
type: string
|
||||
description: The database name the configured store should use.
|
||||
introductionVersion: pre5.0
|
||||
@@ -7740,61 +7751,60 @@ OCIS_CACHE_DATABASE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_DISABLE_PERSISTENCE:
|
||||
name: OCIS_CACHE_DISABLE_PERSISTENCE;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_DISABLE_PERSISTENCE
|
||||
defaultValue: "true"
|
||||
name: OCIS_CACHE_DISABLE_PERSISTENCE;FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Disables persistence of the store. Only applies when store type 'nats-js-kv'
|
||||
is configured. Defaults to true.
|
||||
description: Disable persistence of the cache. Only applies when using the 'nats-js-kv'
|
||||
store type. Defaults to false.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_SIZE:
|
||||
name: OCIS_CACHE_SIZE;PROXY_OIDC_USERINFO_CACHE_SIZE
|
||||
name: OCIS_CACHE_SIZE;FRONTEND_OCS_STAT_CACHE_SIZE
|
||||
defaultValue: "0"
|
||||
type: int
|
||||
description: The maximum quantity of items in the user info cache. Only applies
|
||||
when store type 'ocmem' is configured. Defaults to 512 which is derived from the
|
||||
ocmem package though not explicitly set as default.
|
||||
description: Max number of entries to hold in the cache.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_STORE:
|
||||
name: OCIS_CACHE_STORE;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE
|
||||
defaultValue: nats-js-kv
|
||||
name: OCIS_CACHE_STORE;FRONTEND_OCS_STAT_CACHE_STORE
|
||||
defaultValue: memory
|
||||
type: string
|
||||
description: 'The type of the signing key store. Supported values are: ''redis-sentinel'',
|
||||
''nats-js-kv'' and ''ocisstoreservice'' (deprecated). See the text description
|
||||
for details.'
|
||||
introductionVersion: "5.0"
|
||||
description: 'The type of the cache store. Supported values are: ''memory'', ''redis-sentinel'',
|
||||
''nats-js-kv'', ''noop''. See the text description for details.'
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_STORE_NODES:
|
||||
name: OCIS_CACHE_STORE_NODES;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_NODES
|
||||
name: OCIS_CACHE_STORE_NODES;FRONTEND_OCS_STAT_CACHE_STORE_NODES
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. Note that the behaviour
|
||||
how nodes are used is dependent on the library of the configured store. See the
|
||||
Environment Variable Types description for more details.
|
||||
introductionVersion: "5.0"
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
are used is dependent on the library of the configured store. See the Environment
|
||||
Variable Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CACHE_TTL:
|
||||
name: OCIS_CACHE_TTL;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_TTL
|
||||
defaultValue: 12h0m0s
|
||||
name: OCIS_CACHE_TTL;FRONTEND_OCS_STAT_CACHE_TTL
|
||||
defaultValue: 5m0s
|
||||
type: Duration
|
||||
description: Default time to live for signing keys. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: "5.0"
|
||||
description: Default time to live for user info in the cache. Only applied when
|
||||
access tokens has no expiration. See the Environment Variable Types description
|
||||
for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_CREDENTIALS:
|
||||
name: OCIS_CORS_ALLOW_CREDENTIALS;USERLOG_CORS_ALLOW_CREDENTIALS
|
||||
defaultValue: "true"
|
||||
name: OCIS_CORS_ALLOW_CREDENTIALS;FRONTEND_CORS_ALLOW_CREDENTIALS
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: 'Allow credentials for CORS.See following chapter for more details:
|
||||
*Access-Control-Allow-Credentials* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials.'
|
||||
@@ -7803,9 +7813,11 @@ OCIS_CORS_ALLOW_CREDENTIALS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_HEADERS:
|
||||
name: OCIS_CORS_ALLOW_HEADERS;USERLOG_CORS_ALLOW_HEADERS
|
||||
defaultValue: '[Authorization Origin Content-Type Accept X-Requested-With X-Request-Id
|
||||
Ocs-Apirequest]'
|
||||
name: OCIS_CORS_ALLOW_HEADERS;FRONTEND_CORS_ALLOW_HEADERS
|
||||
defaultValue: '[Origin Accept Content-Type Depth Authorization Ocs-Apirequest If-None-Match
|
||||
If-Match Destination Overwrite X-Request-Id X-Requested-With Tus-Resumable Tus-Checksum-Algorithm
|
||||
Upload-Concat Upload-Length Upload-Metadata Upload-Defer-Length Upload-Expires
|
||||
Upload-Checksum Upload-Offset X-HTTP-Method-Override Cache-Control]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS headers. See following chapter for more details:
|
||||
*Access-Control-Request-Headers* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers.
|
||||
@@ -7815,8 +7827,9 @@ OCIS_CORS_ALLOW_HEADERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_METHODS:
|
||||
name: OCIS_CORS_ALLOW_METHODS;USERLOG_CORS_ALLOW_METHODS
|
||||
defaultValue: '[GET]'
|
||||
name: OCIS_CORS_ALLOW_METHODS;FRONTEND_CORS_ALLOW_METHODS
|
||||
defaultValue: '[OPTIONS HEAD GET PUT POST PATCH DELETE MKCOL PROPFIND PROPPATCH
|
||||
MOVE COPY REPORT SEARCH]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS methods. See following chapter for more details:
|
||||
*Access-Control-Request-Method* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method.
|
||||
@@ -7826,8 +7839,8 @@ OCIS_CORS_ALLOW_METHODS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_CORS_ALLOW_ORIGINS:
|
||||
name: OCIS_CORS_ALLOW_ORIGINS;USERLOG_CORS_ALLOW_ORIGINS
|
||||
defaultValue: '[*]'
|
||||
name: OCIS_CORS_ALLOW_ORIGINS;FRONTEND_CORS_ALLOW_ORIGINS
|
||||
defaultValue: '[https://localhost:9200]'
|
||||
type: '[]string'
|
||||
description: 'A list of allowed CORS origins. See following chapter for more details:
|
||||
*Access-Control-Allow-Origin* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin.
|
||||
@@ -7933,7 +7946,7 @@ OCIS_DISABLE_VERSIONING:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EDITION:
|
||||
name: OCIS_EDITION;OCDAV_EDITION
|
||||
name: OCIS_EDITION;FRONTEND_EDITION
|
||||
defaultValue: Community
|
||||
type: string
|
||||
description: Edition of oCIS. Used for branding purposes.
|
||||
@@ -7951,10 +7964,10 @@ OCIS_EMAIL_TEMPLATE_PATH:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_ENABLE_OCM:
|
||||
name: OCIS_ENABLE_OCM;GRAPH_INCLUDE_OCM_SHAREES
|
||||
name: OCIS_ENABLE_OCM;FRONTEND_OCS_INCLUDE_OCM_SHAREES
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Include OCM sharees when listing users.
|
||||
description: Include OCM sharees when listing sharees.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -7970,7 +7983,7 @@ OCIS_ENABLE_RESHARING:
|
||||
removalVersion: ""
|
||||
deprecationInfo: Resharing will be removed in the future.
|
||||
OCIS_EVENTS_AUTH_PASSWORD:
|
||||
name: OCIS_EVENTS_AUTH_PASSWORD;USERLOG_EVENTS_AUTH_PASSWORD
|
||||
name: OCIS_EVENTS_AUTH_PASSWORD;FRONTEND_EVENTS_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to authenticate with the events broker. The events broker
|
||||
@@ -7980,7 +7993,7 @@ OCIS_EVENTS_AUTH_PASSWORD:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_AUTH_USERNAME:
|
||||
name: OCIS_EVENTS_AUTH_USERNAME;USERLOG_EVENTS_AUTH_USERNAME
|
||||
name: OCIS_EVENTS_AUTH_USERNAME;FRONTEND_EVENTS_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to authenticate with the events broker. The events broker
|
||||
@@ -7990,18 +8003,18 @@ OCIS_EVENTS_AUTH_USERNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_CLUSTER:
|
||||
name: OCIS_EVENTS_CLUSTER;USERLOG_EVENTS_CLUSTER
|
||||
name: OCIS_EVENTS_CLUSTER;FRONTEND_EVENTS_CLUSTER
|
||||
defaultValue: ocis-cluster
|
||||
type: string
|
||||
description: The clusterID of the event system. The event system is the message
|
||||
queuing service. It is used as message broker for the microservice architecture.
|
||||
Mandatory when using NATS as event system.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_ENABLE_TLS:
|
||||
name: OCIS_EVENTS_ENABLE_TLS;USERLOG_EVENTS_ENABLE_TLS
|
||||
name: OCIS_EVENTS_ENABLE_TLS;NATS_EVENTS_ENABLE_TLS
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Enable TLS for the connection to the events broker. The events broker
|
||||
@@ -8011,31 +8024,31 @@ OCIS_EVENTS_ENABLE_TLS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_ENDPOINT:
|
||||
name: OCIS_EVENTS_ENDPOINT;USERLOG_EVENTS_ENDPOINT
|
||||
name: OCIS_EVENTS_ENDPOINT;FRONTEND_EVENTS_ENDPOINT
|
||||
defaultValue: 127.0.0.1:9233
|
||||
type: string
|
||||
description: The address of the event system. The event system is the message queuing
|
||||
service. It is used as message broker for the microservice architecture.
|
||||
introductionVersion: pre5.0
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE:
|
||||
name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE;USERLOG_EVENTS_TLS_ROOT_CA_CERTIFICATE
|
||||
name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE;ANTIVIRUS_EVENTS_TLS_ROOT_CA_CERTIFICATE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The root CA certificate used to validate the server's TLS certificate.
|
||||
If provided NOTIFICATIONS_EVENTS_TLS_INSECURE will be seen as false.
|
||||
If provided ANTIVIRUS_EVENTS_TLS_INSECURE will be seen as false.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_GATEWAY_GRPC_ADDR:
|
||||
name: OCIS_GATEWAY_GRPC_ADDR;GATEWAY_GRPC_ADDR
|
||||
name: OCIS_GATEWAY_GRPC_ADDR;STORAGE_USERS_GATEWAY_GRPC_ADDR
|
||||
defaultValue: 127.0.0.1:9142
|
||||
type: string
|
||||
description: The bind address of the GRPC service.
|
||||
introductionVersion: pre5.0
|
||||
description: The bind address of the gateway GRPC address.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -8094,16 +8107,17 @@ OCIS_HTTP_TLS_KEY:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_INSECURE:
|
||||
name: OCIS_INSECURE;USERLOG_EVENTS_TLS_INSECURE
|
||||
name: OCIS_INSECURE;NATS_TLS_SKIP_VERIFY_CLIENT_CERT
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Whether to verify the server TLS certificates.
|
||||
description: Whether the NATS server should skip the client certificate verification
|
||||
during the TLS handshake.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_JWT_SECRET:
|
||||
name: OCIS_JWT_SECRET;USERLOG_JWT_SECRET
|
||||
name: OCIS_JWT_SECRET;GROUPS_JWT_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The secret to mint and validate jwt tokens.
|
||||
@@ -8112,7 +8126,7 @@ OCIS_JWT_SECRET:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_BASE_PATH:
|
||||
name: OCIS_KEYCLOAK_BASE_PATH;INVITATIONS_KEYCLOAK_BASE_PATH
|
||||
name: OCIS_KEYCLOAK_BASE_PATH;GRAPH_KEYCLOAK_BASE_PATH
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The URL to access keycloak.
|
||||
@@ -8121,16 +8135,16 @@ OCIS_KEYCLOAK_BASE_PATH:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_CLIENT_ID:
|
||||
name: OCIS_KEYCLOAK_CLIENT_ID;INVITATIONS_KEYCLOAK_CLIENT_ID
|
||||
name: OCIS_KEYCLOAK_CLIENT_ID;GRAPH_KEYCLOAK_CLIENT_ID
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The client ID to authenticate with keycloak.
|
||||
description: The client id to authenticate with keycloak.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_CLIENT_REALM:
|
||||
name: OCIS_KEYCLOAK_CLIENT_REALM;INVITATIONS_KEYCLOAK_CLIENT_REALM
|
||||
name: OCIS_KEYCLOAK_CLIENT_REALM;GRAPH_KEYCLOAK_CLIENT_REALM
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The realm the client is defined in.
|
||||
@@ -8139,7 +8153,7 @@ OCIS_KEYCLOAK_CLIENT_REALM:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_CLIENT_SECRET:
|
||||
name: OCIS_KEYCLOAK_CLIENT_SECRET;INVITATIONS_KEYCLOAK_CLIENT_SECRET
|
||||
name: OCIS_KEYCLOAK_CLIENT_SECRET;GRAPH_KEYCLOAK_CLIENT_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The client secret to use in authentication.
|
||||
@@ -8148,7 +8162,7 @@ OCIS_KEYCLOAK_CLIENT_SECRET:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY:
|
||||
name: OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY;INVITATIONS_KEYCLOAK_INSECURE_SKIP_VERIFY
|
||||
name: OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY;GRAPH_KEYCLOAK_INSECURE_SKIP_VERIFY
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Disable TLS certificate validation for Keycloak connections. Do not
|
||||
@@ -8158,7 +8172,7 @@ OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_KEYCLOAK_USER_REALM:
|
||||
name: OCIS_KEYCLOAK_USER_REALM;INVITATIONS_KEYCLOAK_USER_REALM
|
||||
name: OCIS_KEYCLOAK_USER_REALM;GRAPH_KEYCLOAK_USER_REALM
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The realm users are defined.
|
||||
@@ -8197,20 +8211,20 @@ OCIS_LDAP_CACERT:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_DISABLE_USER_MECHANISM:
|
||||
name: OCIS_LDAP_DISABLE_USER_MECHANISM;USERS_LDAP_DISABLE_USER_MECHANISM
|
||||
name: OCIS_LDAP_DISABLE_USER_MECHANISM;GRAPH_DISABLE_USER_MECHANISM
|
||||
defaultValue: attribute
|
||||
type: string
|
||||
description: An option to control the behavior for disabling users. Valid options
|
||||
description: An option to control the behavior for disabling users. Supported options
|
||||
are 'none', 'attribute' and 'group'. If set to 'group', disabling a user via API
|
||||
will add the user to the configured group for disabled users, if set to 'attribute'
|
||||
this will be done in the ldap user entry, if set to 'none' the disable request
|
||||
is not processed.
|
||||
is not processed. Default is 'attribute'.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_DISABLED_USERS_GROUP_DN:
|
||||
name: OCIS_LDAP_DISABLED_USERS_GROUP_DN;USERS_LDAP_DISABLED_USERS_GROUP_DN
|
||||
name: OCIS_LDAP_DISABLED_USERS_GROUP_DN;GRAPH_DISABLED_USERS_GROUP_DN
|
||||
defaultValue: cn=DisabledUsersGroup,ou=groups,o=libregraph-idm
|
||||
type: string
|
||||
description: The distinguished name of the group to which added users will be classified
|
||||
@@ -8326,7 +8340,7 @@ OCIS_LDAP_INSECURE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_SERVER_WRITE_ENABLED:
|
||||
name: OCIS_LDAP_SERVER_WRITE_ENABLED;GRAPH_LDAP_SERVER_WRITE_ENABLED
|
||||
name: OCIS_LDAP_SERVER_WRITE_ENABLED;FRONTEND_LDAP_SERVER_WRITE_ENABLED
|
||||
defaultValue: "true"
|
||||
type: bool
|
||||
description: Allow creating, modifying and deleting LDAP users via the GRAPH API.
|
||||
@@ -8357,10 +8371,10 @@ OCIS_LDAP_USER_BASE_DN:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_USER_ENABLED_ATTRIBUTE:
|
||||
name: OCIS_LDAP_USER_ENABLED_ATTRIBUTE;USERS_LDAP_USER_ENABLED_ATTRIBUTE
|
||||
name: OCIS_LDAP_USER_ENABLED_ATTRIBUTE;GRAPH_USER_ENABLED_ATTRIBUTE
|
||||
defaultValue: ownCloudUserEnabled
|
||||
type: string
|
||||
description: LDAP attribute to use as a flag telling if the user is enabled or disabled.
|
||||
description: LDAP Attribute to use as a flag telling if the user is enabled or disabled.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8424,7 +8438,7 @@ OCIS_LDAP_USER_SCHEMA_MAIL:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LDAP_USER_SCHEMA_USER_TYPE:
|
||||
name: OCIS_LDAP_USER_SCHEMA_USER_TYPE;USERS_LDAP_USER_TYPE_ATTRIBUTE
|
||||
name: OCIS_LDAP_USER_SCHEMA_USER_TYPE;GRAPH_LDAP_USER_TYPE_ATTRIBUTE
|
||||
defaultValue: ownCloudUserType
|
||||
type: string
|
||||
description: LDAP Attribute to distinguish between 'Member' and 'Guest' users. Default
|
||||
@@ -8453,7 +8467,7 @@ OCIS_LDAP_USER_SCOPE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_COLOR:
|
||||
name: OCIS_LOG_COLOR;USERLOG_LOG_COLOR
|
||||
name: OCIS_LOG_COLOR;NATS_LOG_COLOR
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates colorized log output.
|
||||
@@ -8462,7 +8476,7 @@ OCIS_LOG_COLOR:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_FILE:
|
||||
name: OCIS_LOG_FILE;USERLOG_LOG_FILE
|
||||
name: OCIS_LOG_FILE;NATS_LOG_FILE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The path to the log file. Activates logging to this file if set.
|
||||
@@ -8471,7 +8485,7 @@ OCIS_LOG_FILE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_LEVEL:
|
||||
name: OCIS_LOG_LEVEL;USERLOG_LOG_LEVEL
|
||||
name: OCIS_LOG_LEVEL;NATS_LOG_LEVEL
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: 'The log level. Valid values are: ''panic'', ''fatal'', ''error'',
|
||||
@@ -8481,7 +8495,7 @@ OCIS_LOG_LEVEL:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_LOG_PRETTY:
|
||||
name: OCIS_LOG_PRETTY;USERLOG_LOG_PRETTY
|
||||
name: OCIS_LOG_PRETTY;NATS_LOG_PRETTY
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates pretty log output.
|
||||
@@ -8490,11 +8504,11 @@ OCIS_LOG_PRETTY:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_MACHINE_AUTH_API_KEY:
|
||||
name: OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY
|
||||
name: OCIS_MACHINE_AUTH_API_KEY;FRONTEND_MACHINE_AUTH_API_KEY
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: Machine auth API key used to validate internal requests necessary to
|
||||
access resources from other services.
|
||||
description: The machine auth API key used to validate internal requests necessary
|
||||
to access resources from other services.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8511,16 +8525,17 @@ OCIS_OIDC_CLIENT_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_OIDC_ISSUER:
|
||||
name: OCIS_URL;OCIS_OIDC_ISSUER;PROXY_OIDC_ISSUER
|
||||
name: OCIS_URL;OCIS_OIDC_ISSUER;GROUPS_IDP_URL
|
||||
defaultValue: https://localhost:9200
|
||||
type: string
|
||||
description: URL of the OIDC issuer. It defaults to URL of the builtin IDP.
|
||||
description: The identity provider value to set in the group IDs of the CS3 group
|
||||
objects for groups returned by this group provider.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST:
|
||||
name: OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST;SHARING_PASSWORD_POLICY_BANNED_PASSWORDS_LIST
|
||||
name: OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST;FRONTEND_PASSWORD_POLICY_BANNED_PASSWORDS_LIST
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: Path to the 'banned passwords list' file. This only impacts public
|
||||
@@ -8530,7 +8545,7 @@ OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_DISABLED:
|
||||
name: OCIS_PASSWORD_POLICY_DISABLED;SHARING_PASSWORD_POLICY_DISABLED
|
||||
name: OCIS_PASSWORD_POLICY_DISABLED;FRONTEND_PASSWORD_POLICY_DISABLED
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Disable the password policy. Defaults to false if not set.
|
||||
@@ -8539,7 +8554,7 @@ OCIS_PASSWORD_POLICY_DISABLED:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_MIN_CHARACTERS:
|
||||
name: OCIS_PASSWORD_POLICY_MIN_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_CHARACTERS
|
||||
name: OCIS_PASSWORD_POLICY_MIN_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_CHARACTERS
|
||||
defaultValue: "8"
|
||||
type: int
|
||||
description: Define the minimum password length. Defaults to 8 if not set.
|
||||
@@ -8548,7 +8563,7 @@ OCIS_PASSWORD_POLICY_MIN_CHARACTERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_MIN_DIGITS:
|
||||
name: OCIS_PASSWORD_POLICY_MIN_DIGITS;SHARING_PASSWORD_POLICY_MIN_DIGITS
|
||||
name: OCIS_PASSWORD_POLICY_MIN_DIGITS;FRONTEND_PASSWORD_POLICY_MIN_DIGITS
|
||||
defaultValue: "1"
|
||||
type: int
|
||||
description: Define the minimum number of digits. Defaults to 1 if not set.
|
||||
@@ -8557,7 +8572,7 @@ OCIS_PASSWORD_POLICY_MIN_DIGITS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS:
|
||||
name: OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS
|
||||
name: OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS
|
||||
defaultValue: "1"
|
||||
type: int
|
||||
description: Define the minimum number of uppercase letters. Defaults to 1 if not
|
||||
@@ -8567,7 +8582,7 @@ OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS:
|
||||
name: OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS
|
||||
name: OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS
|
||||
defaultValue: "1"
|
||||
type: int
|
||||
description: Define the minimum number of characters from the special characters
|
||||
@@ -8577,7 +8592,7 @@ OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS:
|
||||
name: OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS
|
||||
name: OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS
|
||||
defaultValue: "1"
|
||||
type: int
|
||||
description: Define the minimum number of lowercase letters. Defaults to 1 if not
|
||||
@@ -8587,8 +8602,8 @@ OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE:
|
||||
name: OCIS_PERSISTENT_STORE;USERLOG_STORE
|
||||
defaultValue: memory
|
||||
name: OCIS_PERSISTENT_STORE;POSTPROCESSING_STORE
|
||||
defaultValue: nats-js-kv
|
||||
type: string
|
||||
description: 'The type of the store. Supported values are: ''memory'', ''ocmem'',
|
||||
''etcd'', ''redis'', ''redis-sentinel'', ''nats-js'', ''noop''. See the text description
|
||||
@@ -8598,7 +8613,7 @@ OCIS_PERSISTENT_STORE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_AUTH_PASSWORD:
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;USERLOG_STORE_AUTH_PASSWORD
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;POSTPROCESSING_STORE_AUTH_PASSWORD
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The password to authenticate with the store. Only applies when store
|
||||
@@ -8608,7 +8623,7 @@ OCIS_PERSISTENT_STORE_AUTH_PASSWORD:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_AUTH_USERNAME:
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;USERLOG_STORE_AUTH_USERNAME
|
||||
name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;POSTPROCESSING_STORE_AUTH_USERNAME
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The username to authenticate with the store. Only applies when store
|
||||
@@ -8618,8 +8633,8 @@ OCIS_PERSISTENT_STORE_AUTH_USERNAME:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_NODES:
|
||||
name: OCIS_PERSISTENT_STORE_NODES;USERLOG_STORE_NODES
|
||||
defaultValue: '[]'
|
||||
name: OCIS_PERSISTENT_STORE_NODES;POSTPROCESSING_STORE_NODES
|
||||
defaultValue: '[127.0.0.1:9233]'
|
||||
type: '[]string'
|
||||
description: A list of nodes to access the configured store. This has no effect
|
||||
when 'memory' or 'ocmem' stores are configured. Note that the behaviour how nodes
|
||||
@@ -8630,7 +8645,7 @@ OCIS_PERSISTENT_STORE_NODES:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_SIZE:
|
||||
name: OCIS_PERSISTENT_STORE_SIZE;USERLOG_STORE_SIZE
|
||||
name: OCIS_PERSISTENT_STORE_SIZE;POSTPROCESSING_STORE_SIZE
|
||||
defaultValue: "0"
|
||||
type: int
|
||||
description: The maximum quantity of items in the store. Only applies when store
|
||||
@@ -8641,11 +8656,11 @@ OCIS_PERSISTENT_STORE_SIZE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_PERSISTENT_STORE_TTL:
|
||||
name: OCIS_PERSISTENT_STORE_TTL;USERLOG_STORE_TTL
|
||||
defaultValue: 336h0m0s
|
||||
name: OCIS_PERSISTENT_STORE_TTL;POSTPROCESSING_STORE_TTL
|
||||
defaultValue: 0s
|
||||
type: Duration
|
||||
description: Time to live for events in the store. Defaults to '336h' (2 weeks).
|
||||
See the Environment Variable Types description for more details.
|
||||
description: Time to live for events in the store. See the Environment Variable
|
||||
Types description for more details.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8663,7 +8678,7 @@ OCIS_REVA_GATEWAY:
|
||||
name: OCIS_REVA_GATEWAY
|
||||
defaultValue: com.owncloud.api.gateway
|
||||
type: string
|
||||
description: CS3 gateway used to look up user metadata
|
||||
description: The CS3 gateway endpoint.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8691,7 +8706,7 @@ OCIS_REVA_GATEWAY_TLS_MODE:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SERVICE_ACCOUNT_ID:
|
||||
name: OCIS_SERVICE_ACCOUNT_ID;USERLOG_SERVICE_ACCOUNT_ID
|
||||
name: OCIS_SERVICE_ACCOUNT_ID;FRONTEND_SERVICE_ACCOUNT_ID
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The ID of the service account the service should use. See the 'auth-service'
|
||||
@@ -8701,7 +8716,7 @@ OCIS_SERVICE_ACCOUNT_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SERVICE_ACCOUNT_SECRET:
|
||||
name: OCIS_SERVICE_ACCOUNT_SECRET;USERLOG_SERVICE_ACCOUNT_SECRET
|
||||
name: OCIS_SERVICE_ACCOUNT_SECRET;FRONTEND_SERVICE_ACCOUNT_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The service account secret.
|
||||
@@ -8710,7 +8725,7 @@ OCIS_SERVICE_ACCOUNT_SECRET:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD:
|
||||
name: OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD;SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD
|
||||
name: OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD;FRONTEND_OCS_PUBLIC_SHARE_MUST_HAVE_PASSWORD
|
||||
defaultValue: "true"
|
||||
type: bool
|
||||
description: Set this to true if you want to enforce passwords on all public shares.
|
||||
@@ -8719,13 +8734,11 @@ OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD:
|
||||
name: OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD;SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD
|
||||
name: OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD;FRONTEND_OCS_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Set this to true if you want to enforce passwords on Uploader, Editor
|
||||
or Contributor shares. If not using the global OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD,
|
||||
you must define the FRONTEND_OCS_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD in
|
||||
the frontend service.
|
||||
description: Set this to true if you want to enforce passwords for writable shares.
|
||||
Only effective if the setting for 'passwords on all public shares' is set to false.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
@@ -8773,7 +8786,7 @@ OCIS_SYSTEM_USER_ID:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_SYSTEM_USER_IDP:
|
||||
name: OCIS_SYSTEM_USER_IDP;SETTINGS_SYSTEM_USER_IDP
|
||||
name: OCIS_SYSTEM_USER_IDP;SHARING_PUBLIC_CS3_SYSTEM_USER_IDP
|
||||
defaultValue: internal
|
||||
type: string
|
||||
description: IDP of the oCIS STORAGE-SYSTEM system user.
|
||||
@@ -8782,7 +8795,7 @@ OCIS_SYSTEM_USER_IDP:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_COLLECTOR:
|
||||
name: OCIS_TRACING_COLLECTOR;USERLOG_TRACING_COLLECTOR
|
||||
name: OCIS_TRACING_COLLECTOR;NATS_TRACING_COLLECTOR
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces.
|
||||
@@ -8792,7 +8805,7 @@ OCIS_TRACING_COLLECTOR:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_ENABLED:
|
||||
name: OCIS_TRACING_ENABLED;USERLOG_TRACING_ENABLED
|
||||
name: OCIS_TRACING_ENABLED;NATS_TRACING_ENABLED
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Activates tracing.
|
||||
@@ -8801,7 +8814,7 @@ OCIS_TRACING_ENABLED:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_ENDPOINT:
|
||||
name: OCIS_TRACING_ENDPOINT;USERLOG_TRACING_ENDPOINT
|
||||
name: OCIS_TRACING_ENDPOINT;NATS_TRACING_ENDPOINT
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The endpoint of the tracing agent.
|
||||
@@ -8810,7 +8823,7 @@ OCIS_TRACING_ENDPOINT:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRACING_TYPE:
|
||||
name: OCIS_TRACING_TYPE;USERLOG_TRACING_TYPE
|
||||
name: OCIS_TRACING_TYPE;NATS_TRACING_TYPE
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The type of tracing. Defaults to '', which is the same as 'jaeger'.
|
||||
@@ -8823,13 +8836,13 @@ OCIS_TRANSFER_SECRET:
|
||||
name: OCIS_TRANSFER_SECRET
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: The storage transfer secret.
|
||||
description: Transfer secret for signing file up- and download requests.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_TRANSLATION_PATH:
|
||||
name: OCIS_TRANSLATION_PATH;USERLOG_TRANSLATION_PATH
|
||||
name: OCIS_TRANSLATION_PATH;NOTIFICATIONS_TRANSLATION_PATH
|
||||
defaultValue: ""
|
||||
type: string
|
||||
description: (optional) Set this to a path with custom translations to overwrite
|
||||
@@ -8840,20 +8853,21 @@ OCIS_TRANSLATION_PATH:
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_URL:
|
||||
name: OCIS_URL;OCIS_OIDC_ISSUER;PROXY_OIDC_ISSUER
|
||||
name: OCIS_URL;OCIS_OIDC_ISSUER;GROUPS_IDP_URL
|
||||
defaultValue: https://localhost:9200
|
||||
type: string
|
||||
description: URL of the OIDC issuer. It defaults to URL of the builtin IDP.
|
||||
description: The identity provider value to set in the group IDs of the CS3 group
|
||||
objects for groups returned by this group provider.
|
||||
introductionVersion: pre5.0
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
OCIS_WOPI_DISABLE_CHAT:
|
||||
name: APP_PROVIDER_WOPI_DISABLE_CHAT;OCIS_WOPI_DISABLE_CHAT
|
||||
name: COLLABORATION_WOPI_DISABLE_CHAT;OCIS_WOPI_DISABLE_CHAT
|
||||
defaultValue: "false"
|
||||
type: bool
|
||||
description: Disable the chat functionality of the office app.
|
||||
introductionVersion: pre5.0
|
||||
description: Disable chat in the frontend.
|
||||
introductionVersion: '%%NEXT%%'
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
deprecationInfo: ""
|
||||
@@ -9103,8 +9117,8 @@ OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE:
|
||||
name: OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE
|
||||
defaultValue: /etc/ocis/ocmproviders.json
|
||||
type: string
|
||||
description: Path to the JSON file where ocm invite data will be stored. If not
|
||||
defined, the root directory derives from $OCIS_BASE_DATA_PATH:/storage.
|
||||
description: Path to the JSON file where ocm invite data will be stored. Defaults
|
||||
to $OCIS_CONFIG_DIR:/ocmproviders.json.
|
||||
introductionVersion: "5.0"
|
||||
deprecationVersion: ""
|
||||
removalVersion: ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Beta testplan"
|
||||
date: 2022-03-24T00:00:00+00:00
|
||||
weight: 37
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: beta-testplan.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Documentation"
|
||||
date: 2020-07-27T08:39:38+00:00
|
||||
weight: 99
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: build-docs.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Build"
|
||||
date: 2020-02-27T20:35:00+01:00
|
||||
weight: 30
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: build.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Continuous Integration"
|
||||
date: 2020-10-01T20:35:00+01:00
|
||||
weight: 100
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: continuous-integration.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Debugging"
|
||||
date: 2020-03-19T08:21:00+01:00
|
||||
weight: 50
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: debugging.md
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
title: "Deprecating Variables"
|
||||
date: 2022-11-29T15:41:00+01:00
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: deprecating-variables.md
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Deprecating Environment Variables
|
||||
|
||||
Sometimes it is necessary to deprecate environment to align their naming with conventions. We therefore added annotations to automate the documentation process. It is necessary to know when the variable is going to be deprecated, when it is going to be removed and why.
|
||||
|
||||
### Example
|
||||
|
||||
```golang
|
||||
// Notifications defines the config options for the notifications service.
|
||||
type Notifications struct {
|
||||
RevaGateway string `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY;REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" deprecationVersion:"3.0" removalVersion:"4.0.0" deprecationInfo:"REVA_GATEWAY changing name for consistency" deprecationReplacement:"OCIS_REVA_GATEWAY"`
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
There are four different annotation variables that need to be filled:
|
||||
|
||||
| Annotation |Description| Format|
|
||||
|---|---|---|
|
||||
| deprecationVersion | The version the variable will be deprecated | semver (e.g. 3.0)|
|
||||
| removalVersion| The version the variable will be removed from the codebase. Note that according to semver, a removal **MUST NOT** be made in a minor or patch version change, but only in a major release | semver (e.g. 4.0.0) |
|
||||
| deprecationInfo | Information why the variable is deprecated, must start with the name of the variable in order to avoid confusion, when there are multiple options in the `env:`-field | string (e.g. NATS_NATS_HOST is confusing) |
|
||||
| deprecationReplacement | The name of the variable that is going to replace the deprecated one.| string (e.g. NATS_HOST_ADDRESS) |
|
||||
|
||||
### What happens next?
|
||||
|
||||
Once a variable has been finally removed, the annotations must be removed again from the code, since they do not serve any purpose from this point.
|
||||
13
docs/ocis/development/envvars.md
Normal file
13
docs/ocis/development/envvars.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: "Environment Variables"
|
||||
date: 2024-08-22T15:41:00+01:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: envvars.md
|
||||
---
|
||||
|
||||
Environment variables are an essential part of configuring services.
|
||||
|
||||
If you are going to create new ones or deprecate existing ones, you must read the [Envvar Naming Scope]({{< ref "services/general-info/envvar-scopes.md" >}}) and the
|
||||
[Deprecating Variables]({{< ref "services/general-info/deprecating-variables.md" >}}) documentation for more details first before doing so.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Profiling"
|
||||
date: 2021-08-24T12:32:20+01:00
|
||||
weight: 56
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: profiling.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Acceptance Testing"
|
||||
date: 2018-05-02T00:00:00+00:00
|
||||
weight: 38
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development
|
||||
geekdocFilePath: testing.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Unit Testing"
|
||||
date: 2024-04-25T00:00:00+00:00
|
||||
weight: 5
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development/unit-testing
|
||||
geekdocFilePath: _index.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Standard Library Testing"
|
||||
date: 2024-04-25T00:00:00+00:00
|
||||
weight: 15
|
||||
weight: 10
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/ocis/development/unit-testing
|
||||
geekdocFilePath: testing-pkg.md
|
||||
|
||||
@@ -91,3 +91,6 @@ Translations have a `context` and a `translatable string`. The context is shown
|
||||
l10n-clean:
|
||||
rm -f $(TEMPLATE_FILE);
|
||||
```
|
||||
|
||||
* Add Description Text to README\
|
||||
Add the full `Translations` and `Default Language` text blocks including their sub sections to the service readme. You can derive from the `activitylog` or `userlog` service for easy copy/paste.
|
||||
|
||||
54
docs/services/general-info/deprecating-variables.md
Normal file
54
docs/services/general-info/deprecating-variables.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: "Envvar Deprecation"
|
||||
date: 2024-08-22T15:41:00+01:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/general-info
|
||||
geekdocFilePath: deprecating-variables.md
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Deprecating Environment Variables
|
||||
|
||||
Sometimes it is necessary to deprecate an environment variable to align the naming with conventions or remove it completely. We therefore added annotations to automate the *documentation* process.
|
||||
|
||||
The relevant annotations in the envvar struct tag are:
|
||||
|
||||
* `deprecationVersion`\
|
||||
The release an envvar is announced for deprecation.
|
||||
* `removalVersion`\
|
||||
The version it is finally going to be removed is defined via the mandatory placeholder `%%NEXT_PRODUCTION_VERSION%%`, not an actual version number.
|
||||
* `deprecationInfo`\
|
||||
The reason why it was deprecated.
|
||||
* `deprecationReplacement`\
|
||||
Only if it is going to be replaced, not necessary if removed.
|
||||
|
||||
{{< hint warning >}}
|
||||
During the development cycle, the value for the `removalVersion` must be set to `%%NEXT_PRODUCTION_VERSION%%`. This placeholder will be replaced by the real version number during the production releasing process.
|
||||
{{< /hint >}}
|
||||
|
||||
For the documentation to show the correct value for the `removalVersion`, our docs helper scripts will automatically generate the correct version to be printed in the documentation. If `%%NEXT_PRODUCTION_VERSION%%` is found in the query, it will be replaced with `next-prod`, else the value found is used.
|
||||
|
||||
### Example
|
||||
|
||||
```golang
|
||||
// Notifications defines the config options for the notifications service.
|
||||
type Notifications struct {
|
||||
RevaGateway string `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY;REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata" deprecationVersion:"3.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"REVA_GATEWAY changing name for consistency" deprecationReplacement:"OCIS_REVA_GATEWAY"`
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
There are four different annotation variables that need to be filled:
|
||||
|
||||
| Annotation |Description| Format|
|
||||
|---|---|---|
|
||||
| deprecationVersion | The version the variable will be deprecated | semver (e.g. 3.0)|
|
||||
| removalVersion| The version the variable will be removed from the codebase. Note that according to semver, a removal **MUST NOT** be made in a minor or patch version change, but only in a major release | `%%NEXT_PRODUCTION_VERSION%%` |
|
||||
| deprecationInfo | Information why the variable is deprecated, must start with the name of the variable in order to avoid confusion, when there are multiple options in the `env:`-field | string (e.g. NATS_NATS_HOST is confusing) |
|
||||
| deprecationReplacement | The name of the variable that is going to replace the deprecated one.| string (e.g. NATS_HOST_ADDRESS) |
|
||||
|
||||
### What Happens Next?
|
||||
|
||||
Once a variable has been finally been removed, the annotations must be removed again from the code, since they don't serve any purpose.
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Envvar Naming Scope
|
||||
title: Envvar Naming Scopes
|
||||
date: 2023-03-23T00:00:00+00:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
@@ -8,6 +8,8 @@ geekdocFilePath: envvar-scopes.md
|
||||
geekdocCollapseSection: true
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
The scope of an environment variable can be derived from its name. Therefore, it is important to follow the correct naming scheme to enable easy and proper identification. This is important when either:
|
||||
|
||||
- a new local envvar is introduced.
|
||||
@@ -20,7 +22,7 @@ The scope of an environment variable can be derived from its name. Therefore, it
|
||||
- Mandatory when used in a service, a global envvar must have a local counterpart.
|
||||
- Variables that do not belong to any service are by definition global.
|
||||
|
||||
## Name Scope
|
||||
## Naming Scope
|
||||
|
||||
### Local Envvars
|
||||
|
||||
@@ -34,14 +36,32 @@ Note that this envvar is the global representation of the local example from abo
|
||||
|
||||
To get a list of global envvars used in all services, see the [Global Environment Variables](https://doc.owncloud.com/ocis/next/deployment/services/env-vars-special-scope.html#global-environment-variables) table in the ocis admin documentation.
|
||||
|
||||
### Lifecycle
|
||||
## Lifecycle of Envvars
|
||||
|
||||
In the struct tag values of our config data types, we are using three key/value pairs to document the lifecycle of a config variable: `introductionVersion`, `deprecationVersion` and `removalVersion`. During the development cycle, a new value should set to `%%NEXT%%` as long as no release is scheduled. During the release process, the placeholder will be replaced with the actual version number. Our docs helper scripts will then automatically generate the correct documentation based on the version number.
|
||||
The envvar struct tag contains at maximum the following key/value pairs to document the lifecycle of a config variable:
|
||||
|
||||
## Deprecations
|
||||
* `introductionVersion`
|
||||
* `deprecationVersion`
|
||||
* `removalVersion`
|
||||
* `deprecationInfo`
|
||||
* `deprecationReplacement`
|
||||
|
||||
All environment variable types that are used in a service follow the same [deprecation rules]({{< ref "ocis/development/deprecating-variables/_index.md" >}}) independent of their scope.
|
||||
### Introduce new Envvars
|
||||
|
||||
## Separating Envvars
|
||||
If a new envvar is introduced, only the `introductionVersion` is required.
|
||||
|
||||
{{< hint warning >}}
|
||||
During the development cycle, the value for the `introductionVersion` must be set to `%%NEXT%%`. This placeholder will be removed by the real version number during the production releasing process.
|
||||
{{< /hint >}}
|
||||
|
||||
For the documentation to show the correct value for the `IV` (introduction version), our docs helper scripts will automatically generate the correct version to be printed in the documentation. If `%%NEXT%%` is found in the query, it will be replaced with `next`, else the value found is used.
|
||||
|
||||
During the releasing process for a production release, the placeholder `%%NEXT%%` has to be replaced with the new production version number like `%%NEXT%%` → `7.0.0`.
|
||||
|
||||
### Deprecate Existing Envvars
|
||||
|
||||
See the [deprecation rules]({{< ref "./deprecating-variables.md" >}}) documentation for more details.
|
||||
|
||||
## Separating Multiple Envvars
|
||||
|
||||
When multiple envvars are defined for one purpose like a global and local one, use `;` (semicolon) to properly separate the envvars in go code. Though it is possible to separate with `,` (comma) according go rules, the current implementation of the docs generation process only recognizes semicolons as separator.
|
||||
|
||||
@@ -32,7 +32,7 @@ Use this checklist with copy/paste in your PR - right from the beginning. It ren
|
||||
- Add the service config to `ocis-pkg/config/defaultconfig.go`
|
||||
- [ ] If the service is using service accounts, add it to `ocis/pkg/init/init.go`
|
||||
- [ ] Add the service to `.drone.star` to enable CI.
|
||||
- [ ] Inform doc team in an _early stage_ to review the readme AND the environment variables created.
|
||||
- [ ] Inform doc team in an *early stage* to review the readme AND the environment variables created.
|
||||
- The description must reflect the behaviour AND usually has a positive code quality impact.
|
||||
- [ ] Create proper description strings for envvars - see other services for examples, especially when it comes to multiple values. This must include:
|
||||
- base description, set of available values, description of each value.
|
||||
@@ -44,4 +44,5 @@ Use this checklist with copy/paste in your PR - right from the beginning. It ren
|
||||
- [ ] Make sure to have a function `FullDefaultConfig()` in `pkg/config/defaults/defaultconfig.go` of your service. It is needed to create the documentation.
|
||||
- [ ] Add metrics to the code to enable monitoring. See the proxy service for implementation details.
|
||||
- Plus add documentation about monitoring in the README.md file
|
||||
- [ ] When the service requires translations that have to be covered by the service and are not sourced by web, see the [add translation]({{< ref "./add-translations.md" >}}) documentation for more details.
|
||||
```
|
||||
|
||||
@@ -49,7 +49,7 @@ We also suggest using the last port in your extensions' range as a debug/metrics
|
||||
| 9180-9184 | FREE (formerly used by accounts) |
|
||||
| 9185-9189 | [thumbnails]({{< ref "../thumbnails/_index.md" >}}) |
|
||||
| 9190-9194 | [settings]({{< ref "../settings/_index.md" >}}) |
|
||||
| 9195-9197 | [activitylog]({{< ref "../activitylog/_index.md" >}}) |
|
||||
| 9195-9197 | [activitylog]({{< ref "../activitylog/_index.md" >}}) |
|
||||
| 9198-9199 | [auth-service]({{< ref "../auth-service/_index.md" >}}) |
|
||||
| 9200-9204 | [proxy]({{< ref "../proxy/_index.md" >}}) |
|
||||
| 9205-9209 | [proxy]({{< ref "../proxy/_index.md" >}}) |
|
||||
@@ -103,7 +103,7 @@ We also suggest using the last port in your extensions' range as a debug/metrics
|
||||
| 9445-9449 | FREE |
|
||||
| 9450-9454 | FREE |
|
||||
| 9455-9459 | FREE |
|
||||
| 9460-9464 | [store]({{< ref "../store/_index.md" >}}) |
|
||||
| 9460-9464 | FREE (formerly used by store-service) |
|
||||
| 9465-9469 | FREE |
|
||||
| 9470-9474 | FREE |
|
||||
| 9475-9479 | FREE |
|
||||
|
||||
1
docs/services/store/.gitignore
vendored
1
docs/services/store/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
grpc.md
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
title: "Store"
|
||||
date: 2018-05-02T00:00:00+00:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/store
|
||||
geekdocFilePath: _index.md
|
||||
geekdocCollapseSection: true
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This service provides ...
|
||||
|
||||
|
||||
## Table of Contents
|
||||
|
||||
{{< toc-tree >}}
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
title: Service Configuration
|
||||
date: 2018-05-02T00:00:00+00:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/store
|
||||
geekdocFilePath: configuration.md
|
||||
geekdocCollapseSection: true
|
||||
---
|
||||
|
||||
## Example YAML Config
|
||||
|
||||
{{< include file="services/_includes/store-config-example.yaml" language="yaml" >}}
|
||||
|
||||
{{< include file="services/_includes/store_configvars.md" >}}
|
||||
22
go.mod
22
go.mod
@@ -7,7 +7,7 @@ require (
|
||||
github.com/CiscoM31/godata v1.0.10
|
||||
github.com/KimMachineGun/automemlimit v0.6.1
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/MicahParks/keyfunc v1.9.0
|
||||
github.com/MicahParks/keyfunc/v2 v2.1.0
|
||||
github.com/Nerzal/gocloak/v13 v13.9.0
|
||||
github.com/bbalet/stopwords v1.0.0
|
||||
github.com/beevik/etree v1.4.1
|
||||
@@ -15,7 +15,7 @@ require (
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/coreos/go-oidc/v3 v3.11.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb
|
||||
github.com/cs3org/reva/v2 v2.23.0
|
||||
github.com/cs3org/reva/v2 v2.23.1-0.20240826144102-af5123b523cf
|
||||
github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
|
||||
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
|
||||
github.com/egirna/icap-client v0.1.1
|
||||
@@ -23,7 +23,6 @@ require (
|
||||
github.com/ggwhite/go-masker v1.1.0
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/go-jose/go-jose/v3 v3.0.3
|
||||
github.com/go-ldap/ldap/v3 v3.4.8
|
||||
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
|
||||
github.com/go-micro/plugins/v4/client/grpc v1.2.1
|
||||
@@ -42,14 +41,14 @@ require (
|
||||
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-tika v0.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/config/v2 v2.2.5
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0
|
||||
github.com/invopop/validation v0.8.0
|
||||
github.com/jellydator/ttlcache/v2 v2.11.1
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0
|
||||
@@ -67,13 +66,13 @@ require (
|
||||
github.com/oklog/run v1.1.0
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.20.0
|
||||
github.com/onsi/ginkgo/v2 v2.20.1
|
||||
github.com/onsi/gomega v1.34.1
|
||||
github.com/open-policy-agent/opa v0.67.1
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20240820135012-5fac8096ce9c
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/xattr v0.4.9
|
||||
github.com/pkg/xattr v0.4.10
|
||||
github.com/prometheus/client_golang v1.20.1
|
||||
github.com/r3labs/sse/v2 v2.10.0
|
||||
github.com/riandyrn/otelchi v0.9.0
|
||||
@@ -93,7 +92,7 @@ require (
|
||||
github.com/urfave/cli/v2 v2.27.4
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||
go-micro.dev/v4 v4.11.0
|
||||
go.etcd.io/bbolt v1.3.10
|
||||
go.etcd.io/bbolt v1.3.11
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0
|
||||
go.opentelemetry.io/contrib/zpages v0.53.0
|
||||
@@ -110,7 +109,7 @@ require (
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/term v0.23.0
|
||||
golang.org/x/text v0.17.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142
|
||||
google.golang.org/grpc v1.65.0
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@@ -195,6 +194,7 @@ require (
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.11.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
@@ -220,7 +220,7 @@ require (
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||
github.com/golang/glog v1.2.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
@@ -348,7 +348,7 @@ require (
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
|
||||
37
go.sum
37
go.sum
@@ -75,8 +75,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
|
||||
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
|
||||
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
|
||||
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
@@ -255,8 +255,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
|
||||
github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb h1:KmYZDReplv/yfwc1LNYpDcVhVujC3Pasv6WjXx1haSU=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb/go.mod h1:yyP8PRo0EZou3nSH7H4qjlzQwaydPeIRNgX50npQHpE=
|
||||
github.com/cs3org/reva/v2 v2.23.0 h1:tRa+q6usndTQ6LbaxtfEub3UsKVruJ1l7HY6K+ZKS9s=
|
||||
github.com/cs3org/reva/v2 v2.23.0/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
|
||||
github.com/cs3org/reva/v2 v2.23.1-0.20240826144102-af5123b523cf h1:VMg9uATNCBjJhU0dJJ5wgchLCCkZr/6IxjJxY+8hAAs=
|
||||
github.com/cs3org/reva/v2 v2.23.1-0.20240826144102-af5123b523cf/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
@@ -482,11 +482,10 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -610,8 +609,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vb
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 h1:CWyXh/jylQWp2dtiV33mY4iSSp6yf4lmn+c7/tN+ObI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0/go.mod h1:nCLIt0w3Ept2NwF8ThLmrppXsfT07oC8k0XNDxd8sVU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE=
|
||||
@@ -922,8 +921,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
|
||||
github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo=
|
||||
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@@ -970,8 +969,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
|
||||
github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE=
|
||||
github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
|
||||
github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA=
|
||||
github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -1219,8 +1218,8 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ
|
||||
go-micro.dev/v4 v4.11.0 h1:DZ2xcr0pnZJDlp6MJiCLhw4tXRxLw9xrJlPT91kubr0=
|
||||
go-micro.dev/v4 v4.11.0/go.mod h1:eE/tD53n3KbVrzrWxKLxdkGw45Fg1qaNLWjpJMvIUF4=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
|
||||
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
|
||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||
go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c=
|
||||
go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A=
|
||||
@@ -1669,10 +1668,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a h1:YIa/rzVqMEokBkPtydCkx1VLmv3An1Uw7w1P1m6EhOY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a h1:hqK4+jJZXCU4pW7jsAdGOVFIfLHQeV7LaizZKnZ84HI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
@@ -38,7 +38,6 @@ import (
|
||||
storageshares "github.com/owncloud/ocis/v2/services/storage-shares/pkg/config"
|
||||
storagesystem "github.com/owncloud/ocis/v2/services/storage-system/pkg/config"
|
||||
storageusers "github.com/owncloud/ocis/v2/services/storage-users/pkg/config"
|
||||
store "github.com/owncloud/ocis/v2/services/store/pkg/config"
|
||||
thumbnails "github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
|
||||
userlog "github.com/owncloud/ocis/v2/services/userlog/pkg/config"
|
||||
users "github.com/owncloud/ocis/v2/services/users/pkg/config"
|
||||
@@ -68,6 +67,7 @@ type Config struct {
|
||||
GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
|
||||
GRPCServiceTLS *shared.GRPCServiceTLS `yaml:"grpc_service_tls"`
|
||||
HTTPServiceTLS shared.HTTPServiceTLS `yaml:"http_service_tls"`
|
||||
Reva *shared.Reva `yaml:"reva"`
|
||||
|
||||
Mode Mode // DEPRECATED
|
||||
File string
|
||||
@@ -117,7 +117,6 @@ type Config struct {
|
||||
StoragePublicLink *storagepublic.Config `yaml:"storage_public"`
|
||||
StorageShares *storageshares.Config `yaml:"storage_shares"`
|
||||
StorageUsers *storageusers.Config `yaml:"storage_users"`
|
||||
Store *store.Config `yaml:"store"`
|
||||
Thumbnails *thumbnails.Config `yaml:"thumbnails"`
|
||||
Userlog *userlog.Config `yaml:"userlog"`
|
||||
Users *users.Config `yaml:"users"`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
||||
activitylog "github.com/owncloud/ocis/v2/services/activitylog/pkg/config/defaults"
|
||||
antivirus "github.com/owncloud/ocis/v2/services/antivirus/pkg/config/defaults"
|
||||
appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/config/defaults"
|
||||
@@ -37,7 +38,6 @@ import (
|
||||
storageshares "github.com/owncloud/ocis/v2/services/storage-shares/pkg/config/defaults"
|
||||
storageSystem "github.com/owncloud/ocis/v2/services/storage-system/pkg/config/defaults"
|
||||
storageusers "github.com/owncloud/ocis/v2/services/storage-users/pkg/config/defaults"
|
||||
store "github.com/owncloud/ocis/v2/services/store/pkg/config/defaults"
|
||||
thumbnails "github.com/owncloud/ocis/v2/services/thumbnails/pkg/config/defaults"
|
||||
userlog "github.com/owncloud/ocis/v2/services/userlog/pkg/config/defaults"
|
||||
users "github.com/owncloud/ocis/v2/services/users/pkg/config/defaults"
|
||||
@@ -53,6 +53,9 @@ func DefaultConfig() *Config {
|
||||
Port: "9250",
|
||||
Host: "localhost",
|
||||
},
|
||||
Reva: &shared.Reva{
|
||||
Address: "com.owncloud.api.gateway",
|
||||
},
|
||||
|
||||
Activitylog: activitylog.DefaultConfig(),
|
||||
Antivirus: antivirus.DefaultConfig(),
|
||||
@@ -90,7 +93,6 @@ func DefaultConfig() *Config {
|
||||
StorageShares: storageshares.DefaultConfig(),
|
||||
StorageSystem: storageSystem.DefaultConfig(),
|
||||
StorageUsers: storageusers.DefaultConfig(),
|
||||
Store: store.DefaultConfig(),
|
||||
Thumbnails: thumbnails.DefaultConfig(),
|
||||
Userlog: userlog.DefaultConfig(),
|
||||
Users: users.DefaultConfig(),
|
||||
|
||||
@@ -58,7 +58,9 @@ func EnsureDefaults(cfg *config.Config) {
|
||||
if cfg.GRPCServiceTLS == nil {
|
||||
cfg.GRPCServiceTLS = &shared.GRPCServiceTLS{}
|
||||
}
|
||||
|
||||
if cfg.Reva == nil {
|
||||
cfg.Reva = &shared.Reva{}
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureCommons copies applicable parts of the oCIS config into the commons part
|
||||
@@ -111,6 +113,8 @@ func EnsureCommons(cfg *config.Config) {
|
||||
if cfg.OcisURL != "" {
|
||||
cfg.Commons.OcisURL = cfg.OcisURL
|
||||
}
|
||||
|
||||
cfg.Commons.Reva = structs.CopyOrZeroValue(cfg.Reva)
|
||||
}
|
||||
|
||||
// Validate checks that all required configs are set. If a required config value
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -15,10 +13,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/MicahParks/keyfunc"
|
||||
"github.com/MicahParks/keyfunc/v2"
|
||||
goidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -95,6 +92,7 @@ func NewOIDCClient(opts ...Option) OIDCClient {
|
||||
httpClient: options.HTTPClient,
|
||||
accessTokenVerifyMethod: options.AccessTokenVerifyMethod,
|
||||
JWKSOptions: options.JWKSOptions, // TODO I don't like that we pass down config options ...
|
||||
JWKS: options.JWKS,
|
||||
providerLock: &sync.Mutex{},
|
||||
jwksLock: &sync.Mutex{},
|
||||
remoteKeySet: options.KeySet,
|
||||
@@ -296,7 +294,14 @@ func (c *oidcClient) verifyAccessTokenJWT(token string) (RegClaimsWithSID, jwt.M
|
||||
return claims, mapClaims, errors.New("error initializing jwks keyfunc")
|
||||
}
|
||||
|
||||
_, err := jwt.ParseWithClaims(token, &claims, jwks.Keyfunc)
|
||||
issuer := c.issuer
|
||||
if c.provider.AccessTokenIssuer != "" {
|
||||
// AD FS .well-known/openid-configuration has an optional `access_token_issuer` which takes precedence over `issuer`
|
||||
// See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oidce/586de7dd-3385-47c7-93a2-935d9e90441c
|
||||
issuer = c.provider.AccessTokenIssuer
|
||||
}
|
||||
|
||||
_, err := jwt.ParseWithClaims(token, &claims, jwks.Keyfunc, jwt.WithIssuer(issuer))
|
||||
if err != nil {
|
||||
return claims, mapClaims, err
|
||||
}
|
||||
@@ -308,93 +313,50 @@ func (c *oidcClient) verifyAccessTokenJWT(token string) (RegClaimsWithSID, jwt.M
|
||||
return claims, mapClaims, err
|
||||
}
|
||||
|
||||
issuer := c.issuer
|
||||
if c.provider.AccessTokenIssuer != "" {
|
||||
// AD FS .well-known/openid-configuration has an optional `access_token_issuer` which takes precedence over `issuer`
|
||||
// See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-oidce/586de7dd-3385-47c7-93a2-935d9e90441c
|
||||
issuer = c.provider.AccessTokenIssuer
|
||||
}
|
||||
|
||||
if !claims.VerifyIssuer(issuer, true) {
|
||||
vErr := jwt.ValidationError{}
|
||||
vErr.Inner = jwt.ErrTokenInvalidIssuer
|
||||
vErr.Errors |= jwt.ValidationErrorIssuer
|
||||
return claims, mapClaims, vErr
|
||||
}
|
||||
|
||||
return claims, mapClaims, nil
|
||||
}
|
||||
|
||||
func (c *oidcClient) VerifyLogoutToken(ctx context.Context, rawToken string) (*LogoutToken, error) {
|
||||
var claims LogoutToken
|
||||
if err := c.lookupWellKnownOpenidConfiguration(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jws, err := jose.ParseSigned(rawToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Throw out tokens with invalid claims before trying to verify the token. This lets
|
||||
// us do cheap checks before possibly re-syncing keys.
|
||||
payload, err := parseJWT(rawToken)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
|
||||
}
|
||||
var token LogoutToken
|
||||
if err := json.Unmarshal(payload, &token); err != nil {
|
||||
return nil, fmt.Errorf("oidc: failed to unmarshal claims: %v", err)
|
||||
jwks := c.getKeyfunc()
|
||||
if jwks == nil {
|
||||
return nil, errors.New("error initializing jwks keyfunc")
|
||||
}
|
||||
|
||||
//4. Verify that the Logout Token contains a sub Claim, a sid Claim, or both.
|
||||
if token.Subject == "" && token.SessionId == "" {
|
||||
return nil, fmt.Errorf("oidc: logout token must contain either sub or sid and MAY contain both")
|
||||
}
|
||||
//5. Verify that the Logout Token contains an events Claim whose value is JSON object containing the member name http://schemas.openid.net/event/backchannel-logout.
|
||||
if token.Events.Event == nil {
|
||||
return nil, fmt.Errorf("oidc: logout token must contain logout event")
|
||||
}
|
||||
//6. Verify that the Logout Token does not contain a nonce Claim.
|
||||
var n struct {
|
||||
Nonce *string `json:"nonce"`
|
||||
}
|
||||
json.Unmarshal(payload, &n)
|
||||
if n.Nonce != nil {
|
||||
return nil, fmt.Errorf("oidc: nonce on logout token MUST NOT be present")
|
||||
}
|
||||
// Check issuer.
|
||||
if !c.skipIssuerValidation && token.Issuer != c.issuer {
|
||||
return nil, fmt.Errorf("oidc: logout token issued by a different provider, expected %q got %q", c.issuer, token.Issuer)
|
||||
}
|
||||
|
||||
switch len(jws.Signatures) {
|
||||
case 0:
|
||||
return nil, fmt.Errorf("oidc: logout token not signed")
|
||||
case 1:
|
||||
// do nothing
|
||||
default:
|
||||
return nil, fmt.Errorf("oidc: multiple signatures on logout token not supported")
|
||||
}
|
||||
|
||||
sig := jws.Signatures[0]
|
||||
// From the backchannel-logout spec: Like ID Tokens, selection of the
|
||||
// algorithm used is governed by the id_token_signing_alg_values_supported
|
||||
// Discovery parameter and the id_token_signed_response_alg Registration
|
||||
// parameter when they are used; otherwise, the value SHOULD be the default
|
||||
// of RS256
|
||||
supportedSigAlgs := c.algorithms
|
||||
if len(supportedSigAlgs) == 0 {
|
||||
supportedSigAlgs = []string{RS256}
|
||||
}
|
||||
|
||||
if !contains(supportedSigAlgs, sig.Header.Algorithm) {
|
||||
return nil, fmt.Errorf("oidc: logout token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
|
||||
}
|
||||
|
||||
gotPayload, err := c.remoteKeySet.VerifySignature(goidc.ClientContext(ctx, c.httpClient), rawToken)
|
||||
_, err := jwt.ParseWithClaims(rawToken, &claims, jwks.Keyfunc, jwt.WithValidMethods(supportedSigAlgs), jwt.WithIssuer(c.issuer))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to verify signature: %v", err)
|
||||
c.Logger.Debug().Err(err).Msg("Failed to parse logout token")
|
||||
return nil, err
|
||||
}
|
||||
// Basic token validation has happened in ParseWithClaims (signature,
|
||||
// issuer, audience, ...). Now for some logout token specific checks.
|
||||
// 1. Verify that the Logout Token contains a sub Claim, a sid Claim, or both.
|
||||
if claims.Subject == "" && claims.SessionId == "" {
|
||||
return nil, fmt.Errorf("oidc: logout token must contain either sub or sid and MAY contain both")
|
||||
}
|
||||
// 2. Verify that the Logout Token contains an events Claim whose value is JSON object containing the member name http://schemas.openid.net/event/backchannel-logout.
|
||||
if claims.Events.Event == nil {
|
||||
return nil, fmt.Errorf("oidc: logout token must contain logout event")
|
||||
}
|
||||
// 3. Verify that the Logout Token does not contain a nonce Claim.
|
||||
if claims.Nonce != nil {
|
||||
return nil, fmt.Errorf("oidc: nonce on logout token MUST NOT be present")
|
||||
}
|
||||
|
||||
// Ensure that the payload returned by the square actually matches the payload parsed earlier.
|
||||
if !bytes.Equal(gotPayload, payload) {
|
||||
return nil, errors.New("oidc: internal error, payload parsed did not match previous payload")
|
||||
}
|
||||
|
||||
return &token, nil
|
||||
return &claims, nil
|
||||
}
|
||||
|
||||
func unmarshalResp(r *http.Response, body []byte, v interface{}) error {
|
||||
@@ -409,24 +371,3 @@ func unmarshalResp(r *http.Response, body []byte, v interface{}) error {
|
||||
}
|
||||
return fmt.Errorf("expected Content-Type = application/json, got %q: %v", ct, err)
|
||||
}
|
||||
|
||||
func contains(sli []string, ele string) bool {
|
||||
for _, s := range sli {
|
||||
if s == ele {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseJWT(p string) ([]byte, error) {
|
||||
parts := strings.Split(p, ".")
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("oidc: malformed jwt, expected 3 parts got %d", len(parts))
|
||||
}
|
||||
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: malformed jwt payload: %v", err)
|
||||
}
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
@@ -2,152 +2,124 @@ package oidc_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
goidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/go-jose/go-jose/v3"
|
||||
"github.com/MicahParks/keyfunc/v2"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
|
||||
)
|
||||
|
||||
type signingKey struct {
|
||||
keyID string // optional
|
||||
priv interface{}
|
||||
pub interface{}
|
||||
alg jose.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// sign creates a JWS using the private key from the provided payload.
|
||||
func (s *signingKey) sign(t testing.TB, payload []byte) string {
|
||||
privKey := &jose.JSONWebKey{Key: s.priv, Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
|
||||
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: s.alg, Key: privKey}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jws, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data, err := jws.CompactSerialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func (s *signingKey) jwk() jose.JSONWebKey {
|
||||
return jose.JSONWebKey{Key: s.pub, Use: "sig", Algorithm: string(s.alg), KeyID: s.keyID}
|
||||
priv interface{}
|
||||
jwks *keyfunc.JWKS
|
||||
}
|
||||
|
||||
func TestLogoutVerify(t *testing.T) {
|
||||
tests := []logoutVerificationTest{
|
||||
{
|
||||
name: "good token",
|
||||
logoutToken: ` {
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": {
|
||||
"http://schemas.openid.net/event/backchannel-logout": {}
|
||||
}
|
||||
}`,
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": map[string]interface{}{
|
||||
"http://schemas.openid.net/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
},
|
||||
{
|
||||
name: "invalid issuer",
|
||||
issuer: "https://bar",
|
||||
logoutToken: `{"iss":"https://foo"}`,
|
||||
config: goidc.Config{
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
name: "invalid issuer",
|
||||
issuer: "https://bar",
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo1",
|
||||
"sub": "248289761001",
|
||||
"events": map[string]interface{}{
|
||||
"http://schemas.openid.net/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid sig",
|
||||
logoutToken: `{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": {
|
||||
"http://schemas.openid.net/event/backchannel-logout": {}
|
||||
}
|
||||
}`,
|
||||
config: goidc.Config{
|
||||
SkipExpiryCheck: true,
|
||||
},
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": map[string]interface{}{
|
||||
"http://schemas.openid.net/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
verificationKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "no sid and no sub",
|
||||
logoutToken: ` {
|
||||
"iss": "https://foo",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"events": {
|
||||
"http://schemas.openid.net/event/backchannel-logout": {}
|
||||
}
|
||||
}`,
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"events": map[string]interface{}{
|
||||
"http://schemas.openid.net/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Prohibited nonce present",
|
||||
logoutToken: ` {
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"nonce" : "prohibited",
|
||||
"events": {
|
||||
"http://schemas.openid.net/event/backchannel-logout": {}
|
||||
}
|
||||
}`,
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"nonce": "123",
|
||||
"events": map[string]interface{}{
|
||||
"http://schemas.openid.net/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Wrong Event string",
|
||||
logoutToken: ` {
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": {
|
||||
"not a logout event": {}
|
||||
}
|
||||
}`,
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
"events": map[string]interface{}{
|
||||
"http://blah.blah.blash/event/backchannel-logout": struct{}{},
|
||||
},
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "No Event string",
|
||||
logoutToken: ` {
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
}`,
|
||||
logoutToken: jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
|
||||
"iss": "https://foo",
|
||||
"sub": "248289761001",
|
||||
"aud": "s6BhdRkqt3",
|
||||
"iat": 1471566154,
|
||||
"jti": "bWJq",
|
||||
"sid": "08a5019c-17e1-4977-8f42-65a12843ea02",
|
||||
}),
|
||||
signKey: newRSAKey(t),
|
||||
wantErr: true,
|
||||
},
|
||||
@@ -165,7 +137,7 @@ type logoutVerificationTest struct {
|
||||
issuer string
|
||||
|
||||
// JWT payload (just the claims).
|
||||
logoutToken string
|
||||
logoutToken *jwt.Token
|
||||
|
||||
// Key to sign the ID Token with.
|
||||
signKey *signingKey
|
||||
@@ -173,40 +145,31 @@ type logoutVerificationTest struct {
|
||||
// testing invalid signatures.
|
||||
verificationKey *signingKey
|
||||
|
||||
config goidc.Config
|
||||
wantErr bool
|
||||
}
|
||||
|
||||
type testVerifier struct {
|
||||
jwk jose.JSONWebKey
|
||||
}
|
||||
|
||||
func (t *testVerifier) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
|
||||
jws, err := jose.ParseSigned(jwt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
|
||||
}
|
||||
return jws.Verify(&t.jwk)
|
||||
}
|
||||
|
||||
func (v logoutVerificationTest) runGetToken(t *testing.T) (*oidc.LogoutToken, error) {
|
||||
token := v.signKey.sign(t, []byte(v.logoutToken))
|
||||
// token := v.signKey.sign(t, []byte(v.logoutToken))
|
||||
v.logoutToken.Header["kid"] = "1"
|
||||
token, err := v.logoutToken.SignedString(v.signKey.priv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
issuer := "https://foo"
|
||||
var ks goidc.KeySet
|
||||
var jwks *keyfunc.JWKS
|
||||
if v.verificationKey == nil {
|
||||
ks = &testVerifier{v.signKey.jwk()}
|
||||
jwks = v.signKey.jwks
|
||||
} else {
|
||||
ks = &testVerifier{v.verificationKey.jwk()}
|
||||
jwks = v.verificationKey.jwks
|
||||
}
|
||||
|
||||
pm := oidc.ProviderMetadata{}
|
||||
verifier := oidc.NewOIDCClient(
|
||||
oidc.WithOidcIssuer(issuer),
|
||||
oidc.WithKeySet(ks),
|
||||
oidc.WithConfig(&v.config),
|
||||
oidc.WithJWKS(jwks),
|
||||
oidc.WithProviderMetadata(&pm),
|
||||
)
|
||||
|
||||
@@ -228,13 +191,15 @@ func newRSAKey(t testing.TB) *signingKey {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.RS256}
|
||||
}
|
||||
givenKey := keyfunc.NewGivenRSA(
|
||||
&priv.PublicKey,
|
||||
keyfunc.GivenKeyOptions{Algorithm: jwt.SigningMethodRS256.Alg()},
|
||||
)
|
||||
jwks := keyfunc.NewGiven(
|
||||
map[string]keyfunc.GivenKey{
|
||||
"1": givenKey,
|
||||
},
|
||||
)
|
||||
|
||||
func newECDSAKey(t *testing.T) *signingKey {
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &signingKey{"", priv, priv.Public(), jose.ES256}
|
||||
return &signingKey{priv, jwks}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
)
|
||||
|
||||
@@ -59,35 +59,12 @@ type ProviderMetadata struct {
|
||||
|
||||
// Logout Token defines an logout Token
|
||||
type LogoutToken struct {
|
||||
// The URL of the server which issued this token. OpenID Connect
|
||||
// requires this value always be identical to the URL used for
|
||||
// initial discovery.
|
||||
//
|
||||
// Note: Because of a known issue with Google Accounts' implementation
|
||||
// this value may differ when using Google.
|
||||
//
|
||||
// See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo
|
||||
Issuer string `json:"iss"` // example "https://server.example.com"
|
||||
|
||||
// A unique string which identifies the end user.
|
||||
Subject string `json:"sub"` //"248289761001"
|
||||
|
||||
// The client ID, or set of client IDs, that this token is issued for. For
|
||||
// common uses, this is the client that initialized the auth flow.
|
||||
//
|
||||
// This package ensures the audience contains an expected value.
|
||||
Audience jwt.ClaimStrings `json:"aud"` // "s6BhdRkqt3"
|
||||
|
||||
// When the token was issued by the provider.
|
||||
IssuedAt *jwt.NumericDate `json:"iat"`
|
||||
|
||||
jwt.RegisteredClaims
|
||||
// The Session Id
|
||||
SessionId string `json:"sid"`
|
||||
|
||||
Events LogoutEvent `json:"events"`
|
||||
|
||||
// Jwt Id
|
||||
JwtID string `json:"jti"`
|
||||
SessionId string `json:"sid"`
|
||||
Events LogoutEvent `json:"events"`
|
||||
// Note: This is just here to be able to check for nonce being absent
|
||||
Nonce *string `json:"nonce"`
|
||||
}
|
||||
|
||||
// LogoutEvent defines a logout Event
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Code generated by mockery v2.40.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
jwt "github.com/golang-jwt/jwt/v5"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
oauth2 "golang.org/x/oauth2"
|
||||
|
||||
@@ -3,6 +3,7 @@ package oidc
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/MicahParks/keyfunc/v2"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
|
||||
|
||||
@@ -22,7 +23,14 @@ type Options struct {
|
||||
OIDCIssuer string
|
||||
// JWKSOptions to use when retrieving keys
|
||||
JWKSOptions config.JWKS
|
||||
// KeySet to use when verifiing signatures
|
||||
// the JWKS keyset to use for verifying signatures of Access- and
|
||||
// Logout-Tokens
|
||||
// this option is mostly needed for unit test. To avoid fetching the keys
|
||||
// from the issuer
|
||||
JWKS *keyfunc.JWKS
|
||||
// KeySet to use when verifiing signatures of jwt encoded
|
||||
// user info responses
|
||||
// TODO move userinfo verification to use jwt/keyfunc as well
|
||||
KeySet KeySet
|
||||
// AccessTokenVerifyMethod to use when verifying access tokens
|
||||
// TODO pass a function or interface to verify? an AccessTokenVerifier?
|
||||
@@ -80,6 +88,13 @@ func WithJWKSOptions(val config.JWKS) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithJWKS provides a function to set the JWKS option (mainly useful for testing).
|
||||
func WithJWKS(val *keyfunc.JWKS) Option {
|
||||
return func(o *Options) {
|
||||
o.JWKS = val
|
||||
}
|
||||
}
|
||||
|
||||
// WithKeySet provides a function to set the KeySet option.
|
||||
func WithKeySet(val KeySet) Option {
|
||||
return func(o *Options) {
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
mRegistry "go-micro.dev/v4/registry"
|
||||
"go-micro.dev/v4/server"
|
||||
"go-micro.dev/v4/util/addr"
|
||||
mAddr "go-micro.dev/v4/util/addr"
|
||||
)
|
||||
|
||||
func BuildGRPCService(serviceID, address string, version string) *mRegistry.Service {
|
||||
func BuildGRPCService(serviceID, transport, address, version string) *mRegistry.Service {
|
||||
var host string
|
||||
var port int
|
||||
|
||||
@@ -23,20 +23,25 @@ func BuildGRPCService(serviceID, address string, version string) *mRegistry.Serv
|
||||
host = parts[0]
|
||||
}
|
||||
|
||||
addr, err := addr.Extract(host)
|
||||
if err != nil {
|
||||
addr = host
|
||||
addr := host
|
||||
if transport != "unix" {
|
||||
var err error
|
||||
addr, err = mAddr.Extract(host)
|
||||
if err != nil {
|
||||
addr = host
|
||||
}
|
||||
addr = net.JoinHostPort(addr, strconv.Itoa(port))
|
||||
}
|
||||
|
||||
node := &mRegistry.Node{
|
||||
Id: serviceID + "-" + server.DefaultId,
|
||||
Address: net.JoinHostPort(addr, fmt.Sprint(port)),
|
||||
Address: addr,
|
||||
Metadata: make(map[string]string),
|
||||
}
|
||||
|
||||
node.Metadata["registry"] = GetRegistry().String()
|
||||
node.Metadata["server"] = "grpc"
|
||||
node.Metadata["transport"] = "grpc"
|
||||
node.Metadata["transport"] = transport
|
||||
node.Metadata["protocol"] = "grpc"
|
||||
|
||||
return &mRegistry.Service{
|
||||
@@ -59,7 +64,7 @@ func BuildHTTPService(serviceID, address string, version string) *mRegistry.Serv
|
||||
host = parts[0]
|
||||
}
|
||||
|
||||
addr, err := addr.Extract(host)
|
||||
addr, err := mAddr.Extract(host)
|
||||
if err != nil {
|
||||
addr = host
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ Do not remove any revisions but print the revisions that would be removed.
|
||||
Allows specifying the blobstore to use. Defaults to `ocis`. Can be switched to `s3ng` but needs addtional envvar configuration (see the `storage-users` service for more details).
|
||||
* `-v` / `--verbose`\
|
||||
Prints additional information about the revisions that are removed.
|
||||
* `--glob-mechanism` (default: `glob`\
|
||||
(advanced) Allows specifying the mechanism to use for globbing. Can be `glob`, `list` or `workers`. In most cases the default `glob` does not need to be changed. If large spaces need to be purged, `list` or `workers` can be used to improve performance at the cost of higher cpu and ram usage. `list` will spawn 10 threads that list folder contents in parallel. `workers` will use a special globbing mechanism and multiple threads to achieve the best performance for the highest cost.
|
||||
|
||||
### Trash CLI
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
ocisbs "github.com/cs3org/reva/v2/pkg/storage/fs/ocis/blobstore"
|
||||
"github.com/cs3org/reva/v2/pkg/storage/fs/posix/lookup"
|
||||
s3bs "github.com/cs3org/reva/v2/pkg/storage/fs/s3ng/blobstore"
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
|
||||
var (
|
||||
// _nodesGlobPattern is the glob pattern to find all nodes
|
||||
_nodesGlobPattern = "spaces/*/*/*/*/*/*/*/*"
|
||||
_nodesGlobPattern = "spaces/*/*/nodes/"
|
||||
)
|
||||
|
||||
// RevisionsCommand is the entrypoint for the revisions command.
|
||||
@@ -30,7 +31,7 @@ func RevisionsCommand(cfg *config.Config) *cli.Command {
|
||||
Subcommands: []*cli.Command{
|
||||
PurgeRevisionsCommand(cfg),
|
||||
},
|
||||
Before: func(c *cli.Context) error {
|
||||
Before: func(_ *cli.Context) error {
|
||||
return configlog.ReturnError(parser.ParseConfig(cfg, true))
|
||||
},
|
||||
Action: func(_ *cli.Context) error {
|
||||
@@ -74,6 +75,11 @@ func PurgeRevisionsCommand(cfg *config.Config) *cli.Command {
|
||||
Aliases: []string{"r"},
|
||||
Usage: "purge all revisions of this file/space. If not set, all revisions will be purged",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "glob-mechanism",
|
||||
Usage: "the glob mechanism to find all nodes. Can be 'glob', 'list' or 'workers'. 'glob' uses globbing with a single worker. 'workers' spawns multiple go routines, accelatering the command drastically but causing high cpu and ram usage. 'list' looks for references by listing directories with multiple workers. Default is 'glob'",
|
||||
Value: "glob",
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
basePath := c.String("basepath")
|
||||
@@ -108,43 +114,72 @@ func PurgeRevisionsCommand(cfg *config.Config) *cli.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := generatePath(basePath, c.String("resource-id"))
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error parsing resourceID: %s", err)
|
||||
return err
|
||||
var rid *provider.ResourceId
|
||||
resid, err := storagespace.ParseID(c.String("resource-id"))
|
||||
if err == nil {
|
||||
rid = &resid
|
||||
}
|
||||
|
||||
if err := revisions.PurgeRevisions(p, bs, c.Bool("dry-run"), c.Bool("verbose")); err != nil {
|
||||
fmt.Printf("❌ Error purging revisions: %s", err)
|
||||
return err
|
||||
mechanism := c.String("glob-mechanism")
|
||||
if rid.GetOpaqueId() != "" {
|
||||
mechanism = "glob"
|
||||
}
|
||||
|
||||
var ch <-chan string
|
||||
switch mechanism {
|
||||
default:
|
||||
fallthrough
|
||||
case "glob":
|
||||
p := generatePath(basePath, rid)
|
||||
if rid.GetOpaqueId() == "" {
|
||||
p = filepath.Join(p, "*/*/*/*/*")
|
||||
}
|
||||
ch = revisions.Glob(p)
|
||||
case "workers":
|
||||
p := generatePath(basePath, rid)
|
||||
ch = revisions.GlobWorkers(p, "/*", "/*/*/*/*")
|
||||
case "list":
|
||||
p := filepath.Join(basePath, "spaces")
|
||||
if rid != nil {
|
||||
p = generatePath(basePath, rid)
|
||||
}
|
||||
ch = revisions.List(p, 10)
|
||||
}
|
||||
|
||||
files, blobs, revisions := revisions.PurgeRevisions(ch, bs, c.Bool("dry-run"), c.Bool("verbose"))
|
||||
printResults(files, blobs, revisions, c.Bool("dry-run"))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generatePath(basePath string, resourceID string) (string, error) {
|
||||
if resourceID == "" {
|
||||
return filepath.Join(basePath, _nodesGlobPattern), nil
|
||||
func printResults(countFiles, countBlobs, countRevisions int, dryRun bool) {
|
||||
switch {
|
||||
case countFiles == 0 && countRevisions == 0 && countBlobs == 0:
|
||||
fmt.Println("❎ No revisions found. Storage provider is clean.")
|
||||
case !dryRun:
|
||||
fmt.Printf("✅ Deleted %d revisions (%d files / %d blobs)\n", countRevisions, countFiles, countBlobs)
|
||||
default:
|
||||
fmt.Printf("👉 Would delete %d revisions (%d files / %d blobs)\n", countRevisions, countFiles, countBlobs)
|
||||
}
|
||||
}
|
||||
|
||||
rid, err := storagespace.ParseID(resourceID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
func generatePath(basePath string, rid *provider.ResourceId) string {
|
||||
if rid == nil {
|
||||
return filepath.Join(basePath, _nodesGlobPattern)
|
||||
}
|
||||
|
||||
sid := lookup.Pathify(rid.GetSpaceId(), 1, 2)
|
||||
if sid == "" {
|
||||
sid = "*/*"
|
||||
return ""
|
||||
}
|
||||
|
||||
nid := lookup.Pathify(rid.GetOpaqueId(), 4, 2)
|
||||
if nid == "" {
|
||||
nid = "*/*/*/*/"
|
||||
return filepath.Join(basePath, "spaces", sid, "nodes")
|
||||
}
|
||||
|
||||
return filepath.Join(basePath, "spaces", sid, "nodes", nid+"*"), nil
|
||||
return filepath.Join(basePath, "spaces", sid, "nodes", nid+"*")
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -44,7 +44,6 @@ import (
|
||||
storageshares "github.com/owncloud/ocis/v2/services/storage-shares/pkg/command"
|
||||
storagesystem "github.com/owncloud/ocis/v2/services/storage-system/pkg/command"
|
||||
storageusers "github.com/owncloud/ocis/v2/services/storage-users/pkg/command"
|
||||
store "github.com/owncloud/ocis/v2/services/store/pkg/command"
|
||||
thumbnails "github.com/owncloud/ocis/v2/services/thumbnails/pkg/command"
|
||||
userlog "github.com/owncloud/ocis/v2/services/userlog/pkg/command"
|
||||
users "github.com/owncloud/ocis/v2/services/users/pkg/command"
|
||||
@@ -234,11 +233,6 @@ var svccmds = []register.Command{
|
||||
cfg.StorageUsers.Commons = cfg.Commons
|
||||
})
|
||||
},
|
||||
func(cfg *config.Config) *cli.Command {
|
||||
return ServiceCommand(cfg, cfg.Store.Service.Name, store.GetCommands(cfg.Store), func(c *config.Config) {
|
||||
cfg.Store.Commons = cfg.Commons
|
||||
})
|
||||
},
|
||||
func(cfg *config.Config) *cli.Command {
|
||||
return ServiceCommand(cfg, cfg.Thumbnails.Service.Name, thumbnails.GetCommands(cfg.Thumbnails), func(c *config.Config) {
|
||||
cfg.Thumbnails.Commons = cfg.Commons
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
package revisions
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node"
|
||||
"github.com/shamaton/msgpack/v2"
|
||||
@@ -26,25 +26,121 @@ type DelBlobstore interface {
|
||||
Delete(node *node.Node) error
|
||||
}
|
||||
|
||||
// Glob uses globbing to find all revision nodes in a storage provider.
|
||||
func Glob(pattern string) <-chan string {
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
nodes, err := filepath.Glob(filepath.Join(pattern))
|
||||
if err != nil {
|
||||
fmt.Println("error globbing", pattern, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(nodes) == 0 {
|
||||
fmt.Println("no nodes found. Double check storage path")
|
||||
return
|
||||
}
|
||||
|
||||
for _, n := range nodes {
|
||||
if _versionRegex.MatchString(n) {
|
||||
ch <- n
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// GlobWorkers uses multiple go routine to glob all revision nodes in a storage provider.
|
||||
func GlobWorkers(pattern string, depth string, remainder string) <-chan string {
|
||||
wg := sync.WaitGroup{}
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
nodes, err := filepath.Glob(pattern + depth)
|
||||
if err != nil {
|
||||
fmt.Println("error globbing", pattern, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(nodes) == 0 {
|
||||
fmt.Println("no nodes found. Double check storage path")
|
||||
return
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
wg.Add(1)
|
||||
go func(node string) {
|
||||
defer wg.Done()
|
||||
nodes, err := filepath.Glob(node + remainder)
|
||||
if err != nil {
|
||||
fmt.Println("error globbing", node, err)
|
||||
return
|
||||
}
|
||||
for _, n := range nodes {
|
||||
if _versionRegex.MatchString(n) {
|
||||
ch <- n
|
||||
}
|
||||
}
|
||||
}(node)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// Walk walks the storage provider to find all revision nodes.
|
||||
func Walk(base string) <-chan string {
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
fmt.Println("error walking", base, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !_versionRegex.MatchString(info.Name()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
ch <- path
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("error walking", base, err)
|
||||
return
|
||||
}
|
||||
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// List uses directory listing to find all revision nodes in a storage provider.
|
||||
func List(base string, workers int) <-chan string {
|
||||
ch := make(chan string)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
if err := listFolder(base, ch, make(chan struct{}, workers)); err != nil {
|
||||
fmt.Println("error listing", base, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// PurgeRevisions removes all revisions from a storage provider.
|
||||
func PurgeRevisions(pattern string, bs DelBlobstore, dryRun bool, verbose bool) error {
|
||||
if verbose {
|
||||
fmt.Println("Looking for nodes in", pattern)
|
||||
}
|
||||
|
||||
nodes, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(nodes) == 0 {
|
||||
return errors.New("no nodes found, double check storage path")
|
||||
}
|
||||
|
||||
func PurgeRevisions(nodes <-chan string, bs DelBlobstore, dryRun, verbose bool) (int, int, int) {
|
||||
countFiles := 0
|
||||
countBlobs := 0
|
||||
countRevisions := 0
|
||||
for _, d := range nodes {
|
||||
|
||||
var err error
|
||||
for d := range nodes {
|
||||
if !_versionRegex.MatchString(d) {
|
||||
continue
|
||||
}
|
||||
@@ -106,14 +202,37 @@ func PurgeRevisions(pattern string, bs DelBlobstore, dryRun bool, verbose bool)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case countFiles == 0 && countRevisions == 0 && countBlobs == 0:
|
||||
fmt.Println("❎ No revisions found. Storage provider is clean.")
|
||||
case !dryRun:
|
||||
fmt.Printf("✅ Deleted %d revisions (%d files / %d blobs)\n", countRevisions, countFiles, countBlobs)
|
||||
default:
|
||||
fmt.Printf("👉 Would delete %d revisions (%d files / %d blobs)\n", countRevisions, countFiles, countBlobs)
|
||||
return countFiles, countBlobs, countRevisions
|
||||
}
|
||||
|
||||
func listFolder(path string, ch chan<- string, workers chan struct{}) error {
|
||||
workers <- struct{}{}
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
children, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
<-workers
|
||||
return err
|
||||
}
|
||||
|
||||
for _, child := range children {
|
||||
if child.IsDir() {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := listFolder(filepath.Join(path, child.Name()), ch, workers); err != nil {
|
||||
fmt.Println("error listing", path, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if _versionRegex.MatchString(child.Name()) {
|
||||
ch <- filepath.Join(path, child.Name())
|
||||
}
|
||||
|
||||
}
|
||||
<-workers
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
170
ocis/pkg/revisions/revisions_test.go
Normal file
170
ocis/pkg/revisions/revisions_test.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package revisions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/lookup"
|
||||
"github.com/google/uuid"
|
||||
"github.com/test-go/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
_basePath = "/spaces/8f/638374-6ea8-4f0d-80c4-66d9b49830a5/nodes/"
|
||||
)
|
||||
|
||||
// func TestInit(t *testing.T) {
|
||||
// initialize(10, 2)
|
||||
// defer os.RemoveAll("test_temp")
|
||||
// }
|
||||
|
||||
func TestGlob30(t *testing.T) { test(t, 10, 2, glob) }
|
||||
func TestGlob80(t *testing.T) { test(t, 20, 3, glob) }
|
||||
func TestGlob250(t *testing.T) { test(t, 50, 4, glob) }
|
||||
func TestGlob600(t *testing.T) { test(t, 100, 5, glob) }
|
||||
|
||||
func TestWalk30(t *testing.T) { test(t, 10, 2, walk) }
|
||||
func TestWalk80(t *testing.T) { test(t, 20, 3, walk) }
|
||||
func TestWalk250(t *testing.T) { test(t, 50, 4, walk) }
|
||||
func TestWalk600(t *testing.T) { test(t, 100, 5, walk) }
|
||||
|
||||
func TestList30(t *testing.T) { test(t, 10, 2, list2) }
|
||||
func TestList80(t *testing.T) { test(t, 20, 3, list10) }
|
||||
func TestList250(t *testing.T) { test(t, 50, 4, list20) }
|
||||
func TestList600(t *testing.T) { test(t, 100, 5, list2) }
|
||||
|
||||
func TestGlobWorkers30(t *testing.T) { test(t, 10, 2, globWorkersD1) }
|
||||
func TestGlobWorkers80(t *testing.T) { test(t, 20, 3, globWorkersD2) }
|
||||
func TestGlobWorkers250(t *testing.T) { test(t, 50, 4, globWorkersD4) }
|
||||
func TestGlobWorkers600(t *testing.T) { test(t, 100, 5, globWorkersD2) }
|
||||
|
||||
func BenchmarkGlob30(b *testing.B) { benchmark(b, 10, 2, glob) }
|
||||
func BenchmarkWalk30(b *testing.B) { benchmark(b, 10, 2, walk) }
|
||||
func BenchmarkList30(b *testing.B) { benchmark(b, 10, 2, list2) }
|
||||
func BenchmarkGlobWorkers30(b *testing.B) { benchmark(b, 10, 2, globWorkersD2) }
|
||||
|
||||
func BenchmarkGlob80(b *testing.B) { benchmark(b, 20, 3, glob) }
|
||||
func BenchmarkWalk80(b *testing.B) { benchmark(b, 20, 3, walk) }
|
||||
func BenchmarkList80(b *testing.B) { benchmark(b, 20, 3, list2) }
|
||||
func BenchmarkGlobWorkers80(b *testing.B) { benchmark(b, 20, 3, globWorkersD2) }
|
||||
|
||||
func BenchmarkGlob250(b *testing.B) { benchmark(b, 50, 4, glob) }
|
||||
func BenchmarkWalk250(b *testing.B) { benchmark(b, 50, 4, walk) }
|
||||
func BenchmarkList250(b *testing.B) { benchmark(b, 50, 4, list2) }
|
||||
func BenchmarkGlobWorkers250(b *testing.B) { benchmark(b, 50, 4, globWorkersD2) }
|
||||
|
||||
func BenchmarkGlobAT600(b *testing.B) { benchmark(b, 100, 5, glob) }
|
||||
func BenchmarkWalkAT600(b *testing.B) { benchmark(b, 100, 5, walk) }
|
||||
func BenchmarkList2AT600(b *testing.B) { benchmark(b, 100, 5, list2) }
|
||||
func BenchmarkList10AT600(b *testing.B) { benchmark(b, 100, 5, list10) }
|
||||
func BenchmarkList20AT600(b *testing.B) { benchmark(b, 100, 5, list20) }
|
||||
func BenchmarkGlobWorkersD1AT600(b *testing.B) { benchmark(b, 100, 5, globWorkersD1) }
|
||||
func BenchmarkGlobWorkersD2AT600(b *testing.B) { benchmark(b, 100, 5, globWorkersD2) }
|
||||
func BenchmarkGlobWorkersD4AT600(b *testing.B) { benchmark(b, 100, 5, globWorkersD4) }
|
||||
|
||||
func BenchmarkGlobAT22000(b *testing.B) { benchmark(b, 2000, 10, glob) }
|
||||
func BenchmarkWalkAT22000(b *testing.B) { benchmark(b, 2000, 10, walk) }
|
||||
func BenchmarkList2AT22000(b *testing.B) { benchmark(b, 2000, 10, list2) }
|
||||
func BenchmarkList10AT22000(b *testing.B) { benchmark(b, 2000, 10, list10) }
|
||||
func BenchmarkList20AT22000(b *testing.B) { benchmark(b, 2000, 10, list20) }
|
||||
func BenchmarkGlobWorkersD1AT22000(b *testing.B) { benchmark(b, 2000, 10, globWorkersD1) }
|
||||
func BenchmarkGlobWorkersD2AT22000(b *testing.B) { benchmark(b, 2000, 10, globWorkersD2) }
|
||||
func BenchmarkGlobWorkersD4AT22000(b *testing.B) { benchmark(b, 2000, 10, globWorkersD4) }
|
||||
|
||||
func BenchmarkGlob110000(b *testing.B) { benchmark(b, 10000, 10, glob) }
|
||||
func BenchmarkWalk110000(b *testing.B) { benchmark(b, 10000, 10, walk) }
|
||||
func BenchmarkList110000(b *testing.B) { benchmark(b, 10000, 10, list2) }
|
||||
func BenchmarkGlobWorkers110000(b *testing.B) { benchmark(b, 10000, 10, globWorkersD2) }
|
||||
|
||||
func benchmark(b *testing.B, numNodes int, numRevisions int, f func(string) <-chan string) {
|
||||
base := initialize(numNodes, numRevisions)
|
||||
defer os.RemoveAll(base)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ch := f(base)
|
||||
PurgeRevisions(ch, nil, false, false)
|
||||
}
|
||||
b.StopTimer()
|
||||
}
|
||||
|
||||
func test(t *testing.T, numNodes int, numRevisions int, f func(string) <-chan string) {
|
||||
base := initialize(numNodes, numRevisions)
|
||||
defer os.RemoveAll(base)
|
||||
|
||||
ch := f(base)
|
||||
_, _, revisions := PurgeRevisions(ch, nil, false, false)
|
||||
require.Equal(t, numNodes*numRevisions, revisions, "Deleted Revisions")
|
||||
}
|
||||
|
||||
func glob(base string) <-chan string {
|
||||
return Glob(base + _basePath + "*/*/*/*/*")
|
||||
}
|
||||
|
||||
func walk(base string) <-chan string {
|
||||
return Walk(base + _basePath)
|
||||
}
|
||||
|
||||
func list2(base string) <-chan string {
|
||||
return List(base+_basePath, 2)
|
||||
}
|
||||
|
||||
func list10(base string) <-chan string {
|
||||
return List(base+_basePath, 10)
|
||||
}
|
||||
|
||||
func list20(base string) <-chan string {
|
||||
return List(base+_basePath, 20)
|
||||
}
|
||||
|
||||
func globWorkersD1(base string) <-chan string {
|
||||
return GlobWorkers(base+_basePath, "*", "/*/*/*/*")
|
||||
}
|
||||
|
||||
func globWorkersD2(base string) <-chan string {
|
||||
return GlobWorkers(base+_basePath, "*/*", "/*/*/*")
|
||||
}
|
||||
|
||||
func globWorkersD4(base string) <-chan string {
|
||||
return GlobWorkers(base+_basePath, "*/*/*/*", "/*")
|
||||
}
|
||||
|
||||
func initialize(numNodes int, numRevisions int) string {
|
||||
base := "test_temp_" + uuid.New().String()
|
||||
if err := os.Mkdir(base, os.ModePerm); err != nil {
|
||||
fmt.Println("Error creating test_temp directory", err)
|
||||
os.RemoveAll(base)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// create base path
|
||||
if err := os.MkdirAll(base+_basePath, fs.ModePerm); err != nil {
|
||||
fmt.Println("Error creating base path", err)
|
||||
os.RemoveAll(base)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for i := 0; i < numNodes; i++ {
|
||||
path := lookup.Pathify(uuid.New().String(), 4, 2)
|
||||
dir := filepath.Dir(path)
|
||||
if err := os.MkdirAll(base+_basePath+dir, fs.ModePerm); err != nil {
|
||||
fmt.Println("Error creating test_temp directory", err)
|
||||
os.RemoveAll(base)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if _, err := os.Create(base + _basePath + path); err != nil {
|
||||
fmt.Println("Error creating file", err)
|
||||
os.RemoveAll(base)
|
||||
os.Exit(1)
|
||||
}
|
||||
for i := 0; i < numRevisions; i++ {
|
||||
os.Create(base + _basePath + path + ".REV.2024-05-22T07:32:53.89969" + strconv.Itoa(i) + "Z")
|
||||
}
|
||||
}
|
||||
return base
|
||||
}
|
||||
@@ -526,7 +526,7 @@ func pingNats(cfg *ociscfg.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func pingGateway(_ *ociscfg.Config) error {
|
||||
func pingGateway(cfg *ociscfg.Config) error {
|
||||
// init grpc connection
|
||||
_, err := ogrpc.NewClient()
|
||||
if err != nil {
|
||||
@@ -536,7 +536,7 @@ func pingGateway(_ *ociscfg.Config) error {
|
||||
b := backoff.NewExponentialBackOff()
|
||||
o := func() error {
|
||||
n := b.NextBackOff()
|
||||
_, err := pool.GetGatewayServiceClient("com.owncloud.api.gateway")
|
||||
_, err := pool.GetGatewayServiceClient(cfg.Reva.Address)
|
||||
if err != nil && n > time.Second {
|
||||
logger.New().Error().Err(err).Msgf("can't connect to gateway service, retrying in %s", n)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@ packages:
|
||||
github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0:
|
||||
interfaces:
|
||||
ValueService:
|
||||
github.com/owncloud/ocis/v2/protogen/gen/ocis/services/store/v0:
|
||||
interfaces:
|
||||
StoreService:
|
||||
github.com/owncloud/ocis/v2/protogen/gen/ocis/services/thumbnails/v0:
|
||||
interfaces:
|
||||
ThumbnailService:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,484 +0,0 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
client "go-micro.dev/v4/client"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/store/v0"
|
||||
)
|
||||
|
||||
// StoreService is an autogenerated mock type for the StoreService type
|
||||
type StoreService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
type StoreService_Expecter struct {
|
||||
mock *mock.Mock
|
||||
}
|
||||
|
||||
func (_m *StoreService) EXPECT() *StoreService_Expecter {
|
||||
return &StoreService_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// Databases provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) Databases(ctx context.Context, in *v0.DatabasesRequest, opts ...client.CallOption) (*v0.DatabasesResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Databases")
|
||||
}
|
||||
|
||||
var r0 *v0.DatabasesResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.DatabasesRequest, ...client.CallOption) (*v0.DatabasesResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.DatabasesRequest, ...client.CallOption) *v0.DatabasesResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.DatabasesResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.DatabasesRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_Databases_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Databases'
|
||||
type StoreService_Databases_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Databases is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.DatabasesRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) Databases(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_Databases_Call {
|
||||
return &StoreService_Databases_Call{Call: _e.mock.On("Databases",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_Databases_Call) Run(run func(ctx context.Context, in *v0.DatabasesRequest, opts ...client.CallOption)) *StoreService_Databases_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.DatabasesRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Databases_Call) Return(_a0 *v0.DatabasesResponse, _a1 error) *StoreService_Databases_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Databases_Call) RunAndReturn(run func(context.Context, *v0.DatabasesRequest, ...client.CallOption) (*v0.DatabasesResponse, error)) *StoreService_Databases_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) Delete(ctx context.Context, in *v0.DeleteRequest, opts ...client.CallOption) (*v0.DeleteResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 *v0.DeleteResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.DeleteRequest, ...client.CallOption) (*v0.DeleteResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.DeleteRequest, ...client.CallOption) *v0.DeleteResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.DeleteResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.DeleteRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete'
|
||||
type StoreService_Delete_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Delete is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.DeleteRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) Delete(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_Delete_Call {
|
||||
return &StoreService_Delete_Call{Call: _e.mock.On("Delete",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_Delete_Call) Run(run func(ctx context.Context, in *v0.DeleteRequest, opts ...client.CallOption)) *StoreService_Delete_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.DeleteRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Delete_Call) Return(_a0 *v0.DeleteResponse, _a1 error) *StoreService_Delete_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Delete_Call) RunAndReturn(run func(context.Context, *v0.DeleteRequest, ...client.CallOption) (*v0.DeleteResponse, error)) *StoreService_Delete_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) List(ctx context.Context, in *v0.ListRequest, opts ...client.CallOption) (v0.Store_ListService, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for List")
|
||||
}
|
||||
|
||||
var r0 v0.Store_ListService
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListRequest, ...client.CallOption) (v0.Store_ListService, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListRequest, ...client.CallOption) v0.Store_ListService); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(v0.Store_ListService)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.ListRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List'
|
||||
type StoreService_List_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// List is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.ListRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) List(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_List_Call {
|
||||
return &StoreService_List_Call{Call: _e.mock.On("List",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_List_Call) Run(run func(ctx context.Context, in *v0.ListRequest, opts ...client.CallOption)) *StoreService_List_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.ListRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_List_Call) Return(_a0 v0.Store_ListService, _a1 error) *StoreService_List_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_List_Call) RunAndReturn(run func(context.Context, *v0.ListRequest, ...client.CallOption) (v0.Store_ListService, error)) *StoreService_List_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Read provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) Read(ctx context.Context, in *v0.ReadRequest, opts ...client.CallOption) (*v0.ReadResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Read")
|
||||
}
|
||||
|
||||
var r0 *v0.ReadResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ReadRequest, ...client.CallOption) (*v0.ReadResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ReadRequest, ...client.CallOption) *v0.ReadResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.ReadResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.ReadRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read'
|
||||
type StoreService_Read_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Read is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.ReadRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) Read(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_Read_Call {
|
||||
return &StoreService_Read_Call{Call: _e.mock.On("Read",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_Read_Call) Run(run func(ctx context.Context, in *v0.ReadRequest, opts ...client.CallOption)) *StoreService_Read_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.ReadRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Read_Call) Return(_a0 *v0.ReadResponse, _a1 error) *StoreService_Read_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Read_Call) RunAndReturn(run func(context.Context, *v0.ReadRequest, ...client.CallOption) (*v0.ReadResponse, error)) *StoreService_Read_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Tables provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) Tables(ctx context.Context, in *v0.TablesRequest, opts ...client.CallOption) (*v0.TablesResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Tables")
|
||||
}
|
||||
|
||||
var r0 *v0.TablesResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.TablesRequest, ...client.CallOption) (*v0.TablesResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.TablesRequest, ...client.CallOption) *v0.TablesResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.TablesResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.TablesRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_Tables_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Tables'
|
||||
type StoreService_Tables_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Tables is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.TablesRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) Tables(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_Tables_Call {
|
||||
return &StoreService_Tables_Call{Call: _e.mock.On("Tables",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_Tables_Call) Run(run func(ctx context.Context, in *v0.TablesRequest, opts ...client.CallOption)) *StoreService_Tables_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.TablesRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Tables_Call) Return(_a0 *v0.TablesResponse, _a1 error) *StoreService_Tables_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Tables_Call) RunAndReturn(run func(context.Context, *v0.TablesRequest, ...client.CallOption) (*v0.TablesResponse, error)) *StoreService_Tables_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Write provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *StoreService) Write(ctx context.Context, in *v0.WriteRequest, opts ...client.CallOption) (*v0.WriteResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Write")
|
||||
}
|
||||
|
||||
var r0 *v0.WriteResponse
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.WriteRequest, ...client.CallOption) (*v0.WriteResponse, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.WriteRequest, ...client.CallOption) *v0.WriteResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.WriteResponse)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.WriteRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// StoreService_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write'
|
||||
type StoreService_Write_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Write is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *v0.WriteRequest
|
||||
// - opts ...client.CallOption
|
||||
func (_e *StoreService_Expecter) Write(ctx interface{}, in interface{}, opts ...interface{}) *StoreService_Write_Call {
|
||||
return &StoreService_Write_Call{Call: _e.mock.On("Write",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *StoreService_Write_Call) Run(run func(ctx context.Context, in *v0.WriteRequest, opts ...client.CallOption)) *StoreService_Write_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]client.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(client.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*v0.WriteRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Write_Call) Return(_a0 *v0.WriteResponse, _a1 error) *StoreService_Write_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *StoreService_Write_Call) RunAndReturn(run func(context.Context, *v0.WriteRequest, ...client.CallOption) (*v0.WriteResponse, error)) *StoreService_Write_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// NewStoreService creates a new instance of StoreService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewStoreService(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *StoreService {
|
||||
mock := &StoreService{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -1,929 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: ocis/services/store/v0/store.proto
|
||||
|
||||
package v0
|
||||
|
||||
import (
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
|
||||
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/store/v0"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ReadRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Options *v0.ReadOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ReadRequest) Reset() {
|
||||
*x = ReadRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ReadRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ReadRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ReadRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ReadRequest) GetKey() string {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadRequest) GetOptions() *v0.ReadOptions {
|
||||
if x != nil {
|
||||
return x.Options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReadResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Records []*v0.Record `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ReadResponse) Reset() {
|
||||
*x = ReadResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ReadResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ReadResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ReadResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ReadResponse) GetRecords() []*v0.Record {
|
||||
if x != nil {
|
||||
return x.Records
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Record *v0.Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"`
|
||||
Options *v0.WriteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (x *WriteRequest) Reset() {
|
||||
*x = WriteRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WriteRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WriteRequest) ProtoMessage() {}
|
||||
|
||||
func (x *WriteRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WriteRequest.ProtoReflect.Descriptor instead.
|
||||
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *WriteRequest) GetRecord() *v0.Record {
|
||||
if x != nil {
|
||||
return x.Record
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *WriteRequest) GetOptions() *v0.WriteOptions {
|
||||
if x != nil {
|
||||
return x.Options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *WriteResponse) Reset() {
|
||||
*x = WriteResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *WriteResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*WriteResponse) ProtoMessage() {}
|
||||
|
||||
func (x *WriteResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use WriteResponse.ProtoReflect.Descriptor instead.
|
||||
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type DeleteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Options *v0.DeleteOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) Reset() {
|
||||
*x = DeleteRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) GetKey() string {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) GetOptions() *v0.DeleteOptions {
|
||||
if x != nil {
|
||||
return x.Options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeleteResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *DeleteResponse) Reset() {
|
||||
*x = DeleteResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
type ListRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Options *v0.ListOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListRequest) Reset() {
|
||||
*x = ListRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ListRequest) GetOptions() *v0.ListOptions {
|
||||
if x != nil {
|
||||
return x.Options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Keys []string `protobuf:"bytes,2,rep,name=keys,proto3" json:"keys,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListResponse) Reset() {
|
||||
*x = ListResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *ListResponse) GetKeys() []string {
|
||||
if x != nil {
|
||||
return x.Keys
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DatabasesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *DatabasesRequest) Reset() {
|
||||
*x = DatabasesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DatabasesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DatabasesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DatabasesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DatabasesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DatabasesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type DatabasesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Databases []string `protobuf:"bytes,1,rep,name=databases,proto3" json:"databases,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DatabasesResponse) Reset() {
|
||||
*x = DatabasesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DatabasesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DatabasesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DatabasesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DatabasesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DatabasesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *DatabasesResponse) GetDatabases() []string {
|
||||
if x != nil {
|
||||
return x.Databases
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type TablesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TablesRequest) Reset() {
|
||||
*x = TablesRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TablesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TablesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TablesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TablesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*TablesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *TablesRequest) GetDatabase() string {
|
||||
if x != nil {
|
||||
return x.Database
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TablesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Tables []string `protobuf:"bytes,1,rep,name=tables,proto3" json:"tables,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TablesResponse) Reset() {
|
||||
*x = TablesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TablesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TablesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TablesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_ocis_services_store_v0_store_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TablesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TablesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_ocis_services_store_v0_store_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *TablesResponse) GetTables() []string {
|
||||
if x != nil {
|
||||
return x.Tables
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_ocis_services_store_v0_store_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_ocis_services_store_v0_store_proto_rawDesc = []byte{
|
||||
0x0a, 0x22, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x1a, 0x22, 0x6f, 0x63,
|
||||
0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65,
|
||||
0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61,
|
||||
0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x5e, 0x0a, 0x0b, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x3d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x61, 0x64,
|
||||
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x22, 0x48, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x38, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x0c, 0x57,
|
||||
0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x06, 0x72,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x63,
|
||||
0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x06, 0x72, 0x65, 0x63,
|
||||
0x6f, 0x72, 0x64, 0x12, 0x3e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x57, 0x72,
|
||||
0x69, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76,
|
||||
0x30, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
|
||||
0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x0b, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x07, 0x6f, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x63, 0x69,
|
||||
0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x76, 0x30, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
|
||||
0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x28, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x4a, 0x04, 0x08, 0x01,
|
||||
0x10, 0x02, 0x22, 0x12, 0x0a, 0x10, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x31, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61,
|
||||
0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64,
|
||||
0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
|
||||
0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x22, 0x2b, 0x0a, 0x0d, 0x54, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61,
|
||||
0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61,
|
||||
0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x28, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73,
|
||||
0x32, 0xa5, 0x04, 0x0a, 0x05, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x53, 0x0a, 0x04, 0x52, 0x65,
|
||||
0x61, 0x64, 0x12, 0x23, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x61, 0x64,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30,
|
||||
0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
||||
0x56, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76,
|
||||
0x30, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25,
|
||||
0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x12, 0x25, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e,
|
||||
0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76,
|
||||
0x30, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x00, 0x12, 0x55, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x23, 0x2e, 0x6f, 0x63, 0x69,
|
||||
0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x76, 0x30, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x24, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x09, 0x44, 0x61, 0x74,
|
||||
0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e,
|
||||
0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x29, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61,
|
||||
0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x59, 0x0a,
|
||||
0x06, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30,
|
||||
0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26,
|
||||
0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xd9, 0x02, 0x5a, 0x3b, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67,
|
||||
0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x30, 0x92, 0x41, 0x98, 0x02, 0x12, 0xb3, 0x01, 0x0a,
|
||||
0x1d, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69,
|
||||
0x74, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x47,
|
||||
0x0a, 0x0d, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12,
|
||||
0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69,
|
||||
0x73, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x77, 0x6e, 0x63, 0x6c,
|
||||
0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x2a, 0x42, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68,
|
||||
0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f,
|
||||
0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73,
|
||||
0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30,
|
||||
0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x38, 0x0a, 0x10, 0x44, 0x65,
|
||||
0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x24,
|
||||
0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x65, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_ocis_services_store_v0_store_proto_rawDescOnce sync.Once
|
||||
file_ocis_services_store_v0_store_proto_rawDescData = file_ocis_services_store_v0_store_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_ocis_services_store_v0_store_proto_rawDescGZIP() []byte {
|
||||
file_ocis_services_store_v0_store_proto_rawDescOnce.Do(func() {
|
||||
file_ocis_services_store_v0_store_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_services_store_v0_store_proto_rawDescData)
|
||||
})
|
||||
return file_ocis_services_store_v0_store_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_ocis_services_store_v0_store_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_ocis_services_store_v0_store_proto_goTypes = []interface{}{
|
||||
(*ReadRequest)(nil), // 0: ocis.services.store.v0.ReadRequest
|
||||
(*ReadResponse)(nil), // 1: ocis.services.store.v0.ReadResponse
|
||||
(*WriteRequest)(nil), // 2: ocis.services.store.v0.WriteRequest
|
||||
(*WriteResponse)(nil), // 3: ocis.services.store.v0.WriteResponse
|
||||
(*DeleteRequest)(nil), // 4: ocis.services.store.v0.DeleteRequest
|
||||
(*DeleteResponse)(nil), // 5: ocis.services.store.v0.DeleteResponse
|
||||
(*ListRequest)(nil), // 6: ocis.services.store.v0.ListRequest
|
||||
(*ListResponse)(nil), // 7: ocis.services.store.v0.ListResponse
|
||||
(*DatabasesRequest)(nil), // 8: ocis.services.store.v0.DatabasesRequest
|
||||
(*DatabasesResponse)(nil), // 9: ocis.services.store.v0.DatabasesResponse
|
||||
(*TablesRequest)(nil), // 10: ocis.services.store.v0.TablesRequest
|
||||
(*TablesResponse)(nil), // 11: ocis.services.store.v0.TablesResponse
|
||||
(*v0.ReadOptions)(nil), // 12: ocis.messages.store.v0.ReadOptions
|
||||
(*v0.Record)(nil), // 13: ocis.messages.store.v0.Record
|
||||
(*v0.WriteOptions)(nil), // 14: ocis.messages.store.v0.WriteOptions
|
||||
(*v0.DeleteOptions)(nil), // 15: ocis.messages.store.v0.DeleteOptions
|
||||
(*v0.ListOptions)(nil), // 16: ocis.messages.store.v0.ListOptions
|
||||
}
|
||||
var file_ocis_services_store_v0_store_proto_depIdxs = []int32{
|
||||
12, // 0: ocis.services.store.v0.ReadRequest.options:type_name -> ocis.messages.store.v0.ReadOptions
|
||||
13, // 1: ocis.services.store.v0.ReadResponse.records:type_name -> ocis.messages.store.v0.Record
|
||||
13, // 2: ocis.services.store.v0.WriteRequest.record:type_name -> ocis.messages.store.v0.Record
|
||||
14, // 3: ocis.services.store.v0.WriteRequest.options:type_name -> ocis.messages.store.v0.WriteOptions
|
||||
15, // 4: ocis.services.store.v0.DeleteRequest.options:type_name -> ocis.messages.store.v0.DeleteOptions
|
||||
16, // 5: ocis.services.store.v0.ListRequest.options:type_name -> ocis.messages.store.v0.ListOptions
|
||||
0, // 6: ocis.services.store.v0.Store.Read:input_type -> ocis.services.store.v0.ReadRequest
|
||||
2, // 7: ocis.services.store.v0.Store.Write:input_type -> ocis.services.store.v0.WriteRequest
|
||||
4, // 8: ocis.services.store.v0.Store.Delete:input_type -> ocis.services.store.v0.DeleteRequest
|
||||
6, // 9: ocis.services.store.v0.Store.List:input_type -> ocis.services.store.v0.ListRequest
|
||||
8, // 10: ocis.services.store.v0.Store.Databases:input_type -> ocis.services.store.v0.DatabasesRequest
|
||||
10, // 11: ocis.services.store.v0.Store.Tables:input_type -> ocis.services.store.v0.TablesRequest
|
||||
1, // 12: ocis.services.store.v0.Store.Read:output_type -> ocis.services.store.v0.ReadResponse
|
||||
3, // 13: ocis.services.store.v0.Store.Write:output_type -> ocis.services.store.v0.WriteResponse
|
||||
5, // 14: ocis.services.store.v0.Store.Delete:output_type -> ocis.services.store.v0.DeleteResponse
|
||||
7, // 15: ocis.services.store.v0.Store.List:output_type -> ocis.services.store.v0.ListResponse
|
||||
9, // 16: ocis.services.store.v0.Store.Databases:output_type -> ocis.services.store.v0.DatabasesResponse
|
||||
11, // 17: ocis.services.store.v0.Store.Tables:output_type -> ocis.services.store.v0.TablesResponse
|
||||
12, // [12:18] is the sub-list for method output_type
|
||||
6, // [6:12] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_ocis_services_store_v0_store_proto_init() }
|
||||
func file_ocis_services_store_v0_store_proto_init() {
|
||||
if File_ocis_services_store_v0_store_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ReadRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ReadResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*WriteRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*WriteResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DatabasesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DatabasesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TablesRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_ocis_services_store_v0_store_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TablesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_ocis_services_store_v0_store_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_ocis_services_store_v0_store_proto_goTypes,
|
||||
DependencyIndexes: file_ocis_services_store_v0_store_proto_depIdxs,
|
||||
MessageInfos: file_ocis_services_store_v0_store_proto_msgTypes,
|
||||
}.Build()
|
||||
File_ocis_services_store_v0_store_proto = out.File
|
||||
file_ocis_services_store_v0_store_proto_rawDesc = nil
|
||||
file_ocis_services_store_v0_store_proto_goTypes = nil
|
||||
file_ocis_services_store_v0_store_proto_depIdxs = nil
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: ocis/services/store/v0/store.proto
|
||||
|
||||
package v0
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
|
||||
_ "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/store/v0"
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
api "go-micro.dev/v4/api"
|
||||
client "go-micro.dev/v4/client"
|
||||
server "go-micro.dev/v4/server"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ api.Endpoint
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Api Endpoints for Store service
|
||||
|
||||
func NewStoreEndpoints() []*api.Endpoint {
|
||||
return []*api.Endpoint{}
|
||||
}
|
||||
|
||||
// Client API for Store service
|
||||
|
||||
type StoreService interface {
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error)
|
||||
Write(ctx context.Context, in *WriteRequest, opts ...client.CallOption) (*WriteResponse, error)
|
||||
Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error)
|
||||
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (Store_ListService, error)
|
||||
Databases(ctx context.Context, in *DatabasesRequest, opts ...client.CallOption) (*DatabasesResponse, error)
|
||||
Tables(ctx context.Context, in *TablesRequest, opts ...client.CallOption) (*TablesResponse, error)
|
||||
}
|
||||
|
||||
type storeService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewStoreService(name string, c client.Client) StoreService {
|
||||
return &storeService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *storeService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.Read", in)
|
||||
out := new(ReadResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storeService) Write(ctx context.Context, in *WriteRequest, opts ...client.CallOption) (*WriteResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.Write", in)
|
||||
out := new(WriteResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storeService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.Delete", in)
|
||||
out := new(DeleteResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storeService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (Store_ListService, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.List", &ListRequest{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := stream.Send(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &storeServiceList{stream}, nil
|
||||
}
|
||||
|
||||
type Store_ListService interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
CloseSend() error
|
||||
Close() error
|
||||
Recv() (*ListResponse, error)
|
||||
}
|
||||
|
||||
type storeServiceList struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *storeServiceList) CloseSend() error {
|
||||
return x.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (x *storeServiceList) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *storeServiceList) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *storeServiceList) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *storeServiceList) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *storeServiceList) Recv() (*ListResponse, error) {
|
||||
m := new(ListResponse)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *storeService) Databases(ctx context.Context, in *DatabasesRequest, opts ...client.CallOption) (*DatabasesResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.Databases", in)
|
||||
out := new(DatabasesResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *storeService) Tables(ctx context.Context, in *TablesRequest, opts ...client.CallOption) (*TablesResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Store.Tables", in)
|
||||
out := new(TablesResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Store service
|
||||
|
||||
type StoreHandler interface {
|
||||
Read(context.Context, *ReadRequest, *ReadResponse) error
|
||||
Write(context.Context, *WriteRequest, *WriteResponse) error
|
||||
Delete(context.Context, *DeleteRequest, *DeleteResponse) error
|
||||
List(context.Context, *ListRequest, Store_ListStream) error
|
||||
Databases(context.Context, *DatabasesRequest, *DatabasesResponse) error
|
||||
Tables(context.Context, *TablesRequest, *TablesResponse) error
|
||||
}
|
||||
|
||||
func RegisterStoreHandler(s server.Server, hdlr StoreHandler, opts ...server.HandlerOption) error {
|
||||
type store interface {
|
||||
Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error
|
||||
Write(ctx context.Context, in *WriteRequest, out *WriteResponse) error
|
||||
Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error
|
||||
List(ctx context.Context, stream server.Stream) error
|
||||
Databases(ctx context.Context, in *DatabasesRequest, out *DatabasesResponse) error
|
||||
Tables(ctx context.Context, in *TablesRequest, out *TablesResponse) error
|
||||
}
|
||||
type Store struct {
|
||||
store
|
||||
}
|
||||
h := &storeHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Store{h}, opts...))
|
||||
}
|
||||
|
||||
type storeHandler struct {
|
||||
StoreHandler
|
||||
}
|
||||
|
||||
func (h *storeHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error {
|
||||
return h.StoreHandler.Read(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *storeHandler) Write(ctx context.Context, in *WriteRequest, out *WriteResponse) error {
|
||||
return h.StoreHandler.Write(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *storeHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error {
|
||||
return h.StoreHandler.Delete(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *storeHandler) List(ctx context.Context, stream server.Stream) error {
|
||||
m := new(ListRequest)
|
||||
if err := stream.Recv(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return h.StoreHandler.List(ctx, m, &storeListStream{stream})
|
||||
}
|
||||
|
||||
type Store_ListStream interface {
|
||||
Context() context.Context
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Send(*ListResponse) error
|
||||
}
|
||||
|
||||
type storeListStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *storeListStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *storeListStream) Context() context.Context {
|
||||
return x.stream.Context()
|
||||
}
|
||||
|
||||
func (x *storeListStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *storeListStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *storeListStream) Send(m *ListResponse) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (h *storeHandler) Databases(ctx context.Context, in *DatabasesRequest, out *DatabasesResponse) error {
|
||||
return h.StoreHandler.Databases(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *storeHandler) Tables(ctx context.Context, in *TablesRequest, out *TablesResponse) error {
|
||||
return h.StoreHandler.Tables(ctx, in, out)
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "ownCloud Infinite Scale store",
|
||||
"version": "1.0.0",
|
||||
"contact": {
|
||||
"name": "ownCloud GmbH",
|
||||
"url": "https://github.com/owncloud/ocis",
|
||||
"email": "support@owncloud.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache-2.0",
|
||||
"url": "https://github.com/owncloud/ocis/blob/master/LICENSE"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Store"
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {},
|
||||
"definitions": {
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"@type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0DatabasesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"databases": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0DeleteOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"table": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0DeleteResponse": {
|
||||
"type": "object"
|
||||
},
|
||||
"v0Field": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"title": "type of value e.g string, int, int64, bool, float64"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"title": "the actual value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0ListOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"table": {
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "string"
|
||||
},
|
||||
"limit": {
|
||||
"type": "string",
|
||||
"format": "uint64"
|
||||
},
|
||||
"offset": {
|
||||
"type": "string",
|
||||
"format": "uint64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0ListResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keys": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0ReadOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"table": {
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"limit": {
|
||||
"type": "string",
|
||||
"format": "uint64"
|
||||
},
|
||||
"offset": {
|
||||
"type": "string",
|
||||
"format": "uint64"
|
||||
},
|
||||
"where": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v0Field"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0ReadResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v0Record"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0Record": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string",
|
||||
"title": "key of the recorda"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"title": "value in the record"
|
||||
},
|
||||
"expiry": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "time.Duration (signed int64 nanoseconds)"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v0Field"
|
||||
},
|
||||
"title": "the associated metadata"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0TablesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0WriteOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"database": {
|
||||
"type": "string"
|
||||
},
|
||||
"table": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiry": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "time.Time"
|
||||
},
|
||||
"ttl": {
|
||||
"type": "string",
|
||||
"format": "int64",
|
||||
"title": "time.Duration"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v0WriteResponse": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"externalDocs": {
|
||||
"description": "Developer Manual",
|
||||
"url": "https://owncloud.dev/services/store/"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.40.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.43.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Activitylog Service
|
||||
# Activitylog
|
||||
|
||||
The `activitylog` service is responsible for storing events (activities) per resource.
|
||||
|
||||
@@ -13,3 +13,29 @@ Log services like the `activitylog`, `userlog`, `clientlog` and `sse` are respon
|
||||
## Activitylog Store
|
||||
|
||||
The `activitylog` stores activities for each resource. It works in conjunction with the `eventhistory` service to keep the data it needs to store to a minimum.
|
||||
|
||||
## Translations
|
||||
|
||||
The `activitylog` service has embedded translations sourced via transifex to provide a basic set of translated languages. These embedded translations are available for all deployment scenarios. In addition, the service supports custom translations, though it is currently not possible to just add custom translations to embedded ones. If custom translations are configured, the embedded ones are not used. To configure custom translations, the `ACTIVITYLOG_TRANSLATION_PATH` environment variable needs to point to a base folder that will contain the translation files. This path must be available from all instances of the activitylog service, a shared storage is recommended. Translation files must be of type [.po](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files) or [.mo](https://www.gnu.org/software/gettext/manual/html_node/Binaries.html). For each language, the filename needs to be `activitylog.po` (or `activitylog.mo`) and stored in a folder structure defining the language code. In general the path/name pattern for a translation file needs to be:
|
||||
|
||||
```text
|
||||
{ACTIVITYLOG_TRANSLATION_PATH}/{language-code}/LC_MESSAGES/activitylog.po
|
||||
```
|
||||
|
||||
The language code pattern is composed of `language[_territory]` where `language` is the base language and `_territory` is optional and defines a country.
|
||||
|
||||
For example, for the language `de`, one needs to place the corresponding translation files to `{ACTIVITYLOG_TRANSLATION_PATH}/de_DE/LC_MESSAGES/activitylog.po`.
|
||||
|
||||
<!-- also see the notifications readme -->
|
||||
|
||||
Important: For the time being, the embedded ownCloud Web frontend only supports the main language code but does not handle any territory. When strings are available in the language code `language_territory`, the web frontend does not see it as it only requests `language`. In consequence, any translations made must exist in the requested `language` to avoid a fallback to the default.
|
||||
|
||||
### Translation Rules
|
||||
|
||||
* If a requested language code is not available, the service tries to fall back to the base language if available. For example, if the requested language-code `de_DE` is not available, the service tries to fall back to translations in the `de` folder.
|
||||
* If the base language `de` is also not available, the service falls back to the system's default English (`en`),
|
||||
which is the source of the texts provided by the code.
|
||||
|
||||
## Default Language
|
||||
|
||||
The default language can be defined via the `OCIS_DEFAULT_LANGUAGE` environment variable. See the `settings` service for a detailed description.
|
||||
|
||||
@@ -26,6 +26,9 @@ type Config struct {
|
||||
HTTP HTTP `yaml:"http"`
|
||||
TokenManager *TokenManager `yaml:"token_manager"`
|
||||
|
||||
TranslationPath string `yaml:"translation_path" env:"OCIS_TRANSLATION_PATH;ACTIVITYLOG_TRANSLATION_PATH" desc:"(optional) Set this to a path with custom translations to overwrite the builtin translations. Note that file and folder naming rules apply, see the documentation for more details." introductionVersion:"%%NEXT%%"`
|
||||
DefaultLanguage string `yaml:"default_language" env:"OCIS_DEFAULT_LANGUAGE" desc:"The default language used by services and the WebUI. If not defined, English will be used as default. See the documentation for more details." introductionVersion:"%%NEXT%%"`
|
||||
|
||||
ServiceAccount ServiceAccount `yaml:"service_account"`
|
||||
|
||||
Context context.Context `yaml:"-"`
|
||||
|
||||
@@ -37,7 +37,8 @@ func DefaultConfig() *config.Config {
|
||||
Database: "activitylog",
|
||||
Table: "",
|
||||
},
|
||||
RevaGateway: shared.DefaultRevaConfig().Address,
|
||||
RevaGateway: shared.DefaultRevaConfig().Address,
|
||||
DefaultLanguage: "en",
|
||||
HTTP: config.HTTP{
|
||||
Addr: "127.0.0.1:0",
|
||||
Root: "/",
|
||||
|
||||
@@ -164,9 +164,8 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
|
||||
continue
|
||||
}
|
||||
|
||||
// FIXME: configurable default locale?
|
||||
loc := l10n.MustGetUserLocale(r.Context(), activeUser.GetId().GetOpaqueId(), r.Header.Get(l10n.HeaderAcceptLanguage), s.valService)
|
||||
t := l10n.NewTranslatorFromCommonConfig("en", _domain, "", _localeFS, _localeSubPath)
|
||||
t := l10n.NewTranslatorFromCommonConfig(s.cfg.DefaultLanguage, _domain, s.cfg.TranslationPath, _localeFS, _localeSubPath)
|
||||
|
||||
resp.Activities = append(resp.Activities, NewActivity(t.Translate(message, loc), ts, e.GetId(), vars))
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2024-08-21 05:51+0000\n"
|
||||
"POT-Creation-Date: 2024-08-22 00:53+0000\n"
|
||||
"PO-Revision-Date: 2024-08-20 10:13+0000\n"
|
||||
"Last-Translator: Martin <github@diemattels.at>, 2024\n"
|
||||
"Language-Team: German (https://app.transifex.com/owncloud-org/teams/6149/de/)\n"
|
||||
@@ -23,15 +23,15 @@ msgstr ""
|
||||
|
||||
#: pkg/service/response.go:23
|
||||
msgid "{user} added {resource} to {space}"
|
||||
msgstr "{user} hat {resource} zum {space} hinzugefügt"
|
||||
msgstr "{user} hat {resource} zu {space} hinzugefügt"
|
||||
|
||||
#: pkg/service/response.go:31
|
||||
msgid "{user} added {sharee} as member of {space}"
|
||||
msgstr "{user} hat {sharee} als Mitglied zum {space} hinzugefügt"
|
||||
msgstr "{user} hat {sharee} als Mitglied zu {space} hinzugefügt"
|
||||
|
||||
#: pkg/service/response.go:24
|
||||
msgid "{user} deleted {resource} from {space}"
|
||||
msgstr "{user} hat {resource} vom {space} gelöscht"
|
||||
msgstr "{user} hat {resource} in {space} gelöscht"
|
||||
|
||||
#: pkg/service/response.go:25
|
||||
msgid "{user} moved {resource} to {space}"
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
# Translators:
|
||||
# Viktor Scharf, 2024
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2024-08-24 00:53+0000\n"
|
||||
"PO-Revision-Date: 2024-08-20 10:13+0000\n"
|
||||
"Last-Translator: Viktor Scharf, 2024\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/owncloud-org/teams/6149/ru/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ru\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
|
||||
|
||||
#: pkg/service/response.go:23
|
||||
msgid "{user} added {resource} to {space}"
|
||||
msgstr "{user} добавил {resource} в {space}"
|
||||
|
||||
#: pkg/service/response.go:31
|
||||
msgid "{user} added {sharee} as member of {space}"
|
||||
msgstr "{user} добавил {sharee} как участника {space}"
|
||||
|
||||
#: pkg/service/response.go:24
|
||||
msgid "{user} deleted {resource} from {space}"
|
||||
msgstr "{user} удалил {resource} из {space}"
|
||||
|
||||
#: pkg/service/response.go:25
|
||||
msgid "{user} moved {resource} to {space}"
|
||||
msgstr "{user} переместил {resource} в {space}"
|
||||
|
||||
#: pkg/service/response.go:30
|
||||
msgid "{user} removed link to {resource}"
|
||||
msgstr "{user} удалил ссылку на {resource}"
|
||||
|
||||
#: pkg/service/response.go:28
|
||||
msgid "{user} removed {sharee} from {resource}"
|
||||
msgstr "{user} удалил {sharee} из {resource}"
|
||||
|
||||
#: pkg/service/response.go:32
|
||||
msgid "{user} removed {sharee} from {space}"
|
||||
msgstr "{user} удалил {sharee} из {space}"
|
||||
|
||||
#: pkg/service/response.go:26
|
||||
msgid "{user} renamed {oldResource} to {resource}"
|
||||
msgstr "{user} переименовал {oldResource} в {resource}"
|
||||
|
||||
#: pkg/service/response.go:29
|
||||
msgid "{user} shared {resource} via link"
|
||||
msgstr "{user} поделился {resource} через ссылку"
|
||||
|
||||
#: pkg/service/response.go:27
|
||||
msgid "{user} shared {resource} with {sharee}"
|
||||
msgstr "{user} поделился {resource} с {sharee}"
|
||||
@@ -0,0 +1,62 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
# Translators:
|
||||
# Besnik Bleta <besnik@programeshqip.org>, 2024
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2024-08-22 00:53+0000\n"
|
||||
"PO-Revision-Date: 2024-08-20 10:13+0000\n"
|
||||
"Last-Translator: Besnik Bleta <besnik@programeshqip.org>, 2024\n"
|
||||
"Language-Team: Albanian (https://app.transifex.com/owncloud-org/teams/6149/sq/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: sq\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: pkg/service/response.go:23
|
||||
msgid "{user} added {resource} to {space}"
|
||||
msgstr "{user} shtoi {resource} te {space}"
|
||||
|
||||
#: pkg/service/response.go:31
|
||||
msgid "{user} added {sharee} as member of {space}"
|
||||
msgstr "{user} shtoi {sharee} si anëtar të {space}"
|
||||
|
||||
#: pkg/service/response.go:24
|
||||
msgid "{user} deleted {resource} from {space}"
|
||||
msgstr "{user} fshiu {resource} nga {space}"
|
||||
|
||||
#: pkg/service/response.go:25
|
||||
msgid "{user} moved {resource} to {space}"
|
||||
msgstr "{user} e shpuri {resource} te {space}"
|
||||
|
||||
#: pkg/service/response.go:30
|
||||
msgid "{user} removed link to {resource}"
|
||||
msgstr "{user} hoqi lidhjen për te {resource}"
|
||||
|
||||
#: pkg/service/response.go:28
|
||||
msgid "{user} removed {sharee} from {resource}"
|
||||
msgstr "{user} hoqi {sharee} nga {resource}"
|
||||
|
||||
#: pkg/service/response.go:32
|
||||
msgid "{user} removed {sharee} from {space}"
|
||||
msgstr "{user} hoqi {sharee} nga {space}"
|
||||
|
||||
#: pkg/service/response.go:26
|
||||
msgid "{user} renamed {oldResource} to {resource}"
|
||||
msgstr "{user} riemërtoi {oldResource} si {resource}"
|
||||
|
||||
#: pkg/service/response.go:29
|
||||
msgid "{user} shared {resource} via link"
|
||||
msgstr "{user} ndau me të tjerët {resource} përmes lidhjeje"
|
||||
|
||||
#: pkg/service/response.go:27
|
||||
msgid "{user} shared {resource} with {sharee}"
|
||||
msgstr "{user} ndau {resource} me {sharee}"
|
||||
@@ -99,6 +99,7 @@ func WithTrashedResource(ref *provider.Reference, rid *provider.ResourceId) Acti
|
||||
|
||||
resp, err := gwc.ListRecycle(ctx, &provider.ListRecycleRequest{
|
||||
Ref: ref,
|
||||
Key: rid.GetOpaqueId(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -81,7 +81,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"APP_PROVIDER_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;APP_PROVIDER_GRPC_PROTOCOL" desc:"The transport protocol of the GPRC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
type Drivers struct {
|
||||
|
||||
@@ -76,7 +76,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
cancel()
|
||||
})
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"APP_REGISTRY_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;APP_REGISTRY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
type AppRegistry struct {
|
||||
|
||||
@@ -89,7 +89,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"AUTH_APP_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"%%NEXT%%"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"AUTH_APP_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"%%NEXT%%"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;AUTH_APP_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"%%NEXT%%"`
|
||||
}
|
||||
|
||||
// HTTP defines the available http configuration.
|
||||
|
||||
@@ -94,7 +94,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"AUTH_BASIC_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;AUTH_BASIC_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
type AuthProviders struct {
|
||||
|
||||
@@ -81,7 +81,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"AUTH_BEARER_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"AUTH_BEARER_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;AUTH_BEARER_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
type OIDC struct {
|
||||
|
||||
@@ -81,7 +81,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -48,5 +48,5 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"AUTH_MACHINE_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;AUTH_MACHINE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
sync.Trap(&gr, cancel)
|
||||
}
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"AUTH_SERVICE_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"AUTH_SERVICE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;AUTH_SERVICE_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"5.0"`
|
||||
}
|
||||
|
||||
// ServiceAccount is the configuration for the used service account
|
||||
|
||||
@@ -221,6 +221,7 @@ func processShareEvent(ctx context.Context, ref *provider.Reference, gwc gateway
|
||||
func processItemTrashedEvent(ctx context.Context, ref *provider.Reference, gwc gateway.GatewayAPIClient, initiatorid string, itemID *provider.ResourceId) ([]string, FileEvent, error) {
|
||||
resp, err := gwc.ListRecycle(ctx, &provider.ListRecycleRequest{
|
||||
Ref: ref,
|
||||
Key: itemID.GetOpaqueId(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, FileEvent{}, err
|
||||
|
||||
@@ -33,6 +33,7 @@ func DefaultConfig() *config.Config {
|
||||
},
|
||||
GRPC: config.GRPC{
|
||||
Addr: "127.0.0.1:9301",
|
||||
Protocol: "tcp",
|
||||
Namespace: "com.owncloud.api",
|
||||
},
|
||||
HTTP: config.HTTP{
|
||||
|
||||
@@ -2,6 +2,8 @@ package config
|
||||
|
||||
// GRPC defines the available grpc configuration.
|
||||
type GRPC struct {
|
||||
Addr string `yaml:"addr" env:"COLLABORATION_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"6.0.0"`
|
||||
Addr string `yaml:"addr" env:"COLLABORATION_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"6.0.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;COLLABORATION_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"%%NEXT%%"`
|
||||
|
||||
Namespace string `yaml:"-"`
|
||||
}
|
||||
|
||||
@@ -52,10 +52,8 @@ var _ = Describe("ContentConnector", func() {
|
||||
},
|
||||
Path: ".",
|
||||
},
|
||||
User: &userv1beta1.User{}, // Not used for now
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
EditAppUrl: "http://test.ex.prv/edit",
|
||||
ViewAppUrl: "http://test.ex.prv/view",
|
||||
User: &userv1beta1.User{}, // Not used for now
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
}
|
||||
|
||||
randomContent = "This is the content of the test.txt file"
|
||||
@@ -186,10 +184,8 @@ var _ = Describe("ContentConnector", func() {
|
||||
},
|
||||
Path: ".",
|
||||
},
|
||||
User: &userv1beta1.User{}, // Not used for now
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_VIEW_ONLY,
|
||||
EditAppUrl: "http://test.ex.prv/edit",
|
||||
ViewAppUrl: "http://test.ex.prv/view",
|
||||
User: &userv1beta1.User{}, // Not used for now
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_VIEW_ONLY,
|
||||
}
|
||||
|
||||
ctx := middleware.WopiContextToCtx(context.Background(), wopiCtx)
|
||||
|
||||
@@ -1050,8 +1050,9 @@ func (f *FileConnector) CheckFileInfo(ctx context.Context) (*ConnectorResponse,
|
||||
// to get the folder we actually need to do a GetPath() request
|
||||
//BreadcrumbFolderName: path.Dir(statRes.Info.Path),
|
||||
|
||||
fileinfo.KeyHostViewURL: wopiContext.ViewAppUrl,
|
||||
fileinfo.KeyHostEditURL: wopiContext.EditAppUrl,
|
||||
// TODO: these URLs must point to ocis, which is hosting the editor's iframe
|
||||
//fileinfo.KeyHostViewURL: wopiContext.ViewAppUrl,
|
||||
//fileinfo.KeyHostEditURL: wopiContext.EditAppUrl,
|
||||
|
||||
fileinfo.KeyEnableOwnerTermination: true, // only for collabora
|
||||
fileinfo.KeySupportsExtendedLockLength: true,
|
||||
@@ -1061,7 +1062,6 @@ func (f *FileConnector) CheckFileInfo(ctx context.Context) (*ConnectorResponse,
|
||||
fileinfo.KeySupportsDeleteFile: true,
|
||||
fileinfo.KeySupportsRename: true,
|
||||
|
||||
//fileinfo.KeyUserCanNotWriteRelative: true,
|
||||
fileinfo.KeyIsAnonymousUser: isAnonymousUser,
|
||||
fileinfo.KeyUserFriendlyName: userFriendlyName,
|
||||
fileinfo.KeyUserID: userId,
|
||||
|
||||
@@ -82,9 +82,7 @@ var _ = Describe("FileConnector", func() {
|
||||
// },
|
||||
//},
|
||||
},
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
EditAppUrl: "http://test.ex.prv/edit",
|
||||
ViewAppUrl: "http://test.ex.prv/view",
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1546,8 +1544,6 @@ var _ = Describe("FileConnector", func() {
|
||||
BaseFileName: "test.txt",
|
||||
BreadcrumbDocName: "test.txt",
|
||||
UserCanNotWriteRelative: false,
|
||||
HostViewURL: "http://test.ex.prv/view",
|
||||
HostEditURL: "http://test.ex.prv/edit",
|
||||
SupportsExtendedLockLength: true,
|
||||
SupportsGetLock: true,
|
||||
SupportsLocks: true,
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// There are no explicit requirements for the context, and it will be passed
|
||||
// without changes to the underlying RegisterService method.
|
||||
func RegisterOcisService(ctx context.Context, cfg *config.Config, logger log.Logger) error {
|
||||
svc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name+"."+cfg.App.Name, cfg.GRPC.Addr, version.GetString())
|
||||
svc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name+"."+cfg.App.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
return registry.RegisterService(ctx, svc, logger)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package middleware
|
||||
|
||||
import "github.com/golang-jwt/jwt/v4"
|
||||
import "github.com/golang-jwt/jwt/v5"
|
||||
|
||||
// Claims contains the jwt registered claims plus the used WOPI context
|
||||
type Claims struct {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/helpers"
|
||||
"github.com/rs/zerolog"
|
||||
@@ -31,8 +31,6 @@ type WopiContext struct {
|
||||
FileReference *providerv1beta1.Reference
|
||||
User *userv1beta1.User
|
||||
ViewMode appproviderv1beta1.ViewMode
|
||||
EditAppUrl string
|
||||
ViewAppUrl string
|
||||
}
|
||||
|
||||
// WopiContextAuthMiddleware will prepare an HTTP handler to be used as
|
||||
@@ -71,11 +69,6 @@ func WopiContextAuthMiddleware(cfg *config.Config, next http.Handler) http.Handl
|
||||
return
|
||||
}
|
||||
|
||||
if err := claims.Valid(); err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
wopiContextAccessToken, err := DecryptAES([]byte(cfg.Wopi.Secret), claims.WopiContext.AccessToken)
|
||||
|
||||
@@ -2,10 +2,11 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
appproviderv1beta1 "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
||||
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
@@ -80,147 +81,47 @@ func (s *Service) OpenInApp(
|
||||
Path: ".",
|
||||
}
|
||||
|
||||
// build a urlsafe and stable file reference that can be used for proxy routing,
|
||||
// so that all sessions on one file end on the same office server
|
||||
fileRef := helpers.HashResourceId(req.GetResourceInfo().GetId())
|
||||
logger := s.logger.With().
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).
|
||||
Logger()
|
||||
|
||||
// get the file extension to use the right wopi app url
|
||||
fileExt := path.Ext(req.GetResourceInfo().GetPath())
|
||||
|
||||
var viewCommentAppURL string
|
||||
var viewAppURL string
|
||||
var editAppURL string
|
||||
if viewCommentAppURLs, ok := s.appURLs["view_comment"]; ok {
|
||||
if u, ok := viewCommentAppURLs[fileExt]; ok {
|
||||
viewCommentAppURL = u
|
||||
}
|
||||
}
|
||||
if viewAppURLs, ok := s.appURLs["view"]; ok {
|
||||
if u, ok := viewAppURLs[fileExt]; ok {
|
||||
viewAppURL = u
|
||||
}
|
||||
}
|
||||
if editAppURLs, ok := s.appURLs["edit"]; ok {
|
||||
if u, ok := editAppURLs[fileExt]; ok {
|
||||
editAppURL = u
|
||||
}
|
||||
}
|
||||
if editAppURL == "" && viewAppURL == "" && viewCommentAppURL == "" {
|
||||
err := fmt.Errorf("OpenInApp: neither edit nor view app url found")
|
||||
s.logger.Error().
|
||||
Err(err).
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).Send()
|
||||
return nil, err
|
||||
// get the appURL we need to use
|
||||
appURL := s.getAppUrl(fileExt, req.GetViewMode())
|
||||
if appURL == "" {
|
||||
logger.Error().Msg("OpenInApp: neither edit nor view app URL found")
|
||||
return nil, errors.New("neither edit nor view app URL found")
|
||||
}
|
||||
|
||||
if editAppURL == "" {
|
||||
// assuming that an view action is always available in the /hosting/discovery manifest
|
||||
// eg. Collabora does support viewing jpgs but no editing
|
||||
// eg. OnlyOffice does support viewing pdfs but no editing
|
||||
// there is no known case of supporting edit only without view
|
||||
editAppURL = viewAppURL
|
||||
}
|
||||
if viewAppURL == "" {
|
||||
// the URL of the end-user application in view mode when different (defaults to edit mod URL)
|
||||
viewAppURL = editAppURL
|
||||
}
|
||||
// TODO: check if collabora will support an "edit" url in the future
|
||||
if viewAppURL == "" && editAppURL == "" && viewCommentAppURL != "" {
|
||||
// there are rare cases where neither view nor edit is supported but view_comment is
|
||||
viewAppURL = viewCommentAppURL
|
||||
// that can be the case for editable and viewable files
|
||||
if req.GetViewMode() == appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE {
|
||||
editAppURL = viewCommentAppURL
|
||||
}
|
||||
}
|
||||
wopiSrcURL, err := url.Parse(s.config.Wopi.WopiSrc)
|
||||
// append the parameters we need
|
||||
appURL, err = s.addQueryToURL(appURL, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wopiSrcURL.Path = path.Join("wopi", "files", fileRef)
|
||||
|
||||
addWopiSrcQueryParam := func(baseURL string) (string, error) {
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Add("WOPISrc", wopiSrcURL.String())
|
||||
|
||||
if s.config.Wopi.DisableChat {
|
||||
q.Add("dchat", "1")
|
||||
}
|
||||
|
||||
lang := utils.ReadPlainFromOpaque(req.GetOpaque(), "lang")
|
||||
|
||||
if lang != "" {
|
||||
q.Add("ui", lang) // OnlyOffice
|
||||
q.Add("lang", lang) // Collabora, Impact on the default document language of OnlyOffice
|
||||
q.Add("UI_LLCC", lang) // Office365
|
||||
}
|
||||
qs := q.Encode()
|
||||
u.RawQuery = qs
|
||||
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
viewAppURL, err = addWopiSrcQueryParam(viewAppURL)
|
||||
if err != nil {
|
||||
s.logger.Error().
|
||||
Err(err).
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).
|
||||
Msg("OpenInApp: error parsing viewAppUrl")
|
||||
return nil, err
|
||||
}
|
||||
editAppURL, err = addWopiSrcQueryParam(editAppURL)
|
||||
if err != nil {
|
||||
s.logger.Error().
|
||||
Err(err).
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).
|
||||
Msg("OpenInApp: error parsing editAppUrl")
|
||||
logger.Error().Err(err).Msg("OpenInApp: error parsing appUrl")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
appURL := viewAppURL
|
||||
if req.GetViewMode() == appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE {
|
||||
appURL = editAppURL
|
||||
}
|
||||
|
||||
// create the wopiContext and generate the token
|
||||
wopiContext := middleware.WopiContext{
|
||||
AccessToken: req.GetAccessToken(), // it will be encrypted
|
||||
ViewOnlyToken: utils.ReadPlainFromOpaque(req.GetOpaque(), "viewOnlyToken"),
|
||||
FileReference: &providerFileRef,
|
||||
User: user,
|
||||
ViewMode: req.GetViewMode(),
|
||||
EditAppUrl: editAppURL,
|
||||
ViewAppUrl: viewAppURL,
|
||||
}
|
||||
|
||||
accessToken, accessExpiration, err := middleware.GenerateWopiToken(wopiContext, s.config)
|
||||
if err != nil {
|
||||
s.logger.Error().
|
||||
Err(err).
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).
|
||||
Msg("OpenInApp: error generating the token")
|
||||
logger.Error().Err(err).Msg("OpenInApp: error generating the token")
|
||||
return &appproviderv1beta1.OpenInAppResponse{
|
||||
Status: &rpcv1beta1.Status{Code: rpcv1beta1.Code_CODE_INTERNAL},
|
||||
}, err
|
||||
}
|
||||
|
||||
s.logger.Debug().
|
||||
Str("FileReference", providerFileRef.String()).
|
||||
Str("ViewMode", req.GetViewMode().String()).
|
||||
Str("Requester", user.GetId().String()).
|
||||
Msg("OpenInApp: success")
|
||||
logger.Debug().Msg("OpenInApp: success")
|
||||
|
||||
return &appproviderv1beta1.OpenInAppResponse{
|
||||
Status: &rpcv1beta1.Status{Code: rpcv1beta1.Code_CODE_OK},
|
||||
@@ -237,3 +138,97 @@ func (s *Service) OpenInApp(
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getAppUrlFor gets the appURL from the list of appURLs based on the
|
||||
// action and file extension provided. If there is no match, an empty
|
||||
// string will be returned.
|
||||
func (s *Service) getAppUrlFor(action, fileExt string) string {
|
||||
if actionURL, ok := s.appURLs[action]; ok {
|
||||
if actionExtensionURL, ok := actionURL[fileExt]; ok {
|
||||
return actionExtensionURL
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// getAppUrl will get the appURL that should be used based on the extension
|
||||
// and the provided view mode.
|
||||
// "view" urls will be chosen first, then if the view mode is "read/write",
|
||||
// "edit" urls will be prioritized. Note that "view" url might be returned for
|
||||
// "read/write" view mode if no "edit" url is found.
|
||||
func (s *Service) getAppUrl(fileExt string, viewMode appproviderv1beta1.ViewMode) string {
|
||||
// prioritize view action if possible
|
||||
appURL := s.getAppUrlFor("view", fileExt)
|
||||
|
||||
if strings.ToLower(s.config.App.Name) == "collabora" {
|
||||
// collabora provides only one action per extension. usual options
|
||||
// are "view" (checked above), "edit" or "view_comment" (this last one
|
||||
// is exclusive of collabora)
|
||||
if appURL == "" {
|
||||
if editURL := s.getAppUrlFor("edit", fileExt); editURL != "" {
|
||||
return editURL
|
||||
}
|
||||
if commentURL := s.getAppUrlFor("view_comment", fileExt); commentURL != "" {
|
||||
return commentURL
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If not collabora, there might be an edit action for the extension.
|
||||
// If read/write mode has been requested, prioritize edit action.
|
||||
if viewMode == appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE {
|
||||
if editAppURL := s.getAppUrlFor("edit", fileExt); editAppURL != "" {
|
||||
appURL = editAppURL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return appURL
|
||||
}
|
||||
|
||||
// addQueryToURL will add specific query parameters to the baseURL. These
|
||||
// parameters are:
|
||||
// * "WOPISrc" pointing to the requested resource in the OpenInAppRequest
|
||||
// * "dchat" to disable the chat, based on configuration
|
||||
// * "lang" (WOPI app dependent) with the language in the request. "lang"
|
||||
// for collabora, "ui" for onlyoffice and "UI_LLCC" for the rest
|
||||
func (s *Service) addQueryToURL(baseURL string, req *appproviderv1beta1.OpenInAppRequest) (string, error) {
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// build a urlsafe and stable file reference that can be used for proxy routing,
|
||||
// so that all sessions on one file end on the same office server
|
||||
fileRef := helpers.HashResourceId(req.GetResourceInfo().GetId())
|
||||
|
||||
wopiSrcURL, err := url.Parse(s.config.Wopi.WopiSrc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
wopiSrcURL.Path = path.Join("wopi", "files", fileRef)
|
||||
|
||||
q := u.Query()
|
||||
q.Add("WOPISrc", wopiSrcURL.String())
|
||||
|
||||
if s.config.Wopi.DisableChat {
|
||||
q.Add("dchat", "1")
|
||||
}
|
||||
|
||||
lang := utils.ReadPlainFromOpaque(req.GetOpaque(), "lang")
|
||||
|
||||
if lang != "" {
|
||||
switch strings.ToLower(s.config.App.Name) {
|
||||
case "collabora":
|
||||
q.Add("lang", lang)
|
||||
case "onlyoffice":
|
||||
q.Add("ui", lang)
|
||||
default:
|
||||
q.Add("UI_LLCC", lang)
|
||||
}
|
||||
}
|
||||
|
||||
qs := q.Encode()
|
||||
u.RawQuery = qs
|
||||
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@@ -136,133 +136,66 @@ var _ = Describe("Discovery", func() {
|
||||
Expect(resp).To(BeNil())
|
||||
})
|
||||
|
||||
It("Success", func() {
|
||||
ctx := context.Background()
|
||||
nowTime := time.Now()
|
||||
DescribeTable(
|
||||
"Success",
|
||||
func(appName, lang string, disableChat bool, expectedAppUrl string) {
|
||||
ctx := context.Background()
|
||||
nowTime := time.Now()
|
||||
|
||||
cfg.Wopi.WopiSrc = "https://wopiserver.test.prv"
|
||||
cfg.Wopi.Secret = "my_supa_secret"
|
||||
cfg.Wopi.WopiSrc = "https://wopiserver.test.prv"
|
||||
cfg.Wopi.Secret = "my_supa_secret"
|
||||
cfg.Wopi.DisableChat = disableChat
|
||||
cfg.App.Name = appName
|
||||
|
||||
myself := &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
Idp: "myIdp",
|
||||
OpaqueId: "opaque001",
|
||||
Type: userv1beta1.UserType_USER_TYPE_PRIMARY,
|
||||
},
|
||||
Username: "username",
|
||||
}
|
||||
|
||||
req := &appproviderv1beta1.OpenInAppRequest{
|
||||
ResourceInfo: &providerv1beta1.ResourceInfo{
|
||||
Id: &providerv1beta1.ResourceId{
|
||||
StorageId: "myStorage",
|
||||
OpaqueId: "storageOpaque001",
|
||||
SpaceId: "SpaceA",
|
||||
myself := &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
Idp: "myIdp",
|
||||
OpaqueId: "opaque001",
|
||||
Type: userv1beta1.UserType_USER_TYPE_PRIMARY,
|
||||
},
|
||||
Path: "/path/to/file.docx",
|
||||
},
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
AccessToken: MintToken(myself, cfg.Wopi.Secret, nowTime),
|
||||
}
|
||||
req.Opaque = utils.AppendPlainToOpaque(req.Opaque, "lang", "de")
|
||||
Username: "username",
|
||||
}
|
||||
|
||||
gatewayClient.On("WhoAmI", mock.Anything, mock.Anything).Times(1).Return(&gatewayv1beta1.WhoAmIResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
User: myself,
|
||||
}, nil)
|
||||
|
||||
resp, err := srv.OpenInApp(ctx, req)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(resp.GetStatus().GetCode()).To(Equal(rpcv1beta1.Code_CODE_OK))
|
||||
Expect(resp.GetAppUrl().GetMethod()).To(Equal("POST"))
|
||||
Expect(resp.GetAppUrl().GetAppUrl()).To(Equal("https://test.server.prv/hosting/wopi/word/edit?UI_LLCC=de&WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&lang=de&ui=de"))
|
||||
Expect(resp.GetAppUrl().GetFormParameters()["access_token_ttl"]).To(Equal(strconv.FormatInt(nowTime.Add(5*time.Hour).Unix()*1000, 10)))
|
||||
})
|
||||
|
||||
It("Success", func() {
|
||||
ctx := context.Background()
|
||||
nowTime := time.Now()
|
||||
|
||||
cfg.Wopi.WopiSrc = "https://wopiserver.test.prv"
|
||||
cfg.Wopi.Secret = "my_supa_secret"
|
||||
cfg.Wopi.DisableChat = true
|
||||
|
||||
myself := &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
Idp: "myIdp",
|
||||
OpaqueId: "opaque001",
|
||||
Type: userv1beta1.UserType_USER_TYPE_PRIMARY,
|
||||
},
|
||||
Username: "username",
|
||||
}
|
||||
|
||||
req := &appproviderv1beta1.OpenInAppRequest{
|
||||
ResourceInfo: &providerv1beta1.ResourceInfo{
|
||||
Id: &providerv1beta1.ResourceId{
|
||||
StorageId: "myStorage",
|
||||
OpaqueId: "storageOpaque001",
|
||||
SpaceId: "SpaceA",
|
||||
req := &appproviderv1beta1.OpenInAppRequest{
|
||||
ResourceInfo: &providerv1beta1.ResourceInfo{
|
||||
Id: &providerv1beta1.ResourceId{
|
||||
StorageId: "myStorage",
|
||||
OpaqueId: "storageOpaque001",
|
||||
SpaceId: "SpaceA",
|
||||
},
|
||||
Path: "/path/to/file.docx",
|
||||
},
|
||||
Path: "/path/to/file.docx",
|
||||
},
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
AccessToken: MintToken(myself, cfg.Wopi.Secret, nowTime),
|
||||
}
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
AccessToken: MintToken(myself, cfg.Wopi.Secret, nowTime),
|
||||
}
|
||||
if lang != "" {
|
||||
req.Opaque = utils.AppendPlainToOpaque(req.Opaque, "lang", lang)
|
||||
}
|
||||
|
||||
gatewayClient.On("WhoAmI", mock.Anything, mock.Anything).Times(1).Return(&gatewayv1beta1.WhoAmIResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
User: myself,
|
||||
}, nil)
|
||||
gatewayClient.On("WhoAmI", mock.Anything, mock.Anything).Times(1).Return(&gatewayv1beta1.WhoAmIResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
User: myself,
|
||||
}, nil)
|
||||
|
||||
resp, err := srv.OpenInApp(ctx, req)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(resp.GetStatus().GetCode()).To(Equal(rpcv1beta1.Code_CODE_OK))
|
||||
Expect(resp.GetAppUrl().GetMethod()).To(Equal("POST"))
|
||||
Expect(resp.GetAppUrl().GetAppUrl()).To(Equal("https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"))
|
||||
Expect(resp.GetAppUrl().GetFormParameters()["access_token_ttl"]).To(Equal(strconv.FormatInt(nowTime.Add(5*time.Hour).Unix()*1000, 10)))
|
||||
})
|
||||
|
||||
It("Success", func() {
|
||||
ctx := context.Background()
|
||||
nowTime := time.Now()
|
||||
|
||||
cfg.Wopi.WopiSrc = "https://wopiserver.test.prv"
|
||||
cfg.Wopi.Secret = "my_supa_secret"
|
||||
cfg.Wopi.DisableChat = true
|
||||
|
||||
myself := &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
Idp: "myIdp",
|
||||
OpaqueId: "opaque001",
|
||||
Type: userv1beta1.UserType_USER_TYPE_PRIMARY,
|
||||
},
|
||||
Username: "username",
|
||||
}
|
||||
|
||||
req := &appproviderv1beta1.OpenInAppRequest{
|
||||
ResourceInfo: &providerv1beta1.ResourceInfo{
|
||||
Id: &providerv1beta1.ResourceId{
|
||||
StorageId: "myStorage",
|
||||
OpaqueId: "storageOpaque001",
|
||||
SpaceId: "SpaceA",
|
||||
},
|
||||
Path: "/path/to/file.docx",
|
||||
},
|
||||
ViewMode: appproviderv1beta1.ViewMode_VIEW_MODE_READ_WRITE,
|
||||
AccessToken: MintToken(myself, cfg.Wopi.Secret, nowTime),
|
||||
}
|
||||
|
||||
gatewayClient.On("WhoAmI", mock.Anything, mock.Anything).Times(1).Return(&gatewayv1beta1.WhoAmIResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
User: myself,
|
||||
}, nil)
|
||||
|
||||
resp, err := srv.OpenInApp(ctx, req)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(resp.GetStatus().GetCode()).To(Equal(rpcv1beta1.Code_CODE_OK))
|
||||
Expect(resp.GetAppUrl().GetMethod()).To(Equal("POST"))
|
||||
Expect(resp.GetAppUrl().GetAppUrl()).To(Equal("https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"))
|
||||
Expect(resp.GetAppUrl().GetFormParameters()["access_token_ttl"]).To(Equal(strconv.FormatInt(nowTime.Add(5*time.Hour).Unix()*1000, 10)))
|
||||
})
|
||||
resp, err := srv.OpenInApp(ctx, req)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(resp.GetStatus().GetCode()).To(Equal(rpcv1beta1.Code_CODE_OK))
|
||||
Expect(resp.GetAppUrl().GetMethod()).To(Equal("POST"))
|
||||
Expect(resp.GetAppUrl().GetAppUrl()).To(Equal(expectedAppUrl))
|
||||
Expect(resp.GetAppUrl().GetFormParameters()["access_token_ttl"]).To(Equal(strconv.FormatInt(nowTime.Add(5*time.Hour).Unix()*1000, 10)))
|
||||
},
|
||||
Entry("Microsoft chat no lang", "Microsoft", "", false, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e"),
|
||||
Entry("Collabora chat no lang", "Collabora", "", false, "https://test.server.prv/hosting/wopi/word/view?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e"),
|
||||
Entry("OnlyOffice chat no lang", "OnlyOffice", "", false, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e"),
|
||||
Entry("Microsoft chat lang", "Microsoft", "de", false, "https://test.server.prv/hosting/wopi/word/edit?UI_LLCC=de&WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e"),
|
||||
Entry("Collabora chat lang", "Collabora", "de", false, "https://test.server.prv/hosting/wopi/word/view?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&lang=de"),
|
||||
Entry("OnlyOffice chat lang", "OnlyOffice", "de", false, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&ui=de"),
|
||||
Entry("Microsoft no chat no lang", "Microsoft", "", true, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"),
|
||||
Entry("Collabora no chat no lang", "Collabora", "", true, "https://test.server.prv/hosting/wopi/word/view?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"),
|
||||
Entry("OnlyOffice no chat no lang", "OnlyOffice", "", true, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"),
|
||||
Entry("Microsoft no chat lang", "Microsoft", "de", true, "https://test.server.prv/hosting/wopi/word/edit?UI_LLCC=de&WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1"),
|
||||
Entry("Collabora no chat lang", "Collabora", "de", true, "https://test.server.prv/hosting/wopi/word/view?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1&lang=de"),
|
||||
Entry("OnlyOffice no chat lang", "OnlyOffice", "de", true, "https://test.server.prv/hosting/wopi/word/edit?WOPISrc=https%3A%2F%2Fwopiserver.test.prv%2Fwopi%2Ffiles%2F2f6ec18696dd1008106749bd94106e5cfad5c09e15de7b77088d03843e71b43e&dchat=1&ui=de"),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,7 +31,74 @@ Store specific notes:
|
||||
- When using `nats-js-kv` it is recommended to set `OCIS_CACHE_STORE_NODES` to the same value as `OCIS_EVENTS_ENDPOINT`. That way the cache uses the same nats instance as the event bus.
|
||||
- When using the `nats-js-kv` store, it is possible to set `OCIS_CACHE_DISABLE_PERSISTENCE` to instruct nats to not persist cache data on disc.
|
||||
|
||||
## Storage registry
|
||||
## Service Endpoints
|
||||
|
||||
**IMPORTANT**\
|
||||
This functionality is currently experimental.
|
||||
|
||||
The gateway acts as a proxy for other CS3 services. As such it has to forward requests to a lot of services and needs to establish connections by looking up the IP address using the service registry. Instead of using the service registry each endpoint can also be configured to use the grpc `dns://` or `kubernetes://` URLs, which might be useful when running in kubernetes.
|
||||
|
||||
For a local single node deployment you might want to use `unix:` sockets as shown below. Using unix sockets will reduce the amount of service lookups and omit the TCP stack. For now, this is experimental and the services do not delete the socket on shutdown. PRs welcome.
|
||||
|
||||
```console
|
||||
USERS_GRPC_PROTOCOL=unix"
|
||||
USERS_GRPC_ADDR=/var/run/ocis/users.sock"
|
||||
GATEWAY_USERS_ENDPOINT=unix:/var/run/ocis/users.sock"
|
||||
|
||||
GROUPS_GRPC_PROTOCOL=unix"
|
||||
GROUPS_GRPC_ADDR=/var/run/ocis/groups.sock"
|
||||
GATEWAY_GROUPS_ENDPOINT=unix:/var/run/ocis/groups.sock"
|
||||
|
||||
AUTH_APP_GRPC_PROTOCOL=unix"
|
||||
AUTH_APP_GRPC_ADDR=/var/run/ocis/auth-app.sock"
|
||||
GATEWAY_AUTH_APP_ENDPOINT=unix:/var/run/ocis/auth-app.sock"
|
||||
|
||||
AUTH_BASIC_GRPC_PROTOCOL=unix"
|
||||
AUTH_BASIC_GRPC_ADDR=/var/run/ocis/auth-basic.sock"
|
||||
GATEWAY_AUTH_BASIC_ENDPOINT=unix:/var/run/ocis/auth-basic.sock"
|
||||
|
||||
AUTH_MACHINE_GRPC_PROTOCOL=unix"
|
||||
AUTH_MACHINE_GRPC_ADDR=/var/run/ocis/auth-machine.sock"
|
||||
GATEWAY_AUTH_MACHINE_ENDPOINT=unix:/var/run/ocis/auth-machine.sock"
|
||||
|
||||
AUTH_SERVICE_GRPC_PROTOCOL=unix"
|
||||
AUTH_SERVICE_GRPC_ADDR=/var/run/ocis/auth-service.sock"
|
||||
GATEWAY_AUTH_SERVICE_ENDPOINT=unix:/var/run/ocis/auth-service.sock"
|
||||
|
||||
STORAGE_PUBLIC_LINK_GRPC_PROTOCOL=unix"
|
||||
STORAGE_PUBLIC_LINK_GRPC_ADDR=/var/run/ocis/storage-public-link.sock"
|
||||
GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT=unix:/var/run/ocis/storage-public-link.sock"
|
||||
|
||||
STORAGE_USERS_GRPC_PROTOCOL=unix"
|
||||
STORAGE_USERS_GRPC_ADDR=/var/run/ocis/storage-users.sock"
|
||||
GATEWAY_STORAGE_USERS_ENDPOINT=unix:/var/run/ocis/storage-users.sock"
|
||||
// graph sometimes bypasses the gateway so we need to configure the socket here as wel
|
||||
GRAPH_SPACES_STORAGE_USERS_ADDRESS=unix:/var/run/ocis/storage-users.sock"
|
||||
|
||||
STORAGE_SHARES_GRPC_PROTOCOL=unix"
|
||||
STORAGE_SHARES_GRPC_ADDR=/var/run/ocis/storage-shares.sock"
|
||||
GATEWAY_STORAGE_SHARES_ENDPOINT=unix:/var/run/ocis/storage-shares.sock"
|
||||
|
||||
APP_REGISTRY_GRPC_PROTOCOL=unix"
|
||||
APP_REGISTRY_GRPC_ADDR=/var/run/ocis/app-registry.sock"
|
||||
GATEWAY_APP_REGISTRY_ENDPOINT=unix:/var/run/ocis/app-registry.sock"
|
||||
|
||||
OCM_GRPC_PROTOCOL=unix"
|
||||
OCM_GRPC_ADDR=/var/run/ocis/ocm.sock"
|
||||
GATEWAY_OCM_ENDPOINT=unix:/var/run/ocis/ocm.sock"
|
||||
|
||||
// storage system
|
||||
STORAGE_SYSTEM_GRPC_PROTOCOL="unix"
|
||||
STORAGE_SYSTEM_GRPC_ADDR="/var/run/ocis/storage-system.sock"
|
||||
STORAGE_GATEWAY_GRPC_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
STORAGE_GRPC_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
SHARING_USER_CS3_PROVIDER_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
SHARING_USER_JSONCS3_PROVIDER_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
SHARING_PUBLIC_CS3_PROVIDER_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
SHARING_PUBLIC_JSONCS3_PROVIDER_ADDR="unix:/var/run/ocis/storage-system.sock"
|
||||
```
|
||||
|
||||
## Storage Registry
|
||||
|
||||
In order to add another storage provider the CS3 storage registry that is running as part of the CS3 gateway hes to be made aware of it. The easiest cleanest way to do it is to set `GATEWAY_STORAGE_REGISTRY_CONFIG_JSON=/path/to/storages.json` and list all storage providers like this:
|
||||
|
||||
@@ -101,4 +168,4 @@ In order to add another storage provider the CS3 storage registry that is runnin
|
||||
}
|
||||
```
|
||||
|
||||
In the above replace `{storage-users-mount-uuid}` with the mount UUID that was generated for the storage-users service. You can find it in the `config.yaml` generated on by `ocis init`. The last entry `com.owncloud.api.storage-hello` and its `providerid` `"hello-storage-id"` are an example for in additional storage provider, in this case running `hellofs`, an example minimal storage driver.
|
||||
In the above replace `{storage-users-mount-uuid}` with the mount UUID that was generated for the storage-users service. You can find it in the `config.yaml` generated on by `ocis init`. The last entry `com.owncloud.api.storage-hello` and its `providerid` `"hello-storage-id"` are an example for in additional storage provider, in this case running `hellofs`, an example minimal storage driver.
|
||||
|
||||
@@ -81,7 +81,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
cancel()
|
||||
})
|
||||
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Addr, version.GetString())
|
||||
grpcSvc := registry.BuildGRPCService(cfg.GRPC.Namespace+"."+cfg.Service.Name, cfg.GRPC.Protocol, cfg.GRPC.Addr, version.GetString())
|
||||
if err := registry.RegisterService(ctx, grpcSvc, logger); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to register the grpc service")
|
||||
}
|
||||
|
||||
@@ -31,20 +31,20 @@ type Config struct {
|
||||
|
||||
FrontendPublicURL string `yaml:"frontend_public_url" env:"OCIS_URL;GATEWAY_FRONTEND_PUBLIC_URL" desc:"The public facing URL of the oCIS frontend." introductionVersion:"pre5.0"`
|
||||
|
||||
UsersEndpoint string `yaml:"-"`
|
||||
GroupsEndpoint string `yaml:"-"`
|
||||
PermissionsEndpoint string `yaml:"-"`
|
||||
SharingEndpoint string `yaml:"-"`
|
||||
AuthAppEndpoint string `yaml:"-"`
|
||||
AuthBasicEndpoint string `yaml:"-"`
|
||||
AuthBearerEndpoint string `yaml:"-"`
|
||||
AuthMachineEndpoint string `yaml:"-"`
|
||||
AuthServiceEndpoint string `yaml:"-"`
|
||||
StoragePublicLinkEndpoint string `yaml:"-"`
|
||||
StorageUsersEndpoint string `yaml:"-"`
|
||||
StorageSharesEndpoint string `yaml:"-"`
|
||||
AppRegistryEndpoint string `yaml:"-"`
|
||||
OCMEndpoint string `yaml:"-"`
|
||||
UsersEndpoint string `yaml:"users_endpoint" env:"GATEWAY_USERS_ENDPOINT" desc:"The endpoint of the users service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
GroupsEndpoint string `yaml:"groups_endpoint" env:"GATEWAY_GROUPS_ENDPOINT" desc:"The endpoint of the groups service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
PermissionsEndpoint string `yaml:"permissions_endpoint" env:"GATEWAY_PERMISSIONS_ENDPOINT" desc:"The endpoint of the permissions service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
SharingEndpoint string `yaml:"sharing_endpoint" env:"GATEWAY_SHARING_ENDPOINT" desc:"The endpoint of the shares service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AuthAppEndpoint string `yaml:"auth_app_endpoint" env:"GATEWAY_AUTH_APP_ENDPOINT" desc:"The endpoint of the auth-app service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AuthBasicEndpoint string `yaml:"auth_basic_endpoint" env:"GATEWAY_AUTH_BASIC_ENDPOINT" desc:"The endpoint of the auth-basic service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AuthBearerEndpoint string `yaml:"auth_bearer_endpoint" env:"GATEWAY_AUTH_BEARER_ENDPOINT" desc:"The endpoint of the auth-bearer service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AuthMachineEndpoint string `yaml:"auth_machine_endpoint" env:"GATEWAY_AUTH_MACHINE_ENDPOINT" desc:"The endpoint of the auth-machine service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AuthServiceEndpoint string `yaml:"auth_service_endpoint" env:"GATEWAY_AUTH_SERVICE_ENDPOINT" desc:"The endpoint of the auth-service service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
StoragePublicLinkEndpoint string `yaml:"storage_public_link_endpoint" env:"GATEWAY_STORAGE_PUBLIC_LINK_ENDPOINT" desc:"The endpoint of the storage-publiclink service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
StorageUsersEndpoint string `yaml:"storage_users_endpoint" env:"GATEWAY_STORAGE_USERS_ENDPOINT" desc:"The endpoint of the storage-users service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
StorageSharesEndpoint string `yaml:"storage_shares_endpoint" env:"GATEWAY_STORAGE_SHARES_ENDPOINT" desc:"The endpoint of the storag-shares service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
AppRegistryEndpoint string `yaml:"app_registry_endpoint" env:"GATEWAY_APP_REGISTRY_ENDPOINT" desc:"The endpoint of the app-registry service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
OCMEndpoint string `yaml:"ocm_endpoint" env:"GATEWAY_OCM_ENDPOINT" desc:"The endpoint of the ocm service. Can take a service name or a gRPC URI with the dns, kubernetes or unix protocol." introductionVersion:"%%NEXT%%"`
|
||||
|
||||
StorageRegistry StorageRegistry `yaml:"storage_registry"` // TODO: should we even support switching this?
|
||||
|
||||
@@ -74,7 +74,7 @@ type GRPCConfig struct {
|
||||
Addr string `yaml:"addr" env:"OCIS_GATEWAY_GRPC_ADDR;GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"pre5.0"`
|
||||
TLS *shared.GRPCServiceTLS `yaml:"tls"`
|
||||
Namespace string `yaml:"-"`
|
||||
Protocol string `yaml:"protocol" env:"GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
Protocol string `yaml:"protocol" env:"OCIS_GRPC_PROTOCOL;GATEWAY_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"pre5.0"`
|
||||
}
|
||||
|
||||
type StorageRegistry struct {
|
||||
|
||||
@@ -63,3 +63,29 @@ The client that is used to authenticate with keycloak has to be able to list use
|
||||
* `view-authorization`
|
||||
|
||||
Note that these roles are only available to assign if the client is in the `master` realm.
|
||||
|
||||
## Translations
|
||||
|
||||
The `graph` service has embedded translations sourced via transifex to provide a basic set of translated languages. These embedded translations are available for all deployment scenarios. In addition, the service supports custom translations, though it is currently not possible to just add custom translations to embedded ones. If custom translations are configured, the embedded ones are not used. To configure custom translations, the `GRAPH_TRANSLATION_PATH` environment variable needs to point to a base folder that will contain the translation files. This path must be available from all instances of the graph service, a shared storage is recommended. Translation files must be of type [.po](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files) or [.mo](https://www.gnu.org/software/gettext/manual/html_node/Binaries.html). For each language, the filename needs to be `graph.po` (or `graph.mo`) and stored in a folder structure defining the language code. In general the path/name pattern for a translation file needs to be:
|
||||
|
||||
```text
|
||||
{GRAPH_TRANSLATION_PATH}/{language-code}/LC_MESSAGES/graph.po
|
||||
```
|
||||
|
||||
The language code pattern is composed of `language[_territory]` where `language` is the base language and `_territory` is optional and defines a country.
|
||||
|
||||
For example, for the language `de`, one needs to place the corresponding translation files to `{GRAPH_TRANSLATION_PATH}/de_DE/LC_MESSAGES/graph.po`.
|
||||
|
||||
<!-- also see the notifications readme -->
|
||||
|
||||
Important: For the time being, the embedded ownCloud Web frontend only supports the main language code but does not handle any territory. When strings are available in the language code `language_territory`, the web frontend does not see it as it only requests `language`. In consequence, any translations made must exist in the requested `language` to avoid a fallback to the default.
|
||||
|
||||
### Translation Rules
|
||||
|
||||
* If a requested language code is not available, the service tries to fall back to the base language if available. For example, if the requested language-code `de_DE` is not available, the service tries to fall back to translations in the `de` folder.
|
||||
* If the base language `de` is also not available, the service falls back to the system's default English (`en`),
|
||||
which is the source of the texts provided by the code.
|
||||
|
||||
## Default Language
|
||||
|
||||
The default language can be defined via the `OCIS_DEFAULT_LANGUAGE` environment variable. See the `settings` service for a detailed description.
|
||||
|
||||
@@ -47,6 +47,7 @@ type Spaces struct {
|
||||
GroupsCacheTTL int `yaml:"groups_cache_ttl" env:"GRAPH_SPACES_GROUPS_CACHE_TTL" desc:"Max TTL in seconds for the spaces groups cache." introductionVersion:"pre5.0"`
|
||||
StorageUsersAddress string `yaml:"storage_users_address" env:"GRAPH_SPACES_STORAGE_USERS_ADDRESS" desc:"The address of the storage-users service." introductionVersion:"5.0"`
|
||||
DefaultLanguage string `yaml:"default_language" env:"OCIS_DEFAULT_LANGUAGE" desc:"The default language used by services and the WebUI. If not defined, English will be used as default. See the documentation for more details." introductionVersion:"5.0"`
|
||||
TranslationPath string `yaml:"translation_path" env:"OCIS_TRANSLATION_PATH;GRAPH_TRANSLATION_PATH" desc:"(optional) Set this to a path with custom translations to overwrite the builtin translations. Note that file and folder naming rules apply, see the documentation for more details." introductionVersion:"%%NEXT%%"`
|
||||
}
|
||||
|
||||
type LDAP struct {
|
||||
|
||||
@@ -20,8 +20,8 @@ const (
|
||||
)
|
||||
|
||||
// Translate translates a string based on the locale and default locale
|
||||
func Translate(content, locale, defaultLocale string) string {
|
||||
t := l10n.NewTranslatorFromCommonConfig(defaultLocale, _domain, "", _localeFS, _localeSubPath)
|
||||
func Translate(content, locale, defaultLocale, translationPath string) string {
|
||||
t := l10n.NewTranslatorFromCommonConfig(defaultLocale, _domain, translationPath, _localeFS, _localeSubPath)
|
||||
return t.Translate(content, locale)
|
||||
}
|
||||
|
||||
|
||||
@@ -73,13 +73,13 @@ const (
|
||||
)
|
||||
|
||||
// NewDriveItemPermissionsService creates a new DriveItemPermissionsService
|
||||
func NewDriveItemPermissionsService(logger log.Logger, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], identityCache identity.IdentityCache, c *config.Config) (DriveItemPermissionsService, error) {
|
||||
func NewDriveItemPermissionsService(logger log.Logger, gatewaySelector pool.Selectable[gateway.GatewayAPIClient], identityCache identity.IdentityCache, config *config.Config) (DriveItemPermissionsService, error) {
|
||||
return DriveItemPermissionsService{
|
||||
BaseGraphService: BaseGraphService{
|
||||
logger: &log.Logger{Logger: logger.With().Str("graph api", "DrivesDriveItemService").Logger()},
|
||||
gatewaySelector: gatewaySelector,
|
||||
identityCache: identityCache,
|
||||
config: c,
|
||||
config: config,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func (s DriveItemPermissionsService) Invite(ctx context.Context, resourceId *sto
|
||||
|
||||
permission := &libregraph.Permission{}
|
||||
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(s.config.UnifiedRoles.AvailableRoles...))
|
||||
if role := unifiedrole.CS3ResourcePermissionsToRole(availableRoles, cs3ResourcePermissions, condition); role != nil {
|
||||
if role := unifiedrole.CS3ResourcePermissionsToRole(availableRoles, cs3ResourcePermissions, condition, false); role != nil {
|
||||
permission.Roles = []string{role.GetId()}
|
||||
}
|
||||
|
||||
@@ -389,6 +389,17 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID
|
||||
if err != nil {
|
||||
return collectionOfPermissions, err
|
||||
}
|
||||
if s.config.IncludeOCMSharees {
|
||||
driveItems, err = s.listOCMShares(ctx, []*ocm.ListOCMSharesRequest_Filter{
|
||||
{
|
||||
Type: ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID,
|
||||
Term: &ocm.ListOCMSharesRequest_Filter_ResourceId{ResourceId: itemID},
|
||||
},
|
||||
}, driveItems)
|
||||
if err != nil {
|
||||
return collectionOfPermissions, err
|
||||
}
|
||||
}
|
||||
}
|
||||
// finally get public shares, which are possible for spaceroots and "normal" resources
|
||||
driveItems, err = s.listPublicShares(ctx, []*link.ListPublicSharesRequest_Filter{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user