From f38a9f43852cdcc89642345636a62c50e8ae8df2 Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Tue, 14 Mar 2023 16:08:22 +0100 Subject: [PATCH] Introduce Policies-Service (#5716) * add policies service add policies proxy middleware add policies event service add policies grpc service prepare ci and git environments (ci, make, readme, doc) * add webfinger to the drone conf * fix docs remove not used virus scan postprocessing step * relocate example rego file implicitly enable and disable proxy and postprocessing policy checking by setting the query. update configuration descriptions * move policies update readme * use converter func to convert pp environment to actual environment expose and test custom rego functions add engine unit tests add opa unit tests update policies readme Co-authored-by: Martin * relocate sample policies to the deployments folder change and document policies service port * update index.md and small fix * add health command add version command add debug server --------- Co-authored-by: Martin --- .drone.star | 2 + .gitignore | 2 + Makefile | 1 + changelog/unreleased/policies-service.md | 20 + .../policies/postprocessing.rego | 10 + .../service_policies/policies/proxy.rego | 12 + .../service_policies/policies/utils.rego | 53 ++ docs/services/policies/_index.md | 89 +++ docs/services/policies/configuration.md | 15 + docs/services/port-ranges.md | 378 +++++----- go.mod | 20 +- go.sum | 45 +- ocis-pkg/config/config.go | 11 +- ocis-pkg/config/defaultconfig.go | 2 + ocis/pkg/command/policies.go | 30 + ocis/pkg/runtime/service/service.go | 4 +- .../ocis/messages/policies/v0/policies.pb.go | 653 ++++++++++++++++++ .../messages/policies/v0/policies.pb.micro.go | 15 + .../policies/v0/policies.swagger.json | 43 ++ .../ocis/messages/settings/v0/settings.pb.go | 98 +-- .../ocis/services/policies/v0/policies.pb.go | 266 +++++++ .../services/policies/v0/policies.pb.micro.go | 103 +++ .../policies/v0/policies.swagger.json | 216 ++++++ protogen/proto/buf.gen.yaml | 4 +- .../ocis/messages/policies/v0/policies.proto | 49 ++ .../ocis/services/policies/v0/policies.proto | 51 ++ services/policies/Makefile | 37 + services/policies/README.md | 73 ++ services/policies/cmd/policies/main.go | 14 + services/policies/pkg/command/health.go | 60 ++ services/policies/pkg/command/root.go | 54 ++ services/policies/pkg/command/server.go | 193 ++++++ services/policies/pkg/command/version.go | 50 ++ services/policies/pkg/config/config.go | 77 +++ .../pkg/config/defaults/defaultconfig.go | 87 +++ services/policies/pkg/config/parser/parse.go | 42 ++ services/policies/pkg/engine/engine.go | 74 ++ .../policies/pkg/engine/engine_suite_test.go | 13 + services/policies/pkg/engine/engine_test.go | 25 + services/policies/pkg/engine/opa.go | 124 ++++ services/policies/pkg/engine/opa_test.go | 46 ++ .../policies/pkg/service/event/service.go | 87 +++ services/policies/pkg/service/grpc/service.go | 35 + services/postprocessing/pkg/config/config.go | 2 +- .../postprocessing/pkg/service/service.go | 1 + services/proxy/pkg/command/server.go | 6 +- services/proxy/pkg/config/config.go | 36 +- services/proxy/pkg/middleware/policies.go | 62 ++ 48 files changed, 3106 insertions(+), 284 deletions(-) create mode 100644 changelog/unreleased/policies-service.md create mode 100644 deployments/examples/service_policies/policies/postprocessing.rego create mode 100644 deployments/examples/service_policies/policies/proxy.rego create mode 100644 deployments/examples/service_policies/policies/utils.rego create mode 100644 docs/services/policies/_index.md create mode 100644 docs/services/policies/configuration.md create mode 100644 ocis/pkg/command/policies.go create mode 100644 protogen/gen/ocis/messages/policies/v0/policies.pb.go create mode 100644 protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go create mode 100644 protogen/gen/ocis/messages/policies/v0/policies.swagger.json create mode 100644 protogen/gen/ocis/services/policies/v0/policies.pb.go create mode 100644 protogen/gen/ocis/services/policies/v0/policies.pb.micro.go create mode 100644 protogen/gen/ocis/services/policies/v0/policies.swagger.json create mode 100644 protogen/proto/ocis/messages/policies/v0/policies.proto create mode 100644 protogen/proto/ocis/services/policies/v0/policies.proto create mode 100644 services/policies/Makefile create mode 100644 services/policies/README.md create mode 100644 services/policies/cmd/policies/main.go create mode 100644 services/policies/pkg/command/health.go create mode 100644 services/policies/pkg/command/root.go create mode 100644 services/policies/pkg/command/server.go create mode 100644 services/policies/pkg/command/version.go create mode 100644 services/policies/pkg/config/config.go create mode 100644 services/policies/pkg/config/defaults/defaultconfig.go create mode 100644 services/policies/pkg/config/parser/parse.go create mode 100644 services/policies/pkg/engine/engine.go create mode 100644 services/policies/pkg/engine/engine_suite_test.go create mode 100644 services/policies/pkg/engine/engine_test.go create mode 100644 services/policies/pkg/engine/opa.go create mode 100644 services/policies/pkg/engine/opa_test.go create mode 100644 services/policies/pkg/service/event/service.go create mode 100644 services/policies/pkg/service/grpc/service.go create mode 100644 services/proxy/pkg/middleware/policies.go diff --git a/.drone.star b/.drone.star index 170c2c376..16cff1fb3 100644 --- a/.drone.star +++ b/.drone.star @@ -71,6 +71,7 @@ config = { "services/notifications", "services/ocdav", "services/ocs", + "services/policies", "services/proxy", "services/search", "services/settings", @@ -85,6 +86,7 @@ config = { "services/users", "services/web", "services/webdav", + "services/webfinger", "ocis-pkg", "ocis", ], diff --git a/.gitignore b/.gitignore index 6a402cb68..ed822db68 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,5 @@ protogen/buf.sha1.lock # misc go.work +.env +.envrc diff --git a/Makefile b/Makefile index a09fc7d2c..63eed8599 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ OCIS_MODULES = \ services/notifications \ services/ocdav \ services/ocs \ + services/policies \ services/postprocessing \ services/proxy \ services/search \ diff --git a/changelog/unreleased/policies-service.md b/changelog/unreleased/policies-service.md new file mode 100644 index 000000000..cb24ddba6 --- /dev/null +++ b/changelog/unreleased/policies-service.md @@ -0,0 +1,20 @@ +Enhancement: Introduce policies-service + +Introduces policies service. The policies-service provides a new grpc api which can be used to return whether a requested operation is allowed or not. +Open Policy Agent is used to determine the set of rules of what is permitted and what is not. + +2 further levels of authorization build on this: + +* Proxy Authorization +* Event Authorization (needs async post-processing enabled) + +The simplest authorization layer is in the proxy, since every request is processed here, only simple decisions that can be processed quickly are made here, more complex queries such as file evaluation are explicitly excluded in this layer. + +The next layer is event-based as a pipeline step in asynchronous post-processing, since processing at this point is asynchronous, the operations there can also take longer and be more expensive, +the bytes of a file can be examined here as an example. + +Since the base block is a grpc api, it is also possible to use it directly. +The policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/). + +https://github.com/owncloud/ocis/pull/5714 +https://github.com/owncloud/ocis/issues/5580 diff --git a/deployments/examples/service_policies/policies/postprocessing.rego b/deployments/examples/service_policies/policies/postprocessing.rego new file mode 100644 index 000000000..8b77f0446 --- /dev/null +++ b/deployments/examples/service_policies/policies/postprocessing.rego @@ -0,0 +1,10 @@ +package postprocessing + +import future.keywords.if +import data.utils + +default granted = true + +granted := false if { + not utils.collection_contains(utils.ALLOWED_FILE_EXTENSIONS, input.resource.name) +} diff --git a/deployments/examples/service_policies/policies/proxy.rego b/deployments/examples/service_policies/policies/proxy.rego new file mode 100644 index 000000000..c1e9da783 --- /dev/null +++ b/deployments/examples/service_policies/policies/proxy.rego @@ -0,0 +1,12 @@ +package proxy + +import future.keywords.if +import data.utils + +default granted = true + +granted := false if { + utils.is_request_type_put + not input.request.path == "/data" + not utils.collection_contains(utils.ALLOWED_FILE_EXTENSIONS, input.request.path) +} diff --git a/deployments/examples/service_policies/policies/utils.rego b/deployments/examples/service_policies/policies/utils.rego new file mode 100644 index 000000000..65e55e31b --- /dev/null +++ b/deployments/examples/service_policies/policies/utils.rego @@ -0,0 +1,53 @@ +package utils + +import future.keywords.if + +ALLOWED_FILE_EXTENSIONS := [ + ".apk", ".avi", ".bat", ".bmp", ".css", ".csv", ".doc", ".docm", ".docx", + ".docxf", ".dotx", ".eml", ".epub", ".htm", ".html", ".ipa", ".jar", ".java", + ".jpg", ".js", ".json", ".mp3", ".mp4", ".msg", ".odp", ".ods", ".odt", ".oform", + ".ots", ".ott", ".pdf", ".php", ".png", ".potm", ".potx", ".ppsm", ".ppsx", ".ppt", + ".pptm", ".pptx", ".py", ".rtf", ".sb3", ".sprite3", ".sql", ".svg", ".tif", ".tiff", + ".txt", ".xls", ".xlsm", ".xlsx", ".xltm", ".xltx", ".xml", ".zip", ".md" +] + +## + +is_stage_http { + input.stage == "http" +} + +is_stage_pp { + input.stage == "pp" +} + +## + +is_user_admin { + input.user.username == "admin" +} + +## + +is_request_type_put { + is_stage_http + input.request.method == "PUT" +} + +is_request_path_file { + is_stage_http + input.request.method == "PUT" +} + +is_request_type_mkcol { + is_stage_http + input.request.method == "MKCOL" +} + +## + +collection_contains(collection, source) { + current := collection[_] + endswith(source, current) +} + diff --git a/docs/services/policies/_index.md b/docs/services/policies/_index.md new file mode 100644 index 000000000..cfb962e41 --- /dev/null +++ b/docs/services/policies/_index.md @@ -0,0 +1,89 @@ +--- +title: Policies +weight: 20 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/services/policies +geekdocFilePath: _index.md +geekdocCollapseSection: true +--- + +## Abstract + +The policies service provides a new grpc api which can be used to return whether a requested operation is allowed or not. To do so, Open Policy Agent (OPA) is used to determine the set of rules of what is permitted and what is not. + +## Table of Contents + +{{< toc-tree >}} + +## Rego + +Policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/). The location of the rego files can be configured via yaml, a configuration via environment variables is not possible. + +The Policies Service consists of the following modules: + +* Proxy Authorization (middleware) +* Event Authorization (async post-processing) +* GRPC API (can be used from other services) + +To configure the Policies Service, three environment variables need to be defined: + +* `POLICIES_ENGINE_TIMEOUT` +* `POLICIES_POSTPROCESSING_QUERY` +* `PROXY_POLICIES_QUERY` + +Note that each query setting defines the [Complete Rules](https://www.openpolicyagent.org/docs/latest/#complete-rules) variable defined in the rego rule set the corresponding step uses for the evaluation. If the variable is mistyped or not found, the evaluation defaults to deny. Individual query definitions can be defined for each module. + +To activate a the policies service for a module, it must be started with a yaml configuration that points to one or more rego files. Note that if the service is scaled horizontally, each instance should have access to the same rego files to avoid unpredictable results. If a file path has been configured but the file it is not present or accessible, the evaluation defaults to deny. + +When using async post-processing which is done via the postprocessing service, the value `policies` must be added to the `POSTPROCESSING_STEPS` configuration in postprocessing service in the order where the evaluation should take place. + +## Modules + +### GRPC Service + +This service can be used from any other internal service. It can also be used for example by third parties to find out if an action is allowed or not. This layer is already used by the proxy middleware. + +### Event Service + +This layer is event-based and part of the postprocessing service. Since processing at this point is asynchronous, the operations can also take longer and be more expensive, like evaluating the bytes of a file. + +### Proxy Middleware + +The [ocis proxy](../proxy) already includes such a middleware which uses the [GRPC service](#grpc-service) to evaluate the policies by using a configurable query. Since the Proxy is in heavy use and every request is processed here, only simple and quick decisions should be evaluated. More complex queries such as file evaluation are strongly discouraged. + +## Example Policies + +The policies service contains a set of pre-configured example policies. Those policies can be found in the [examples directory](https://github.com/owncloud/ocis/tree/master/deployments/examples/service_policies/policies). The contained policies disallows ocis to create certain filetypes, both for the proxy middleware and the events service. + +To use the example policies, it's required to configure ocis to use these files which can be done by adding: + +```yaml +policies: + engine: + policies: + - YOUR_PATH/examples/policies/proxy.rego + - YOUR_PATH/examples/policies/postprocessing.rego + - YOUR_PATH/examples/policies/utils.rego +``` + +Once the policies are configured correctly, the _QUERY configuration needs to be defined for the proxy middleware and for the events service. + +### Proxy + +```yaml +proxy: + policies_middleware: + query: data.proxy.granted +``` + +The same can be achieved by setting the `PROXY_POLICIES_QUERY=data.proxy.granted` environment variable. + +### ASYNC Postprocessing + +```yaml +policies: + postprocessing: + query: data.postprocessing.granted +``` + +The same can be achieved by setting the `POLICIES_POSTPROCESSING_QUERY=data.postprocessing.granted` environment variable. As soon as that query is configured correctly, postprocessing must be informed to use the policies step by setting the environment variable `POSTPROCESSING_STEPS=policies`. Note that additional steps can be configured and their appearance defines the order of processing. For details see the postprocessing service documentation. diff --git a/docs/services/policies/configuration.md b/docs/services/policies/configuration.md new file mode 100644 index 000000000..25e4d9c0f --- /dev/null +++ b/docs/services/policies/configuration.md @@ -0,0 +1,15 @@ +--- +title: Service Configuration +date: 2018-05-02T00:00:00+00:00 +weight: 20 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/services/policies +geekdocFilePath: configuration.md +geekdocCollapseSection: true +--- + +## Example YAML Config + +{{< include file="services/_includes/policies-config-example.yaml" language="yaml" >}} + +{{< include file="services/_includes/policies_configvars.md" >}} diff --git a/docs/services/port-ranges.md b/docs/services/port-ranges.md index 4a9e8128f..0a75793c4 100644 --- a/docs/services/port-ranges.md +++ b/docs/services/port-ranges.md @@ -21,193 +21,193 @@ We also suggest to use the last port in your extensions' range as a debug/metric ## Allocations -| Port range | Service | -| ---------- | ----------------------------------------------------------------------------- | -| 9000-9010 | [reserved for Infinite Scale]({{< ref "../../../ocis/_index.md" >}}) | -| 9100-9104 | [web]({{< ref "./web/_index.md" >}}) | -| 9105-9109 | [hello](https://github.com/owncloud/ocis-hello) | -| 9110-9114 | [ocs]({{< ref "./ocs/_index.md" >}}) | -| 9115-9119 | [webdav]({{< ref "./webdav/_index.md" >}}) | -| 9120-9124 | [graph]({{< ref "./graph/_index.md" >}}) | -| 9125-9129 | FREE (formerly used by glauth) | -| 9130-9134 | [idp]({{< ref "./idp/_index.md" >}}) | -| 9135-9139 | FREE (formerly used by graph-explorer) | -| 9140-9141 | [frontend]({{< ref "./frontend/_index.md" >}}) | -| 9142-9143 | [gateway]({{< ref "./gateway/_index.md" >}}) | -| 9144-9145 | [users]({{< ref "./users/_index.md" >}}) | -| 9146-9147 | [auth-basic]({{< ref "./auth-basic/_index.md" >}}) | -| 9148-9149 | [auth-bearer]({{< ref "./auth-bearer/_index.md" >}}) | -| 9150-9153 | [sharing]({{< ref "./sharing/_index.md" >}}) | -| 9154-9156 | [storage-shares]({{< ref "./storage-shares/_index.md" >}}) | -| 9157-9159 | [storage-users]({{< ref "./storage-users/_index.md" >}}) | -| 9160-9162 | [groups]({{< ref "./groups/_index.md" >}}) | -| 9163 | [ocdav]({{< ref "./ocdav/_index.md" >}}) | -| 9164 | [groups]({{< ref "./groups/_index.md" >}}) | -| 9165 | [app-provider]({{< ref "./app-provider/_index.md" >}}) | -| 9166-9169 | [auth-machine]({{< ref "./auth-machine/_index.md" >}}) | -| 9170-9174 | [notifications]({{< ref "./notifications/_index.md" >}}) | -| 9175-9179 | [storage-publiclink]({{< ref "./storage-publiclink/_index.md" >}}) | -| 9180-9184 | FREE (formerly used by accounts) | -| 9185-9189 | [thumbnails]({{< ref "./thumbnails/_index.md" >}}) | -| 9190-9194 | [settings]({{< ref "./settings/_index.md" >}}) | -| 9195-9199 | FREE | -| 9200-9204 | [proxy]({{< ref "./proxy/_index.md" >}}) | -| 9205-9209 | [proxy]({{< ref "./proxy/_index.md" >}}) | -| 9210-9214 | FREE | -| 9215-9219 | [storage-system]({{< ref "./storage-system/_index.md" >}}) | -| 9220-9224 | [search]({{< ref "./search/_index.md" >}}) | -| 9225-9229 | FREE | -| 9230-9234 | [nats]({{< ref "./nats/_index.md" >}}) | -| 9235-9239 | [idm]({{< ref "./idm/_index.md" >}}) | -| 9240-9244 | [app-registry]({{< ref "./app-registry/_index.md" >}}) | -| 9245-9249 | FREE | +| Port range | Service | +|------------|----------------------------------------------------------------------------------------| +| 9000-9010 | [reserved for Infinite Scale]({{< ref "../../../ocis/_index.md" >}}) | +| 9100-9104 | [web]({{< ref "./web/_index.md" >}}) | +| 9105-9109 | [hello](https://github.com/owncloud/ocis-hello) | +| 9110-9114 | [ocs]({{< ref "./ocs/_index.md" >}}) | +| 9115-9119 | [webdav]({{< ref "./webdav/_index.md" >}}) | +| 9120-9124 | [graph]({{< ref "./graph/_index.md" >}}) | +| 9125-9129 | [policies]({{< ref "./policies/_index.md" >}}) | +| 9130-9134 | [idp]({{< ref "./idp/_index.md" >}}) | +| 9135-9139 | FREE (formerly used by graph-explorer) | +| 9140-9141 | [frontend]({{< ref "./frontend/_index.md" >}}) | +| 9142-9143 | [gateway]({{< ref "./gateway/_index.md" >}}) | +| 9144-9145 | [users]({{< ref "./users/_index.md" >}}) | +| 9146-9147 | [auth-basic]({{< ref "./auth-basic/_index.md" >}}) | +| 9148-9149 | [auth-bearer]({{< ref "./auth-bearer/_index.md" >}}) | +| 9150-9153 | [sharing]({{< ref "./sharing/_index.md" >}}) | +| 9154-9156 | [storage-shares]({{< ref "./storage-shares/_index.md" >}}) | +| 9157-9159 | [storage-users]({{< ref "./storage-users/_index.md" >}}) | +| 9160-9162 | [groups]({{< ref "./groups/_index.md" >}}) | +| 9163 | [ocdav]({{< ref "./ocdav/_index.md" >}}) | +| 9164 | [groups]({{< ref "./groups/_index.md" >}}) | +| 9165 | [app-provider]({{< ref "./app-provider/_index.md" >}}) | +| 9166-9169 | [auth-machine]({{< ref "./auth-machine/_index.md" >}}) | +| 9170-9174 | [notifications]({{< ref "./notifications/_index.md" >}}) | +| 9175-9179 | [storage-publiclink]({{< ref "./storage-publiclink/_index.md" >}}) | +| 9180-9184 | FREE (formerly used by accounts) | +| 9185-9189 | [thumbnails]({{< ref "./thumbnails/_index.md" >}}) | +| 9190-9194 | [settings]({{< ref "./settings/_index.md" >}}) | +| 9195-9199 | FREE | +| 9200-9204 | [proxy]({{< ref "./proxy/_index.md" >}}) | +| 9205-9209 | [proxy]({{< ref "./proxy/_index.md" >}}) | +| 9210-9214 | FREE | +| 9215-9219 | [storage-system]({{< ref "./storage-system/_index.md" >}}) | +| 9220-9224 | [search]({{< ref "./search/_index.md" >}}) | +| 9225-9229 | FREE | +| 9230-9234 | [nats]({{< ref "./nats/_index.md" >}}) | +| 9235-9239 | [idm]({{< ref "./idm/_index.md" >}}) | +| 9240-9244 | [app-registry]({{< ref "./app-registry/_index.md" >}}) | +| 9245-9249 | FREE | | 9250-9254 | [ocis server (runtime)](https://github.com/owncloud/ocis/tree/master/ocis/pkg/runtime) | -| 9255-9259 | FREE | -| 9260-9264 | FREE | -| 9265-9269 | FREE | -| 9270-9274 | FREE | -| 9275-9279 | FREE | -| 9280-9284 | FREE | -| 9285-9289 | FREE | -| 9290-9294 | FREE | -| 9295-9299 | FREE | -| 9300-9304 | FREE | -| 9305-9309 | FREE | -| 9310-9314 | FREE | -| 9315-9319 | FREE | -| 9320-9324 | FREE | -| 9325-9329 | FREE | -| 9330-9334 | FREE | -| 9335-9339 | FREE | -| 9340-9344 | FREE | -| 9345-9349 | FREE | -| 9350-9354 | FREE | -| 9355-9359 | FREE | -| 9360-9364 | FREE | -| 9365-9369 | FREE | -| 9370-9374 | FREE | -| 9375-9379 | FREE | -| 9380-9384 | FREE | -| 9385-9389 | FREE | -| 9390-9394 | FREE | -| 9395-9399 | FREE | -| 9400-9404 | FREE | -| 9405-9409 | FREE | -| 9410-9414 | FREE | -| 9415-9419 | FREE | -| 9420-9424 | FREE | -| 9425-9429 | FREE | -| 9430-9434 | FREE | -| 9435-9439 | FREE | -| 9440-9444 | FREE | -| 9445-9449 | FREE | -| 9450-9454 | FREE | -| 9455-9459 | FREE | -| 9460-9464 | [store]({{< ref "./store/_index.md" >}}) | -| 9465-9469 | FREE | -| 9470-9474 | FREE | -| 9475-9479 | FREE | -| 9480-9484 | FREE | -| 9485-9489 | FREE | -| 9490-9494 | FREE | -| 9495-9499 | FREE | -| 9500-9504 | FREE | -| 9505-9509 | FREE | -| 9510-9514 | FREE | -| 9515-9519 | FREE | -| 9520-9524 | FREE | -| 9525-9529 | FREE | -| 9530-9534 | FREE | -| 9535-9539 | FREE | -| 9540-9544 | FREE | -| 9545-9549 | FREE | -| 9550-9554 | FREE | -| 9555-9559 | FREE | -| 9560-9564 | FREE | -| 9565-9569 | FREE | -| 9570-9574 | FREE | -| 9575-9579 | FREE | -| 9580-9584 | FREE | -| 9585-9589 | FREE | -| 9590-9594 | FREE | -| 9595-9599 | FREE | -| 9600-9604 | FREE | -| 9605-9609 | FREE | -| 9610-9614 | FREE | -| 9615-9619 | FREE | -| 9620-9624 | FREE | -| 9625-9629 | FREE | -| 9630-9634 | FREE | -| 9635-9639 | FREE | -| 9640-9644 | FREE | -| 9645-9649 | FREE | -| 9650-9654 | FREE | -| 9655-9659 | FREE | -| 9660-9664 | FREE | -| 9665-9669 | FREE | -| 9670-9674 | FREE | -| 9675-9679 | FREE | -| 9680-9684 | FREE | -| 9685-9689 | FREE | -| 9690-9694 | FREE | -| 9695-9699 | FREE | -| 9700-9704 | FREE | -| 9705-9709 | FREE | -| 9710-9714 | FREE | -| 9715-9719 | FREE | -| 9720-9724 | FREE | -| 9725-9729 | FREE | -| 9730-9734 | FREE | -| 9735-9739 | FREE | -| 9740-9744 | FREE | -| 9745-9749 | FREE | -| 9750-9754 | FREE | -| 9755-9759 | FREE | -| 9760-9764 | FREE | -| 9765-9769 | FREE | -| 9770-9774 | FREE | -| 9775-9779 | FREE | -| 9780-9784 | FREE | -| 9785-9789 | FREE | -| 9790-9794 | FREE | -| 9795-9799 | FREE | -| 9800-9804 | FREE | -| 9805-9809 | FREE | -| 9810-9814 | FREE | -| 9815-9819 | FREE | -| 9820-9824 | FREE | -| 9825-9829 | FREE | -| 9830-9834 | FREE | -| 9835-9839 | FREE | -| 9840-9844 | FREE | -| 9845-9849 | FREE | -| 9850-9854 | FREE | -| 9855-9859 | FREE | -| 9860-9864 | FREE | -| 9865-9869 | FREE | -| 9870-9874 | FREE | -| 9875-9879 | FREE | -| 9880-9884 | FREE | -| 9885-9889 | FREE | -| 9890-9894 | FREE | -| 9895-9899 | FREE | -| 9900-9904 | FREE | -| 9905-9909 | FREE | -| 9910-9914 | FREE | -| 9915-9919 | FREE | -| 9920-9924 | FREE | -| 9925-9929 | FREE | -| 9930-9934 | FREE | -| 9935-9939 | FREE | -| 9940-9944 | FREE | -| 9945-9949 | FREE | -| 9950-9954 | FREE | -| 9955-9959 | FREE | -| 9960-9964 | FREE | -| 9965-9969 | FREE | -| 9970-9974 | FREE | -| 9975-9979 | FREE | -| 9980-9984 | FREE | -| 9985-9989 | FREE | -| 9990-9994 | FREE | -| 9995-9999 | FREE | +| 9255-9259 | FREE | +| 9260-9264 | FREE | +| 9265-9269 | FREE | +| 9270-9274 | FREE | +| 9275-9279 | FREE | +| 9280-9284 | FREE | +| 9285-9289 | FREE | +| 9290-9294 | FREE | +| 9295-9299 | FREE | +| 9300-9304 | FREE | +| 9305-9309 | FREE | +| 9310-9314 | FREE | +| 9315-9319 | FREE | +| 9320-9324 | FREE | +| 9325-9329 | FREE | +| 9330-9334 | FREE | +| 9335-9339 | FREE | +| 9340-9344 | FREE | +| 9345-9349 | FREE | +| 9350-9354 | FREE | +| 9355-9359 | FREE | +| 9360-9364 | FREE | +| 9365-9369 | FREE | +| 9370-9374 | FREE | +| 9375-9379 | FREE | +| 9380-9384 | FREE | +| 9385-9389 | FREE | +| 9390-9394 | FREE | +| 9395-9399 | FREE | +| 9400-9404 | FREE | +| 9405-9409 | FREE | +| 9410-9414 | FREE | +| 9415-9419 | FREE | +| 9420-9424 | FREE | +| 9425-9429 | FREE | +| 9430-9434 | FREE | +| 9435-9439 | FREE | +| 9440-9444 | FREE | +| 9445-9449 | FREE | +| 9450-9454 | FREE | +| 9455-9459 | FREE | +| 9460-9464 | [store]({{< ref "./store/_index.md" >}}) | +| 9465-9469 | FREE | +| 9470-9474 | FREE | +| 9475-9479 | FREE | +| 9480-9484 | FREE | +| 9485-9489 | FREE | +| 9490-9494 | FREE | +| 9495-9499 | FREE | +| 9500-9504 | FREE | +| 9505-9509 | FREE | +| 9510-9514 | FREE | +| 9515-9519 | FREE | +| 9520-9524 | FREE | +| 9525-9529 | FREE | +| 9530-9534 | FREE | +| 9535-9539 | FREE | +| 9540-9544 | FREE | +| 9545-9549 | FREE | +| 9550-9554 | FREE | +| 9555-9559 | FREE | +| 9560-9564 | FREE | +| 9565-9569 | FREE | +| 9570-9574 | FREE | +| 9575-9579 | FREE | +| 9580-9584 | FREE | +| 9585-9589 | FREE | +| 9590-9594 | FREE | +| 9595-9599 | FREE | +| 9600-9604 | FREE | +| 9605-9609 | FREE | +| 9610-9614 | FREE | +| 9615-9619 | FREE | +| 9620-9624 | FREE | +| 9625-9629 | FREE | +| 9630-9634 | FREE | +| 9635-9639 | FREE | +| 9640-9644 | FREE | +| 9645-9649 | FREE | +| 9650-9654 | FREE | +| 9655-9659 | FREE | +| 9660-9664 | FREE | +| 9665-9669 | FREE | +| 9670-9674 | FREE | +| 9675-9679 | FREE | +| 9680-9684 | FREE | +| 9685-9689 | FREE | +| 9690-9694 | FREE | +| 9695-9699 | FREE | +| 9700-9704 | FREE | +| 9705-9709 | FREE | +| 9710-9714 | FREE | +| 9715-9719 | FREE | +| 9720-9724 | FREE | +| 9725-9729 | FREE | +| 9730-9734 | FREE | +| 9735-9739 | FREE | +| 9740-9744 | FREE | +| 9745-9749 | FREE | +| 9750-9754 | FREE | +| 9755-9759 | FREE | +| 9760-9764 | FREE | +| 9765-9769 | FREE | +| 9770-9774 | FREE | +| 9775-9779 | FREE | +| 9780-9784 | FREE | +| 9785-9789 | FREE | +| 9790-9794 | FREE | +| 9795-9799 | FREE | +| 9800-9804 | FREE | +| 9805-9809 | FREE | +| 9810-9814 | FREE | +| 9815-9819 | FREE | +| 9820-9824 | FREE | +| 9825-9829 | FREE | +| 9830-9834 | FREE | +| 9835-9839 | FREE | +| 9840-9844 | FREE | +| 9845-9849 | FREE | +| 9850-9854 | FREE | +| 9855-9859 | FREE | +| 9860-9864 | FREE | +| 9865-9869 | FREE | +| 9870-9874 | FREE | +| 9875-9879 | FREE | +| 9880-9884 | FREE | +| 9885-9889 | FREE | +| 9890-9894 | FREE | +| 9895-9899 | FREE | +| 9900-9904 | FREE | +| 9905-9909 | FREE | +| 9910-9914 | FREE | +| 9915-9919 | FREE | +| 9920-9924 | FREE | +| 9925-9929 | FREE | +| 9930-9934 | FREE | +| 9935-9939 | FREE | +| 9940-9944 | FREE | +| 9945-9949 | FREE | +| 9950-9954 | FREE | +| 9955-9959 | FREE | +| 9960-9964 | FREE | +| 9965-9969 | FREE | +| 9970-9974 | FREE | +| 9975-9979 | FREE | +| 9980-9984 | FREE | +| 9985-9989 | FREE | +| 9990-9994 | FREE | +| 9995-9999 | FREE | diff --git a/go.mod b/go.mod index 8aebff910..a028048c2 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/cs3org/go-cs3apis v0.0.0-20221012090518-ef2996678965 github.com/cs3org/reva/v2 v2.12.1-0.20230313151335-4339b8ab4759 github.com/disintegration/imaging v1.6.2 + github.com/gabriel-vasile/mimetype v1.4.1 github.com/ggwhite/go-masker v1.0.9 github.com/go-chi/chi/v5 v5.0.8 github.com/go-chi/cors v1.2.1 @@ -59,6 +60,7 @@ require ( github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo/v2 v2.9.1 github.com/onsi/gomega v1.27.4 + github.com/open-policy-agent/opa v0.50.0 github.com/orcaman/concurrent-map v1.0.0 github.com/owncloud/libre-graph-api-go v1.0.2-0.20230309112802-ff71ba8c90aa github.com/pkg/errors v0.9.1 @@ -105,9 +107,11 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect github.com/RoaringBitmap/roaring v0.9.4 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect github.com/ajg/form v1.5.1 // indirect github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 // indirect github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect @@ -159,10 +163,10 @@ require ( github.com/emvi/iso-639-1 v1.0.1 // indirect github.com/evanphx/json-patch/v5 v5.5.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.1 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gdexlab/go-render v1.0.1 // indirect + github.com/ghodss/yaml v1.0.0 // indirect github.com/go-acme/lego/v4 v4.4.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect github.com/go-git/gcfg v1.5.0 // indirect @@ -175,6 +179,7 @@ require ( github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/gobwas/glob v0.2.3 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.0.4 // indirect @@ -224,7 +229,7 @@ require ( github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect github.com/miekg/dns v1.1.50 // indirect @@ -254,6 +259,7 @@ require ( github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/statsd_exporter v0.22.8 // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/rivo/uniseg v0.4.2 // indirect github.com/rs/cors v1.8.2 // indirect github.com/rs/xid v1.4.0 // indirect @@ -269,12 +275,16 @@ require ( github.com/spacewander/go-suffix-tree v0.0.0-20191010040751-0865e368c784 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect + github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect github.com/trustelem/zxcvbn v1.0.1 // indirect github.com/wk8/go-ordered-map v1.0.0 // indirect github.com/xanzy/ssh-agent v0.3.2 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yashtewari/glob-intersection v0.1.0 // indirect go.etcd.io/etcd/api/v3 v3.5.6 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect @@ -284,7 +294,7 @@ require ( golang.org/x/mod v0.9.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.6.0 // indirect - golang.org/x/time v0.1.0 // indirect + golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 698dca8f5..0be9690b2 100644 --- a/go.sum +++ b/go.sum @@ -166,6 +166,8 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY= @@ -179,6 +181,8 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.0/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8= @@ -200,6 +204,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= @@ -281,6 +287,7 @@ github.com/bombsimon/logrusr/v3 v3.1.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHA github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35 h1:bbpRY/l4z5MTH+TRGZdkIqDM9JXQQewJdO1o+80zcok= github.com/c0rby/go-cs3apis v0.0.0-20230110100311-5b424f1baa35/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= @@ -292,6 +299,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceph/go-ceph v0.18.0 h1:4WM6yAq/iqBDaeeADDiPKLqKiP0iZ4fffdgCr1lnOL4= github.com/ceph/go-ceph v0.18.0/go.mod h1:cflETVTBNAQM6jdr7hpNHHFHKYiJiWWcAeRDrRx/1ng= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -355,14 +363,17 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3 github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= @@ -400,14 +411,17 @@ github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGE github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U= @@ -415,6 +429,7 @@ github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4Vg github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= github.com/ggwhite/go-masker v1.0.9 h1:9mKJzhLwJN1E5ekqNMk2ppP9ntWubIGtrUNV9wRouZo= github.com/ggwhite/go-masker v1.0.9/go.mod h1:xnTRHwrIU9FtBADwEjUC5Dy/BVedvoTxyOE7/d3CNwY= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -558,6 +573,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= @@ -636,6 +653,7 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -947,8 +965,9 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b h1:Q53idHrTuQDDHyXaxZ6pUl0I9uyD6Z6uKFK3ocX6LzI= github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b/go.mod h1:KirJrATYGbTyUwVR26xIkaipRqRcMRXBf8N5dacvGus= github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZyWckaLfucYG6KYOXLWo4co8pZYNY= @@ -1048,6 +1067,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/open-policy-agent/opa v0.50.0 h1:CBRj7lJ9DFDHvlx2SRP6uFOCD9ooxDdNW9fYK2IIW+0= +github.com/open-policy-agent/opa v0.50.0/go.mod h1:9jKfDk0L5b9rnhH4M0nq10cGHbYOxqygxzTT3dsvhec= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -1144,6 +1165,8 @@ github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+P github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1244,6 +1267,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= +github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo= @@ -1282,6 +1307,9 @@ github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-simple-mail/v2 v2.13.0 h1:OANWU9jHZrVfBkNkvLf8Ww0fexwpQVF/v/5f96fFTLI= @@ -1292,6 +1320,8 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHg github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yashtewari/glob-intersection v0.1.0 h1:6gJvMYQlTDOL3dMsPF6J0+26vwX9MB8/1q3uAdhmTrg= +github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/yosuke-furukawa/json5 v0.1.1/go.mod h1:sw49aWDqNdRJ6DYUtIQiaA3xyj2IL9tjeNYmX2ixwcU= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1661,6 +1691,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1689,8 +1720,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go index a9ab12f6c..3d368f832 100644 --- a/ocis-pkg/config/config.go +++ b/ocis-pkg/config/config.go @@ -2,7 +2,6 @@ package config import ( "github.com/owncloud/ocis/v2/ocis-pkg/shared" - appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/config" appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/config" audit "github.com/owncloud/ocis/v2/services/audit/pkg/config" @@ -20,6 +19,7 @@ import ( notifications "github.com/owncloud/ocis/v2/services/notifications/pkg/config" ocdav "github.com/owncloud/ocis/v2/services/ocdav/pkg/config" ocs "github.com/owncloud/ocis/v2/services/ocs/pkg/config" + policies "github.com/owncloud/ocis/v2/services/policies/pkg/config" postprocessing "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config" proxy "github.com/owncloud/ocis/v2/services/proxy/pkg/config" search "github.com/owncloud/ocis/v2/services/search/pkg/config" @@ -38,14 +38,6 @@ import ( webfinger "github.com/owncloud/ocis/v2/services/webfinger/pkg/config" ) -const ( - // SUPERVISED sets the runtime mode as supervised threads. - SUPERVISED = iota - - // UNSUPERVISED sets the runtime mode as a single thread. - UNSUPERVISED -) - type Mode int // Runtime configures the oCIS runtime when running in supervised mode. @@ -98,6 +90,7 @@ type Config struct { OCDav *ocdav.Config `yaml:"ocdav"` OCS *ocs.Config `yaml:"ocs"` Postprocessing *postprocessing.Config `yaml:"postprocessing"` + Policies *policies.Config `yaml:"policies"` Proxy *proxy.Config `yaml:"proxy"` Settings *settings.Config `yaml:"settings"` Sharing *sharing.Config `yaml:"sharing"` diff --git a/ocis-pkg/config/defaultconfig.go b/ocis-pkg/config/defaultconfig.go index 434c42e13..d59571d11 100644 --- a/ocis-pkg/config/defaultconfig.go +++ b/ocis-pkg/config/defaultconfig.go @@ -18,6 +18,7 @@ import ( notifications "github.com/owncloud/ocis/v2/services/notifications/pkg/config/defaults" ocdav "github.com/owncloud/ocis/v2/services/ocdav/pkg/config/defaults" ocs "github.com/owncloud/ocis/v2/services/ocs/pkg/config/defaults" + policies "github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults" postprocessing "github.com/owncloud/ocis/v2/services/postprocessing/pkg/config/defaults" proxy "github.com/owncloud/ocis/v2/services/proxy/pkg/config/defaults" search "github.com/owncloud/ocis/v2/services/search/pkg/config/defaults" @@ -62,6 +63,7 @@ func DefaultConfig() *Config { OCDav: ocdav.DefaultConfig(), OCS: ocs.DefaultConfig(), Postprocessing: postprocessing.DefaultConfig(), + Policies: policies.DefaultConfig(), Proxy: proxy.DefaultConfig(), Search: search.FullDefaultConfig(), Settings: settings.DefaultConfig(), diff --git a/ocis/pkg/command/policies.go b/ocis/pkg/command/policies.go new file mode 100644 index 000000000..69540d50b --- /dev/null +++ b/ocis/pkg/command/policies.go @@ -0,0 +1,30 @@ +package command + +import ( + "github.com/owncloud/ocis/v2/ocis-pkg/config" + "github.com/owncloud/ocis/v2/ocis-pkg/config/configlog" + "github.com/owncloud/ocis/v2/ocis-pkg/config/parser" + "github.com/owncloud/ocis/v2/ocis/pkg/command/helper" + "github.com/owncloud/ocis/v2/ocis/pkg/register" + "github.com/owncloud/ocis/v2/services/policies/pkg/command" + "github.com/urfave/cli/v2" +) + +// PoliciesCommand is the entrypoint for the policies service. +func PoliciesCommand(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: cfg.Policies.Service.Name, + Usage: helper.SubcommandDescription(cfg.Policies.Service.Name), + Category: "services", + Before: func(c *cli.Context) error { + configlog.Error(parser.ParseConfig(cfg, true)) + cfg.Policies.Commons = cfg.Commons + return nil + }, + Subcommands: command.GetCommands(cfg.Policies), + } +} + +func init() { + register.AddCommand(PoliciesCommand) +} diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go index fe7060c05..f3a10eb45 100644 --- a/ocis/pkg/runtime/service/service.go +++ b/ocis/pkg/runtime/service/service.go @@ -13,13 +13,11 @@ import ( "syscall" "time" - "github.com/owncloud/ocis/v2/ocis-pkg/shared" - "github.com/mohae/deepcopy" "github.com/olekukonko/tablewriter" - ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config" "github.com/owncloud/ocis/v2/ocis-pkg/log" + "github.com/owncloud/ocis/v2/ocis-pkg/shared" appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/command" appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/command" authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/command" diff --git a/protogen/gen/ocis/messages/policies/v0/policies.pb.go b/protogen/gen/ocis/messages/policies/v0/policies.pb.go new file mode 100644 index 000000000..9bc4770b4 --- /dev/null +++ b/protogen/gen/ocis/messages/policies/v0/policies.pb.go @@ -0,0 +1,653 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: ocis/messages/policies/v0/policies.proto + +package v0 + +import ( + 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 Stage int32 + +const ( + Stage_STAGE_PP Stage = 0 + Stage_STAGE_HTTP Stage = 1 +) + +// Enum value maps for Stage. +var ( + Stage_name = map[int32]string{ + 0: "STAGE_PP", + 1: "STAGE_HTTP", + } + Stage_value = map[string]int32{ + "STAGE_PP": 0, + "STAGE_HTTP": 1, + } +) + +func (x Stage) Enum() *Stage { + p := new(Stage) + *p = x + return p +} + +func (x Stage) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Stage) Descriptor() protoreflect.EnumDescriptor { + return file_ocis_messages_policies_v0_policies_proto_enumTypes[0].Descriptor() +} + +func (Stage) Type() protoreflect.EnumType { + return &file_ocis_messages_policies_v0_policies_proto_enumTypes[0] +} + +func (x Stage) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Stage.Descriptor instead. +func (Stage) EnumDescriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0} +} + +type User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id *User_ID `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + Mail string `protobuf:"bytes,3,opt,name=mail,proto3" json:"mail,omitempty"` + DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Groups []string `protobuf:"bytes,5,rep,name=groups,proto3" json:"groups,omitempty"` +} + +func (x *User) Reset() { + *x = User{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User) ProtoMessage() {} + +func (x *User) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 User.ProtoReflect.Descriptor instead. +func (*User) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0} +} + +func (x *User) GetId() *User_ID { + if x != nil { + return x.Id + } + return nil +} + +func (x *User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *User) GetMail() string { + if x != nil { + return x.Mail + } + return "" +} + +func (x *User) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *User) GetGroups() []string { + if x != nil { + return x.Groups + } + return nil +} + +type Resource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id *Resource_ID `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Size uint64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *Resource) Reset() { + *x = Resource{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Resource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Resource) ProtoMessage() {} + +func (x *Resource) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 Resource.ProtoReflect.Descriptor instead. +func (*Resource) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{1} +} + +func (x *Resource) GetId() *Resource_ID { + if x != nil { + return x.Id + } + return nil +} + +func (x *Resource) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Resource) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *Resource) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *Request) Reset() { + *x = Request{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Request) ProtoMessage() {} + +func (x *Request) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 Request.ProtoReflect.Descriptor instead. +func (*Request) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{2} +} + +func (x *Request) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *Request) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +type Environment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stage Stage `protobuf:"varint,1,opt,name=stage,proto3,enum=ocis.messages.policies.v0.Stage" json:"stage,omitempty"` + User *User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + Request *Request `protobuf:"bytes,3,opt,name=request,proto3" json:"request,omitempty"` + Resource *Resource `protobuf:"bytes,4,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *Environment) Reset() { + *x = Environment{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Environment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Environment) ProtoMessage() {} + +func (x *Environment) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 Environment.ProtoReflect.Descriptor instead. +func (*Environment) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{3} +} + +func (x *Environment) GetStage() Stage { + if x != nil { + return x.Stage + } + return Stage_STAGE_PP +} + +func (x *Environment) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +func (x *Environment) GetRequest() *Request { + if x != nil { + return x.Request + } + return nil +} + +func (x *Environment) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type User_ID struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OpaqueId string `protobuf:"bytes,1,opt,name=opaque_id,json=opaqueId,proto3" json:"opaque_id,omitempty"` +} + +func (x *User_ID) Reset() { + *x = User_ID{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *User_ID) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*User_ID) ProtoMessage() {} + +func (x *User_ID) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 User_ID.ProtoReflect.Descriptor instead. +func (*User_ID) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *User_ID) GetOpaqueId() string { + if x != nil { + return x.OpaqueId + } + return "" +} + +type Resource_ID struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StorageId string `protobuf:"bytes,1,opt,name=storage_id,json=storageId,proto3" json:"storage_id,omitempty"` + OpaqueId string `protobuf:"bytes,2,opt,name=opaque_id,json=opaqueId,proto3" json:"opaque_id,omitempty"` + SpaceId string `protobuf:"bytes,3,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"` +} + +func (x *Resource_ID) Reset() { + *x = Resource_ID{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_messages_policies_v0_policies_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Resource_ID) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Resource_ID) ProtoMessage() {} + +func (x *Resource_ID) ProtoReflect() protoreflect.Message { + mi := &file_ocis_messages_policies_v0_policies_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 Resource_ID.ProtoReflect.Descriptor instead. +func (*Resource_ID) Descriptor() ([]byte, []int) { + return file_ocis_messages_policies_v0_policies_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *Resource_ID) GetStorageId() string { + if x != nil { + return x.StorageId + } + return "" +} + +func (x *Resource_ID) GetOpaqueId() string { + if x != nil { + return x.OpaqueId + } + return "" +} + +func (x *Resource_ID) GetSpaceId() string { + if x != nil { + return x.SpaceId + } + return "" +} + +var File_ocis_messages_policies_v0_policies_proto protoreflect.FileDescriptor + +var file_ocis_messages_policies_v0_policies_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x63, 0x69, 0x73, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x2e, 0x76, 0x30, 0x22, 0xc8, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x32, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x63, 0x69, + 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x44, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x21, 0x0a, + 0x02, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49, 0x64, + 0x22, 0xd9, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63, 0x69, 0x73, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49, + 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, + 0x5b, 0x0a, 0x02, 0x49, 0x44, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x49, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x35, 0x0a, 0x07, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x53, + 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x63, 0x69, 0x73, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x12, 0x3c, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2a, + 0x25, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x47, + 0x45, 0x5f, 0x50, 0x50, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, + 0x48, 0x54, 0x54, 0x50, 0x10, 0x01, 0x42, 0x44, 0x5a, 0x42, 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, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, + 0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ocis_messages_policies_v0_policies_proto_rawDescOnce sync.Once + file_ocis_messages_policies_v0_policies_proto_rawDescData = file_ocis_messages_policies_v0_policies_proto_rawDesc +) + +func file_ocis_messages_policies_v0_policies_proto_rawDescGZIP() []byte { + file_ocis_messages_policies_v0_policies_proto_rawDescOnce.Do(func() { + file_ocis_messages_policies_v0_policies_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_messages_policies_v0_policies_proto_rawDescData) + }) + return file_ocis_messages_policies_v0_policies_proto_rawDescData +} + +var file_ocis_messages_policies_v0_policies_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_ocis_messages_policies_v0_policies_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_ocis_messages_policies_v0_policies_proto_goTypes = []interface{}{ + (Stage)(0), // 0: ocis.messages.policies.v0.Stage + (*User)(nil), // 1: ocis.messages.policies.v0.User + (*Resource)(nil), // 2: ocis.messages.policies.v0.Resource + (*Request)(nil), // 3: ocis.messages.policies.v0.Request + (*Environment)(nil), // 4: ocis.messages.policies.v0.Environment + (*User_ID)(nil), // 5: ocis.messages.policies.v0.User.ID + (*Resource_ID)(nil), // 6: ocis.messages.policies.v0.Resource.ID +} +var file_ocis_messages_policies_v0_policies_proto_depIdxs = []int32{ + 5, // 0: ocis.messages.policies.v0.User.id:type_name -> ocis.messages.policies.v0.User.ID + 6, // 1: ocis.messages.policies.v0.Resource.id:type_name -> ocis.messages.policies.v0.Resource.ID + 0, // 2: ocis.messages.policies.v0.Environment.stage:type_name -> ocis.messages.policies.v0.Stage + 1, // 3: ocis.messages.policies.v0.Environment.user:type_name -> ocis.messages.policies.v0.User + 3, // 4: ocis.messages.policies.v0.Environment.request:type_name -> ocis.messages.policies.v0.Request + 2, // 5: ocis.messages.policies.v0.Environment.resource:type_name -> ocis.messages.policies.v0.Resource + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] 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_messages_policies_v0_policies_proto_init() } +func file_ocis_messages_policies_v0_policies_proto_init() { + if File_ocis_messages_policies_v0_policies_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ocis_messages_policies_v0_policies_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_messages_policies_v0_policies_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Resource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_messages_policies_v0_policies_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_messages_policies_v0_policies_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Environment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_messages_policies_v0_policies_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*User_ID); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_messages_policies_v0_policies_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Resource_ID); 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_messages_policies_v0_policies_proto_rawDesc, + NumEnums: 1, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ocis_messages_policies_v0_policies_proto_goTypes, + DependencyIndexes: file_ocis_messages_policies_v0_policies_proto_depIdxs, + EnumInfos: file_ocis_messages_policies_v0_policies_proto_enumTypes, + MessageInfos: file_ocis_messages_policies_v0_policies_proto_msgTypes, + }.Build() + File_ocis_messages_policies_v0_policies_proto = out.File + file_ocis_messages_policies_v0_policies_proto_rawDesc = nil + file_ocis_messages_policies_v0_policies_proto_goTypes = nil + file_ocis_messages_policies_v0_policies_proto_depIdxs = nil +} diff --git a/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go b/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go new file mode 100644 index 000000000..7b2c9b052 --- /dev/null +++ b/protogen/gen/ocis/messages/policies/v0/policies.pb.micro.go @@ -0,0 +1,15 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: ocis/messages/policies/v0/policies.proto + +package v0 + +import ( + fmt "fmt" + proto "google.golang.org/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf diff --git a/protogen/gen/ocis/messages/policies/v0/policies.swagger.json b/protogen/gen/ocis/messages/policies/v0/policies.swagger.json new file mode 100644 index 000000000..db2d89e2c --- /dev/null +++ b/protogen/gen/ocis/messages/policies/v0/policies.swagger.json @@ -0,0 +1,43 @@ +{ + "swagger": "2.0", + "info": { + "title": "ocis/messages/policies/v0/policies.proto", + "version": "version not set" + }, + "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" + } + } + } + } + } +} diff --git a/protogen/gen/ocis/messages/settings/v0/settings.pb.go b/protogen/gen/ocis/messages/settings/v0/settings.pb.go index bae3a9c87..9f0f3d92c 100644 --- a/protogen/gen/ocis/messages/settings/v0/settings.pb.go +++ b/protogen/gen/ocis/messages/settings/v0/settings.pb.go @@ -489,13 +489,13 @@ type Bundle struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" - Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=ocis.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type" - Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"` // @gotags: yaml:"extension" - DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" - Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"` // @gotags: yaml:"settings" - Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" + Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=ocis.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type" + Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"` // @gotags: yaml:"extension" + DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" + Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"` // @gotags: yaml:"settings" + Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" } func (x *Bundle) Reset() { @@ -584,10 +584,10 @@ type Setting struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" - DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` // @gotags: yaml:"description" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` // @gotags: yaml:"description" // Types that are assignable to Value: // // *Setting_IntValue @@ -597,7 +597,7 @@ type Setting struct { // *Setting_MultiChoiceValue // *Setting_PermissionValue Value isSetting_Value `protobuf_oneof:"value"` - Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" + Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" } func (x *Setting) Reset() { @@ -721,27 +721,27 @@ type isSetting_Value interface { } type Setting_IntValue struct { - IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" + IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" } type Setting_StringValue struct { - StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" + StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" } type Setting_BoolValue struct { - BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" + BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" } type Setting_SingleChoiceValue struct { - SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value" + SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value" } type Setting_MultiChoiceValue struct { - MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value" + MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value" } type Setting_PermissionValue struct { - PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value" + PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value" } func (*Setting_IntValue) isSetting_Value() {} @@ -761,11 +761,11 @@ type Int struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" - Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"` // @gotags: yaml:"min" - Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"` // @gotags: yaml:"max" - Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"` // @gotags: yaml:"step" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" + Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" + Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"` // @gotags: yaml:"min" + Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` // @gotags: yaml:"max" + Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` // @gotags: yaml:"step" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" } func (x *Int) Reset() { @@ -840,11 +840,11 @@ type String struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" - Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"` // @gotags: yaml:"required" - MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length" - MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" + Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" + Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` // @gotags: yaml:"required" + MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length" + MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" } func (x *String) Reset() { @@ -919,8 +919,8 @@ type Bool struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" - Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"` // @gotags: yaml:"label" + Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // @gotags: yaml:"label" } func (x *Bool) Reset() { @@ -974,7 +974,7 @@ type SingleChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" } func (x *SingleChoiceList) Reset() { @@ -1021,7 +1021,7 @@ type MultiChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" } func (x *MultiChoiceList) Reset() { @@ -1068,9 +1068,9 @@ type ListOption struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value" - Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" - DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value" + Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value" + Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" + DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value" } func (x *ListOption) Reset() { @@ -1131,8 +1131,8 @@ type Permission struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=ocis.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"` // @gotags: yaml:"operation" - Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=ocis.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint" + Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=ocis.messages.settings.v0.Permission_Operation" json:"operation,omitempty"` // @gotags: yaml:"operation" + Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=ocis.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint" } func (x *Permission) Reset() { @@ -1187,12 +1187,12 @@ type Value struct { unknownFields protoimpl.UnknownFields // id is the id of the Value. It is generated on saving it. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" - BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" + BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id" // setting_id is the id of the setting from within its bundle. - SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"` // @gotags: yaml:"setting_id" - AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid" - Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" + SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // @gotags: yaml:"setting_id" + AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid" + Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" // Types that are assignable to Value: // // *Value_BoolValue @@ -1309,19 +1309,19 @@ type isValue_Value interface { } type Value_BoolValue struct { - BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" } type Value_IntValue struct { - IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" } type Value_StringValue struct { - StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" } type Value_ListValue struct { - ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value" + ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value" } func (*Value_BoolValue) isValue_Value() {} @@ -1337,7 +1337,7 @@ type ListValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values" + Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values" } func (x *ListValue) Reset() { @@ -1449,11 +1449,11 @@ type isListOptionValue_Option interface { } type ListOptionValue_StringValue struct { - StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" } type ListOptionValue_IntValue struct { - IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" } func (*ListOptionValue_StringValue) isListOptionValue_Option() {} diff --git a/protogen/gen/ocis/services/policies/v0/policies.pb.go b/protogen/gen/ocis/services/policies/v0/policies.pb.go new file mode 100644 index 000000000..fa2f474f9 --- /dev/null +++ b/protogen/gen/ocis/services/policies/v0/policies.pb.go @@ -0,0 +1,266 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: ocis/services/policies/v0/policies.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/policies/v0" + _ "google.golang.org/genproto/googleapis/api/annotations" + 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 EvaluateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Environment *v0.Environment `protobuf:"bytes,2,opt,name=environment,proto3" json:"environment,omitempty"` +} + +func (x *EvaluateRequest) Reset() { + *x = EvaluateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EvaluateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateRequest) ProtoMessage() {} + +func (x *EvaluateRequest) ProtoReflect() protoreflect.Message { + mi := &file_ocis_services_policies_v0_policies_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 EvaluateRequest.ProtoReflect.Descriptor instead. +func (*EvaluateRequest) Descriptor() ([]byte, []int) { + return file_ocis_services_policies_v0_policies_proto_rawDescGZIP(), []int{0} +} + +func (x *EvaluateRequest) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *EvaluateRequest) GetEnvironment() *v0.Environment { + if x != nil { + return x.Environment + } + return nil +} + +type EvaluateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result bool `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"` +} + +func (x *EvaluateResponse) Reset() { + *x = EvaluateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ocis_services_policies_v0_policies_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EvaluateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EvaluateResponse) ProtoMessage() {} + +func (x *EvaluateResponse) ProtoReflect() protoreflect.Message { + mi := &file_ocis_services_policies_v0_policies_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 EvaluateResponse.ProtoReflect.Descriptor instead. +func (*EvaluateResponse) Descriptor() ([]byte, []int) { + return file_ocis_services_policies_v0_policies_proto_rawDescGZIP(), []int{1} +} + +func (x *EvaluateResponse) GetResult() bool { + if x != nil { + return x.Result + } + return false +} + +var File_ocis_services_policies_v0_policies_proto protoreflect.FileDescriptor + +var file_ocis_services_policies_v0_policies_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x63, 0x69, 0x73, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x2e, 0x76, 0x30, 0x1a, 0x28, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, + 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 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, 0x1a, + 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x71, 0x0a, + 0x0f, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x48, 0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63, + 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x22, 0x2a, 0x0a, 0x10, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0x9e, 0x01, 0x0a, + 0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x12, 0x89, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x2a, + 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6f, 0x63, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x22, + 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x42, 0xe2, 0x02, + 0x5a, 0x3e, 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, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x76, 0x30, + 0x92, 0x41, 0x9e, 0x02, 0x12, 0xb6, 0x01, 0x0a, 0x20, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, + 0x64, 0x20, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, + 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 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, 0x3b, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x27, 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, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ocis_services_policies_v0_policies_proto_rawDescOnce sync.Once + file_ocis_services_policies_v0_policies_proto_rawDescData = file_ocis_services_policies_v0_policies_proto_rawDesc +) + +func file_ocis_services_policies_v0_policies_proto_rawDescGZIP() []byte { + file_ocis_services_policies_v0_policies_proto_rawDescOnce.Do(func() { + file_ocis_services_policies_v0_policies_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_services_policies_v0_policies_proto_rawDescData) + }) + return file_ocis_services_policies_v0_policies_proto_rawDescData +} + +var file_ocis_services_policies_v0_policies_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_ocis_services_policies_v0_policies_proto_goTypes = []interface{}{ + (*EvaluateRequest)(nil), // 0: ocis.services.policies.v0.EvaluateRequest + (*EvaluateResponse)(nil), // 1: ocis.services.policies.v0.EvaluateResponse + (*v0.Environment)(nil), // 2: ocis.messages.policies.v0.Environment +} +var file_ocis_services_policies_v0_policies_proto_depIdxs = []int32{ + 2, // 0: ocis.services.policies.v0.EvaluateRequest.environment:type_name -> ocis.messages.policies.v0.Environment + 0, // 1: ocis.services.policies.v0.policiesProvider.Evaluate:input_type -> ocis.services.policies.v0.EvaluateRequest + 1, // 2: ocis.services.policies.v0.policiesProvider.Evaluate:output_type -> ocis.services.policies.v0.EvaluateResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_ocis_services_policies_v0_policies_proto_init() } +func file_ocis_services_policies_v0_policies_proto_init() { + if File_ocis_services_policies_v0_policies_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ocis_services_policies_v0_policies_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EvaluateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ocis_services_policies_v0_policies_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EvaluateResponse); 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_policies_v0_policies_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ocis_services_policies_v0_policies_proto_goTypes, + DependencyIndexes: file_ocis_services_policies_v0_policies_proto_depIdxs, + MessageInfos: file_ocis_services_policies_v0_policies_proto_msgTypes, + }.Build() + File_ocis_services_policies_v0_policies_proto = out.File + file_ocis_services_policies_v0_policies_proto_rawDesc = nil + file_ocis_services_policies_v0_policies_proto_goTypes = nil + file_ocis_services_policies_v0_policies_proto_depIdxs = nil +} diff --git a/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go b/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go new file mode 100644 index 000000000..4d813c168 --- /dev/null +++ b/protogen/gen/ocis/services/policies/v0/policies.pb.micro.go @@ -0,0 +1,103 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: ocis/services/policies/v0/policies.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/policies/v0" + _ "google.golang.org/genproto/googleapis/api/annotations" + 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 PoliciesProvider service + +func NewPoliciesProviderEndpoints() []*api.Endpoint { + return []*api.Endpoint{ + { + Name: "PoliciesProvider.Evaluate", + Path: []string{"/api/v0/policies/evaluate"}, + Method: []string{"POST"}, + Handler: "rpc", + }, + } +} + +// Client API for PoliciesProvider service + +type PoliciesProviderService interface { + Evaluate(ctx context.Context, in *EvaluateRequest, opts ...client.CallOption) (*EvaluateResponse, error) +} + +type policiesProviderService struct { + c client.Client + name string +} + +func NewPoliciesProviderService(name string, c client.Client) PoliciesProviderService { + return &policiesProviderService{ + c: c, + name: name, + } +} + +func (c *policiesProviderService) Evaluate(ctx context.Context, in *EvaluateRequest, opts ...client.CallOption) (*EvaluateResponse, error) { + req := c.c.NewRequest(c.name, "PoliciesProvider.Evaluate", in) + out := new(EvaluateResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for PoliciesProvider service + +type PoliciesProviderHandler interface { + Evaluate(context.Context, *EvaluateRequest, *EvaluateResponse) error +} + +func RegisterPoliciesProviderHandler(s server.Server, hdlr PoliciesProviderHandler, opts ...server.HandlerOption) error { + type policiesProvider interface { + Evaluate(ctx context.Context, in *EvaluateRequest, out *EvaluateResponse) error + } + type PoliciesProvider struct { + policiesProvider + } + h := &policiesProviderHandler{hdlr} + opts = append(opts, api.WithEndpoint(&api.Endpoint{ + Name: "PoliciesProvider.Evaluate", + Path: []string{"/api/v0/policies/evaluate"}, + Method: []string{"POST"}, + Handler: "rpc", + })) + return s.Handle(s.NewHandler(&PoliciesProvider{h}, opts...)) +} + +type policiesProviderHandler struct { + PoliciesProviderHandler +} + +func (h *policiesProviderHandler) Evaluate(ctx context.Context, in *EvaluateRequest, out *EvaluateResponse) error { + return h.PoliciesProviderHandler.Evaluate(ctx, in, out) +} diff --git a/protogen/gen/ocis/services/policies/v0/policies.swagger.json b/protogen/gen/ocis/services/policies/v0/policies.swagger.json new file mode 100644 index 000000000..6eaf5b980 --- /dev/null +++ b/protogen/gen/ocis/services/policies/v0/policies.swagger.json @@ -0,0 +1,216 @@ +{ + "swagger": "2.0", + "info": { + "title": "ownCloud Infinite Scale policies", + "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": "policiesProvider" + } + ], + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api/v0/policies/evaluate": { + "post": { + "operationId": "policiesProvider_Evaluate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v0EvaluateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v0EvaluateRequest" + } + } + ], + "tags": [ + "policiesProvider" + ] + } + } + }, + "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" + } + } + } + }, + "v0Environment": { + "type": "object", + "properties": { + "stage": { + "$ref": "#/definitions/v0Stage" + }, + "user": { + "$ref": "#/definitions/v0User" + }, + "request": { + "$ref": "#/definitions/v0Request" + }, + "resource": { + "$ref": "#/definitions/v0Resource" + } + } + }, + "v0EvaluateRequest": { + "type": "object", + "properties": { + "query": { + "type": "string" + }, + "environment": { + "$ref": "#/definitions/v0Environment" + } + } + }, + "v0EvaluateResponse": { + "type": "object", + "properties": { + "result": { + "type": "boolean" + } + } + }, + "v0Request": { + "type": "object", + "properties": { + "method": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, + "v0Resource": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v0ResourceID" + }, + "name": { + "type": "string" + }, + "size": { + "type": "string", + "format": "uint64" + }, + "url": { + "type": "string" + } + } + }, + "v0ResourceID": { + "type": "object", + "properties": { + "storageId": { + "type": "string" + }, + "opaqueId": { + "type": "string" + }, + "spaceId": { + "type": "string" + } + } + }, + "v0Stage": { + "type": "string", + "enum": [ + "STAGE_PP", + "STAGE_HTTP" + ], + "default": "STAGE_PP" + }, + "v0User": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v0UserID" + }, + "username": { + "type": "string" + }, + "mail": { + "type": "string" + }, + "displayName": { + "type": "string" + }, + "groups": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v0UserID": { + "type": "object", + "properties": { + "opaqueId": { + "type": "string" + } + } + } + }, + "externalDocs": { + "description": "Developer Manual", + "url": "https://owncloud.dev/services/policies/" + } +} diff --git a/protogen/proto/buf.gen.yaml b/protogen/proto/buf.gen.yaml index 37f05fce2..2285da286 100644 --- a/protogen/proto/buf.gen.yaml +++ b/protogen/proto/buf.gen.yaml @@ -23,7 +23,9 @@ plugins: ocis.services.store.v0;\ ocis.messages.store.v0;\ ocis.services.eventhistory.v0;\ - ocis.messages.eventhistory.v0" + ocis.messages.eventhistory.v0;\ + ocis.services.policies.v0;\ + ocis.messages.policies.v0" - name: openapiv2 path: ../../.bingo/protoc-gen-openapiv2 diff --git a/protogen/proto/ocis/messages/policies/v0/policies.proto b/protogen/proto/ocis/messages/policies/v0/policies.proto new file mode 100644 index 000000000..e6763745f --- /dev/null +++ b/protogen/proto/ocis/messages/policies/v0/policies.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package ocis.messages.policies.v0; + +option go_package = "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0"; + +message User { + message ID { + string opaque_id = 1; + } + + ID id = 1; + string username = 2; + string mail = 3; + string display_name = 4; + repeated string groups = 5; +} + +message Resource { + message ID { + string storage_id = 1; + string opaque_id = 2; + string space_id = 3; + } + + ID id = 1; + string name = 2; + uint64 size = 3; + string url = 4; +} + +message Request { + string method = 1; + string path = 2; +} + +enum Stage { + STAGE_PP = 0; + STAGE_HTTP = 1; +} + +message Environment { + Stage stage = 1; + User user = 2; + Request request = 3; + Resource resource = 4; +} + + diff --git a/protogen/proto/ocis/services/policies/v0/policies.proto b/protogen/proto/ocis/services/policies/v0/policies.proto new file mode 100644 index 000000000..e2612db8d --- /dev/null +++ b/protogen/proto/ocis/services/policies/v0/policies.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +package ocis.services.policies.v0; + +option go_package = "github.com/owncloud/ocis/protogen/gen/ocis/service/policies/v0"; + +import "ocis/messages/policies/v0/policies.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "google/api/annotations.proto"; + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "ownCloud Infinite Scale policies"; + 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"; + }; + }; + schemes: HTTP; + schemes: HTTPS; + consumes: "application/json"; + produces: "application/json"; + external_docs: { + description: "Developer Manual"; + url: "https://owncloud.dev/services/policies/"; + }; +}; + +service policiesProvider { + rpc Evaluate(EvaluateRequest) returns (EvaluateResponse) { + option (google.api.http) = { + post: "/api/v0/policies/evaluate", + body: "*" + }; + }; +} + +message EvaluateRequest { + string query = 1; + ocis.messages.policies.v0.Environment environment = 2; +} + +message EvaluateResponse { + bool result = 1; +} diff --git a/services/policies/Makefile b/services/policies/Makefile new file mode 100644 index 000000000..2af589761 --- /dev/null +++ b/services/policies/Makefile @@ -0,0 +1,37 @@ +SHELL := bash +NAME := policies + +include ../../.make/recursion.mk + +############ tooling ############ +ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI +include ../../.bingo/Variables.mk +endif + +############ go tooling ############ +include ../../.make/go.mk + +############ release ############ +include ../../.make/release.mk + +############ docs generate ############ +include ../../.make/docs.mk + +.PHONY: docs-generate +docs-generate: config-docs-generate + +############ generate ############ +include ../../.make/generate.mk + +.PHONY: ci-go-generate +ci-go-generate: # CI runs ci-node-generate automatically before this target + +.PHONY: ci-node-generate +ci-node-generate: + +############ licenses ############ +.PHONY: ci-node-check-licenses +ci-node-check-licenses: + +.PHONY: ci-node-save-licenses +ci-node-save-licenses: diff --git a/services/policies/README.md b/services/policies/README.md new file mode 100644 index 000000000..82a67e18b --- /dev/null +++ b/services/policies/README.md @@ -0,0 +1,73 @@ +# Policies Service + +The policies service provides a new grpc api which can be used to return whether a requested operation is allowed or not. To do so, Open Policy Agent (OPA) is used to determine the set of rules of what is permitted and what is not. + +Policies are written in the [rego query language](https://www.openpolicyagent.org/docs/latest/policy-language/). The location of the rego files can be configured via yaml, a configuration via environment variables is not possible. + +The Policies Service consists of the following modules: + +* Proxy Authorization (middleware) +* Event Authorization (async post-processing) +* GRPC API (can be used from other services) + +To configure the Policies Service, three environment variables need to be defined: + +* `POLICIES_ENGINE_TIMEOUT` +* `POLICIES_POSTPROCESSING_QUERY` +* `PROXY_POLICIES_QUERY` + +Note that each query setting defines the [Complete Rules](https://www.openpolicyagent.org/docs/latest/#complete-rules) variable defined in the rego rule set the corresponding step uses for the evaluation. If the variable is mistyped or not found, the evaluation defaults to deny. Individual query definitions can be defined for each module. + +To activate a the policies service for a module, it must be started with a yaml configuration that points to one or more rego files. Note that if the service is scaled horizontally, each instance should have access to the same rego files to avoid unpredictable results. If a file path has been configured but the file it is not present or accessible, the evaluation defaults to deny. + +When using async post-processing which is done via the postprocessing service, the value `policies` must be added to the `POSTPROCESSING_STEPS` configuration in postprocessing service in the order where the evaluation should take place. + +## Modules + +### GRPC Service + +This service can be used from any other internal service. It can also be used for example by third parties to find out if an action is allowed or not. This layer is already used by the proxy middleware. + +### Event Service + +This layer is event-based and part of the postprocessing service. Since processing at this point is asynchronous, the operations can also take longer and be more expensive, like evaluating the bytes of a file. + +### Proxy Middleware + +The [ocis proxy](../proxy) already includes such a middleware which uses the [GRPC service](#grpc-service) to evaluate the policies by using a configurable query. Since the Proxy is in heavy use and every request is processed here, only simple and quick decisions should be evaluated. More complex queries such as file evaluation are strongly discouraged. + +## Example Policies + +The policies service contains a set of pre-configured example policies. Those policies can be found in the [examples directory](../../deployments/examples/service_policies/policies). The contained policies disallows ocis to create certain filetypes, both for the proxy middleware and the events service. + +To use the example policies, it's required to configure ocis to use these files which can be done by adding: + +```yaml +policies: + engine: + policies: + - YOUR_PATH/examples/policies/proxy.rego + - YOUR_PATH/examples/policies/postprocessing.rego + - YOUR_PATH/examples/policies/utils.rego +``` +Once the policies are configured correctly, the _QUERY configuration needs to be defined for the proxy middleware and for the events service. + +### Proxy + +```yaml +proxy: + policies_middleware: + query: data.proxy.granted +``` + +The same can be achieved by setting the `PROXY_POLICIES_QUERY=data.proxy.granted` environment variable. + +### ASYNC Postprocessing + +```yaml +policies: + postprocessing: + query: data.postprocessing.granted +``` + +The same can be achieved by setting the `POLICIES_POSTPROCESSING_QUERY=data.postprocessing.granted` environment variable. As soon as that query is configured correctly, postprocessing must be informed to use the policies step by setting the environment variable `POSTPROCESSING_STEPS=policies`. Note that additional steps can be configured and their appearance defines the order of processing. For details see the postprocessing service documentation. diff --git a/services/policies/cmd/policies/main.go b/services/policies/cmd/policies/main.go new file mode 100644 index 000000000..db0896e40 --- /dev/null +++ b/services/policies/cmd/policies/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "os" + + "github.com/owncloud/ocis/v2/services/policies/pkg/command" + "github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults" +) + +func main() { + if err := command.Execute(defaults.DefaultConfig()); err != nil { + os.Exit(1) + } +} diff --git a/services/policies/pkg/command/health.go b/services/policies/pkg/command/health.go new file mode 100644 index 000000000..ec03f6a0c --- /dev/null +++ b/services/policies/pkg/command/health.go @@ -0,0 +1,60 @@ +package command + +import ( + "fmt" + "github.com/owncloud/ocis/v2/ocis-pkg/log" + "net/http" + + "github.com/owncloud/ocis/v2/ocis-pkg/config/configlog" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" + "github.com/owncloud/ocis/v2/services/policies/pkg/config/parser" + "github.com/urfave/cli/v2" +) + +// Health is the entrypoint for the health command. +func Health(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "health", + Usage: "check health status", + Category: "info", + Before: func(c *cli.Context) error { + return configlog.ReturnError(parser.ParseConfig(cfg)) + }, + Action: func(c *cli.Context) error { + logger := log.NewLogger( + log.Name(cfg.Service.Name), + log.Level(cfg.Log.Level), + log.Pretty(cfg.Log.Pretty), + log.Color(cfg.Log.Color), + log.File(cfg.Log.File), + ) + + resp, err := http.Get( + fmt.Sprintf( + "http://%s/healthz", + cfg.Debug.Addr, + ), + ) + + if err != nil { + logger.Fatal(). + Err(err). + Msg("Failed to request health check") + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + logger.Fatal(). + Int("code", resp.StatusCode). + Msg("Health seems to be in bad state") + } + + logger.Debug(). + Int("code", resp.StatusCode). + Msg("Health got a good state") + + return nil + }, + } +} diff --git a/services/policies/pkg/command/root.go b/services/policies/pkg/command/root.go new file mode 100644 index 000000000..b57f8aa62 --- /dev/null +++ b/services/policies/pkg/command/root.go @@ -0,0 +1,54 @@ +package command + +import ( + "context" + "os" + + "github.com/owncloud/ocis/v2/ocis-pkg/clihelper" + ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" + "github.com/thejerf/suture/v4" + "github.com/urfave/cli/v2" +) + +// GetCommands provides all commands for this service +func GetCommands(cfg *config.Config) cli.Commands { + return []*cli.Command{ + Server(cfg), + Health(cfg), + Version(cfg), + } +} + +// Execute is the entry point for the policies command. +func Execute(cfg *config.Config) error { + app := clihelper.DefaultApp(&cli.App{ + Name: "policies", + Usage: "Serve ownCloud policies for oCIS", + Commands: GetCommands(cfg), + }) + + return app.Run(os.Args) +} + +// SutureService allows for the web command to be embedded and supervised by a suture supervisor tree. +type SutureService struct { + cfg *config.Config +} + +// NewSutureService creates a new web.SutureService +func NewSutureService(cfg *ociscfg.Config) suture.Service { + cfg.Policies.Commons = cfg.Commons + return SutureService{ + cfg: cfg.Policies, + } +} + +func (s SutureService) Serve(ctx context.Context) error { + s.cfg.Context = ctx + if err := Execute(s.cfg); err != nil { + return err + } + + return nil +} diff --git a/services/policies/pkg/command/server.go b/services/policies/pkg/command/server.go new file mode 100644 index 000000000..9c3cb3eb9 --- /dev/null +++ b/services/policies/pkg/command/server.go @@ -0,0 +1,193 @@ +package command + +import ( + "context" + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "net/http" + "os" + + "github.com/cs3org/reva/v2/pkg/events/stream" + "github.com/go-micro/plugins/v4/events/natsjs" + "github.com/oklog/run" + "github.com/owncloud/ocis/v2/ocis-pkg/config/configlog" + ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto" + "github.com/owncloud/ocis/v2/ocis-pkg/log" + "github.com/owncloud/ocis/v2/ocis-pkg/service/debug" + "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc" + "github.com/owncloud/ocis/v2/ocis-pkg/version" + svcProtogen "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" + "github.com/owncloud/ocis/v2/services/policies/pkg/config/parser" + "github.com/owncloud/ocis/v2/services/policies/pkg/engine" + svcEvent "github.com/owncloud/ocis/v2/services/policies/pkg/service/event" + svcGRPC "github.com/owncloud/ocis/v2/services/policies/pkg/service/grpc" + "github.com/urfave/cli/v2" +) + +// Server is the entrypoint for the server command. +func Server(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "server", + Usage: fmt.Sprintf("start the %s service without runtime (unsupervised mode)", "authz"), + Category: "server", + Before: func(c *cli.Context) error { + return configlog.ReturnFatal(parser.ParseConfig(cfg)) + }, + Action: func(c *cli.Context) error { + var ( + gr = run.Group{} + ctx, cancel = func() (context.Context, context.CancelFunc) { + if cfg.Context == nil { + return context.WithCancel(context.Background()) + } + return context.WithCancel(cfg.Context) + }() + logger = log.NewLogger( + log.Name(cfg.Service.Name), + log.Level(cfg.Log.Level), + log.Pretty(cfg.Log.Pretty), + log.Color(cfg.Log.Color), + log.File(cfg.Log.File), + ) + ) + defer cancel() + + e, err := engine.NewOPA(cfg.Engine.Timeout, cfg.Engine) + if err != nil { + return err + } + + { + err = grpc.Configure(grpc.GetClientOptions(cfg.GRPCClientTLS)...) + if err != nil { + return err + } + + svc, err := grpc.NewService( + grpc.Logger(logger), + grpc.TLSEnabled(cfg.GRPC.TLS.Enabled), + grpc.TLSCert( + cfg.GRPC.TLS.Cert, + cfg.GRPC.TLS.Key, + ), + grpc.Name(cfg.Service.Name), + grpc.Context(ctx), + grpc.Address(cfg.GRPC.Addr), + grpc.Namespace(cfg.GRPC.Namespace), + grpc.Version(version.GetString()), + ) + if err != nil { + return err + } + + grpcSvc, err := svcGRPC.New(e) + if err != nil { + return err + } + + if err := svcProtogen.RegisterPoliciesProviderHandler( + svc.Server(), + grpcSvc, + ); err != nil { + return err + } + + gr.Add(svc.Run, func(_ error) { + cancel() + }) + } + + { + var tlsConf *tls.Config + + if cfg.Events.EnableTLS { + var rootCAPool *x509.CertPool + if cfg.Events.TLSRootCACertificate != "" { + rootCrtFile, err := os.Open(cfg.Events.TLSRootCACertificate) + if err != nil { + return err + } + + rootCAPool, err = ociscrypto.NewCertPoolFromPEM(rootCrtFile) + if err != nil { + return err + } + cfg.Events.TLSInsecure = false + } + + tlsConf = &tls.Config{ + RootCAs: rootCAPool, + } + } + + bus, err := stream.Nats( + natsjs.TLSConfig(tlsConf), + natsjs.Address(cfg.Events.Endpoint), + natsjs.ClusterID(cfg.Events.Cluster), + ) + if err != nil { + return err + } + + eventSvc, err := svcEvent.New(bus, logger, e, cfg.Postprocessing.Query) + if err != nil { + return err + } + + gr.Add(eventSvc.Run, func(_ error) { + cancel() + }) + } + + { + server := debug.NewService( + debug.Logger(logger), + debug.Name(cfg.Service.Name), + debug.Version(version.GetString()), + debug.Address(cfg.Debug.Addr), + debug.Token(cfg.Debug.Token), + debug.Pprof(cfg.Debug.Pprof), + debug.Zpages(cfg.Debug.Zpages), + debug.Health( + func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + + // TODO: check if services are up and running + + _, err := io.WriteString(w, http.StatusText(http.StatusOK)) + // io.WriteString should not fail but if it does we want to know. + if err != nil { + panic(err) + } + }, + ), + debug.Ready( + func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + + // TODO: check if services are up and running + + _, err := io.WriteString(w, http.StatusText(http.StatusOK)) + // io.WriteString should not fail but if it does we want to know. + if err != nil { + panic(err) + } + }, + ), + ) + + gr.Add(server.ListenAndServe, func(_ error) { + _ = server.Shutdown(ctx) + cancel() + }) + } + + return gr.Run() + }, + } +} diff --git a/services/policies/pkg/command/version.go b/services/policies/pkg/command/version.go new file mode 100644 index 000000000..48cfcfa24 --- /dev/null +++ b/services/policies/pkg/command/version.go @@ -0,0 +1,50 @@ +package command + +import ( + "fmt" + "os" + + "github.com/owncloud/ocis/v2/ocis-pkg/registry" + "github.com/owncloud/ocis/v2/ocis-pkg/version" + + tw "github.com/olekukonko/tablewriter" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" + "github.com/urfave/cli/v2" +) + +// Version prints the service versions of all running instances. +func Version(cfg *config.Config) *cli.Command { + return &cli.Command{ + Name: "version", + Usage: "print the version of this binary and the running service instances", + Category: "info", + Action: func(c *cli.Context) error { + fmt.Println("Version: " + version.GetString()) + fmt.Printf("Compiled: %s\n", version.Compiled()) + fmt.Println("") + + reg := registry.GetRegistry() + services, err := reg.GetService(cfg.GRPC.Namespace + "." + cfg.Service.Name) + if err != nil { + fmt.Println(fmt.Errorf("could not get %s services from the registry: %v", cfg.Service.Name, err)) + return err + } + + if len(services) == 0 { + fmt.Println("No running " + cfg.Service.Name + " service found.") + return nil + } + + table := tw.NewWriter(os.Stdout) + table.SetHeader([]string{"Version", "Address", "Id"}) + table.SetAutoFormatHeaders(false) + for _, s := range services { + for _, n := range s.Nodes { + table.Append([]string{s.Version, n.Address, n.Id}) + } + } + table.Render() + return nil + }, + } +} diff --git a/services/policies/pkg/config/config.go b/services/policies/pkg/config/config.go new file mode 100644 index 000000000..9e8f15a69 --- /dev/null +++ b/services/policies/pkg/config/config.go @@ -0,0 +1,77 @@ +package config + +import ( + "context" + "github.com/owncloud/ocis/v2/ocis-pkg/shared" + "time" +) + +// Config combines all available configuration parts. +type Config struct { + Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service + GRPC GRPC `yaml:"grpc"` + Service Service `yaml:"-"` + Debug Debug `yaml:"debug"` + TokenManager *TokenManager `yaml:"token_manager"` + Events Events `yaml:"events"` + Reva *shared.Reva `yaml:"reva"` + GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` + MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;POLICIES_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services."` + Context context.Context `yaml:"-"` + Log *Log `yaml:"log"` + Engine Engine `yaml:"engine"` + Postprocessing Postprocessing `yaml:"postprocessing"` +} + +// Service defines the available service configuration. +type Service struct { + Name string `yaml:"-"` +} + +// GRPC defines the available grpc configuration. +type GRPC struct { + Addr string `ocisConfig:"addr" env:"POLICIES_GRPC_ADDR" desc:"The bind address of the GRPC service."` + Namespace string `ocisConfig:"-" yaml:"-"` + TLS *shared.GRPCServiceTLS `yaml:"tls"` +} + +// TokenManager is the config for using the reva token manager +type TokenManager struct { + JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;POLICIES_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."` +} + +// Engine configures the policy engine. +type Engine struct { + Timeout time.Duration `yaml:"timeout" env:"POLICIES_ENGINE_TIMEOUT" desc:"Sets the timeout the rego expression evaluation can take. The timeout can be set as number followed by a unit identifier like ms, s, etc. Rules default to deny if the timeout was reached."` + Policies []string `yaml:"policies"` +} + +// Postprocessing defines the config options for the postprocessing policy handling. +type Postprocessing struct { + Query string `yaml:"query" env:"POLICIES_POSTPROCESSING_QUERY" desc:"Defines the 'Complete Rules' variable defined in the rego rule set this step uses for its evaluation. Defaults to deny if the variable was not found."` +} + +// Events combines the configuration options for the event bus. +type Events struct { + Endpoint string `yaml:"endpoint" env:"POLICIES_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture."` + Cluster string `yaml:"cluster" env:"POLICIES_EVENTS_CLUSTER" desc:"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."` + TLSInsecure bool `yaml:"tls_insecure" env:"OCIS_INSECURE;POLICIES_EVENTS_TLS_INSECURE" desc:"Whether the server should skip the client certificate verification during the TLS handshake."` + TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"POLICIES_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided POLICIES_EVENTS_TLS_INSECURE will be seen as false."` + EnableTLS bool `yaml:"enable_tls" env:"OCIS_EVENTS_ENABLE_TLS;POLICIES_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the ocis service which receives and delivers events between the services."` +} + +// Log defines the available log configuration. +type Log struct { + Level string `mapstructure:"level" env:"OCIS_LOG_LEVEL;POLICIES_LOG_LEVEL" desc:"The log level. Valid values are: \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"."` + Pretty bool `mapstructure:"pretty" env:"OCIS_LOG_PRETTY;POLICIES_LOG_PRETTY" desc:"Activates pretty log output."` + Color bool `mapstructure:"color" env:"OCIS_LOG_COLOR;POLICIES_LOG_COLOR" desc:"Activates colorized log output."` + File string `mapstructure:"file" env:"OCIS_LOG_FILE;POLICIES_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set."` +} + +// Debug defines the available debug configuration. +type Debug struct { + Addr string `yaml:"addr" env:"POLICIES_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."` + Token string `yaml:"token" env:"POLICIES_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."` + Pprof bool `yaml:"pprof" env:"POLICIES_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."` + Zpages bool `yaml:"zpages" env:"POLICIES_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."` +} diff --git a/services/policies/pkg/config/defaults/defaultconfig.go b/services/policies/pkg/config/defaults/defaultconfig.go new file mode 100644 index 000000000..272809b62 --- /dev/null +++ b/services/policies/pkg/config/defaults/defaultconfig.go @@ -0,0 +1,87 @@ +package defaults + +import ( + "time" + + "github.com/owncloud/ocis/v2/ocis-pkg/shared" + "github.com/owncloud/ocis/v2/ocis-pkg/structs" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" +) + +// FullDefaultConfig returns a fully initialized default configuration which is needed for doc generation. +func FullDefaultConfig() *config.Config { + cfg := DefaultConfig() + EnsureDefaults(cfg) + Sanitize(cfg) + return cfg +} + +// DefaultConfig returns the default config +func DefaultConfig() *config.Config { + return &config.Config{ + Service: config.Service{ + Name: "policies", + }, + Debug: config.Debug{ + Addr: "127.0.0.1:9129", + Token: "", + Pprof: false, + Zpages: false, + }, + GRPC: config.GRPC{ + Addr: "127.0.0.1:9125", + Namespace: "com.owncloud.api", + }, + Reva: shared.DefaultRevaConfig(), + Events: config.Events{ + Endpoint: "127.0.0.1:9233", + Cluster: "ocis-cluster", + EnableTLS: false, + }, + Engine: config.Engine{ + Timeout: 10 * time.Second, + }, + } +} + +func EnsureDefaults(cfg *config.Config) { + if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil { + cfg.TokenManager = &config.TokenManager{ + JWTSecret: cfg.Commons.TokenManager.JWTSecret, + } + } else if cfg.TokenManager == nil { + cfg.TokenManager = &config.TokenManager{} + } + if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" { + cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey + } + + if cfg.Reva == nil && cfg.Commons != nil && cfg.Commons.Reva != nil { + cfg.Reva = &shared.Reva{ + Address: cfg.Commons.Reva.Address, + TLS: cfg.Commons.Reva.TLS, + } + } else if cfg.Reva == nil { + cfg.Reva = &shared.Reva{} + } + + if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil { + cfg.Log = &config.Log{ + Level: cfg.Commons.Log.Level, + Pretty: cfg.Commons.Log.Pretty, + Color: cfg.Commons.Log.Color, + File: cfg.Commons.Log.File, + } + } else if cfg.Log == nil { + cfg.Log = &config.Log{} + } + + if cfg.GRPCClientTLS == nil && cfg.Commons != nil { + cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS) + } + if cfg.GRPC.TLS == nil && cfg.Commons != nil { + cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS) + } +} + +func Sanitize(_ *config.Config) {} diff --git a/services/policies/pkg/config/parser/parse.go b/services/policies/pkg/config/parser/parse.go new file mode 100644 index 000000000..873472671 --- /dev/null +++ b/services/policies/pkg/config/parser/parse.go @@ -0,0 +1,42 @@ +package parser + +import ( + "errors" + + ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config" + "github.com/owncloud/ocis/v2/ocis-pkg/shared" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" + "github.com/owncloud/ocis/v2/services/policies/pkg/config/defaults" + + "github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode" +) + +// ParseConfig loads configuration from known paths. +func ParseConfig(cfg *config.Config) error { + _, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg) + if err != nil { + return err + } + + defaults.EnsureDefaults(cfg) + + // load all env variables relevant to the config in the current context. + if err := envdecode.Decode(cfg); err != nil { + // no environment variable set for this config is an expected "error" + if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) { + return err + } + } + + defaults.Sanitize(cfg) + + return Validate(cfg) +} + +func Validate(cfg *config.Config) error { + if cfg.TokenManager.JWTSecret == "" { + return shared.MissingJWTTokenError(cfg.Service.Name) + } + + return nil +} diff --git a/services/policies/pkg/engine/engine.go b/services/policies/pkg/engine/engine.go new file mode 100644 index 000000000..651f1cbff --- /dev/null +++ b/services/policies/pkg/engine/engine.go @@ -0,0 +1,74 @@ +package engine + +import ( + "context" + "encoding/json" + + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0" + "google.golang.org/protobuf/encoding/protojson" +) + +// Engine defines the granted handlers. +type Engine interface { + Evaluate(ctx context.Context, query string, env Environment) (bool, error) +} + +type ( + // Stage defines the used auth stage + Stage string +) + +var ( + // StagePP defines the post-processing stage + StagePP Stage = "pp" + + // StageHTTP defines the http stage + StageHTTP Stage = "http" +) + +// Resource contains resource information and is used as part of the evaluated environment. +type Resource struct { + ID provider.ResourceId `json:"resource_id"` + Name string `json:"name"` + URL string `json:"url"` + Size uint64 `json:"size"` +} + +// Request contains request information and is used as part of the evaluated environment. +type Request struct { + Method string `json:"method"` + Path string `json:"path"` +} + +// Environment contains every data that is needed to decide if the request should pass or not +type Environment struct { + Stage Stage `json:"stage"` + User user.User `json:"user"` + Request Request `json:"request"` + Resource Resource `json:"resource"` +} + +// NewEnvironmentFromPB converts a PBEnvironment to Environment. +func NewEnvironmentFromPB(pEnv *v0.Environment) (Environment, error) { + env := Environment{} + + rData, err := protojson.Marshal(pEnv) + if err != nil { + return env, err + } + + if err := json.Unmarshal(rData, &env); err != nil { + return env, err + } + + switch pEnv.Stage { + case v0.Stage_STAGE_HTTP: + env.Stage = StageHTTP + case v0.Stage_STAGE_PP: + env.Stage = StagePP + } + + return env, nil +} diff --git a/services/policies/pkg/engine/engine_suite_test.go b/services/policies/pkg/engine/engine_suite_test.go new file mode 100644 index 000000000..062fcadb1 --- /dev/null +++ b/services/policies/pkg/engine/engine_suite_test.go @@ -0,0 +1,13 @@ +package engine_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestEngine(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Engine Suite") +} diff --git a/services/policies/pkg/engine/engine_test.go b/services/policies/pkg/engine/engine_test.go new file mode 100644 index 000000000..3ac7c5101 --- /dev/null +++ b/services/policies/pkg/engine/engine_test.go @@ -0,0 +1,25 @@ +package engine_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + pMessage "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0" + "github.com/owncloud/ocis/v2/services/policies/pkg/engine" +) + +var _ = Describe("Engine", func() { + DescribeTable("NewEnvironmentFromPB", + func(incomingStage pMessage.Stage, outgoinStage engine.Stage) { + pEnv := &pMessage.Environment{ + Stage: incomingStage, + } + + env, err := engine.NewEnvironmentFromPB(pEnv) + Expect(err).ToNot(HaveOccurred()) + + Expect(env.Stage).To(Equal(outgoinStage)) + }, + Entry("http stage", pMessage.Stage_STAGE_HTTP, engine.StageHTTP), + Entry("pp stage", pMessage.Stage_STAGE_PP, engine.StagePP), + ) +}) diff --git a/services/policies/pkg/engine/opa.go b/services/policies/pkg/engine/opa.go new file mode 100644 index 000000000..e317fc030 --- /dev/null +++ b/services/policies/pkg/engine/opa.go @@ -0,0 +1,124 @@ +package engine + +import ( + "bytes" + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/cs3org/reva/v2/pkg/rhttp" + "github.com/gabriel-vasile/mimetype" + "github.com/open-policy-agent/opa/ast" + "github.com/open-policy-agent/opa/rego" + "github.com/open-policy-agent/opa/types" + "github.com/owncloud/ocis/v2/services/policies/pkg/config" +) + +// OPA wraps open policy agent makes it possible to ask if an action is granted. +type OPA struct { + policies []string + timeout time.Duration +} + +// NewOPA returns a ready to use opa engine. +func NewOPA(timeout time.Duration, conf config.Engine) (OPA, error) { + return OPA{ + policies: conf.Policies, + timeout: timeout, + }, + nil +} + +// Evaluate evaluates the opa policies and returns the result. +func (o OPA) Evaluate(ctx context.Context, qs string, env Environment) (bool, error) { + ctx, cancel := context.WithTimeout(ctx, o.timeout) + defer cancel() + + q, err := rego.New( + rego.Query(qs), + rego.Load(o.policies, nil), + GetMimetype, + GetResource, + ).PrepareForEval(ctx) + if err != nil { + return false, err + } + + result, err := q.Eval(ctx, rego.EvalInput(env)) + if err != nil { + return false, err + } + + return result.Allowed(), nil +} + +var GetResource = rego.Function1( + ®o.Function{ + Name: "ocis_get_resource", + Decl: types.NewFunction(types.Args(types.S), types.A), + Memoize: true, + Nondeterministic: true, + }, + func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) { + var url string + + if err := ast.As(a.Value, &url); err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + + client := rhttp.GetHTTPClient(rhttp.Insecure(true)) + res, err := client.Do(req) + if err != nil { + return nil, err + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code from Download %v", res.StatusCode) + } + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(res.Body); err != nil { + return nil, err + } + + v, err := ast.InterfaceToValue(buf.Bytes()) + if err != nil { + return nil, err + } + + return ast.NewTerm(v), nil + }, +) + +var GetMimetype = rego.Function1( + ®o.Function{ + Name: "ocis_get_mimetype", + Decl: types.NewFunction(types.Args(types.A), types.S), + Memoize: true, + Nondeterministic: true, + }, + func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) { + var body []byte + + if err := ast.As(a.Value, &body); err != nil { + return nil, err + } + + mimeInfo := mimetype.Detect(body).String() + detectedMimetype := strings.Split(mimeInfo, ";")[0] + v, err := ast.InterfaceToValue(detectedMimetype) + if err != nil { + return nil, err + } + + return ast.NewTerm(v), nil + }, +) diff --git a/services/policies/pkg/engine/opa_test.go b/services/policies/pkg/engine/opa_test.go new file mode 100644 index 000000000..0e0ff29e0 --- /dev/null +++ b/services/policies/pkg/engine/opa_test.go @@ -0,0 +1,46 @@ +package engine_test + +import ( + "context" + "encoding/base64" + "net/http" + "net/http/httptest" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/open-policy-agent/opa/rego" + "github.com/owncloud/ocis/v2/services/policies/pkg/engine" +) + +var _ = Describe("Opa", func() { + Describe("Custom OPA function", func() { + Describe("GetResource", func() { + It("loads reva resources", func() { + ts := []byte("Lorem Ipsum is simply dummy text of the printing and typesetting") + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(ts) + })) + defer srv.Close() + + r := rego.New(rego.Query(`ocis_get_resource("`+srv.URL+`")`), engine.GetResource) + rs, err := r.Eval(context.Background()) + Expect(err).ToNot(HaveOccurred()) + + data, err := base64.StdEncoding.DecodeString(rs[0].Expressions[0].String()) + Expect(err).ToNot(HaveOccurred()) + + Expect(data).To(Equal(ts)) + + }) + }) + + Describe("GetMimetype", func() { + It("is defined and returns a mimetype", func() { + r := rego.New(rego.Query(`ocis_get_mimetype("")`), engine.GetMimetype) + rs, err := r.Eval(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(rs[0].Expressions[0].String()).To(Equal("text/plain")) + }) + }) + }) +}) diff --git a/services/policies/pkg/service/event/service.go b/services/policies/pkg/service/event/service.go new file mode 100644 index 000000000..054a53979 --- /dev/null +++ b/services/policies/pkg/service/event/service.go @@ -0,0 +1,87 @@ +package eventSVC + +import ( + "context" + "github.com/cs3org/reva/v2/pkg/events" + "github.com/owncloud/ocis/v2/ocis-pkg/log" + "github.com/owncloud/ocis/v2/services/policies/pkg/engine" +) + +// Service defines the service handlers. +type Service struct { + query string + log log.Logger + stream events.Stream + engine engine.Engine +} + +// New returns a service implementation for Service. +func New(stream events.Stream, logger log.Logger, engine engine.Engine, query string) (Service, error) { + svc := Service{ + log: logger, + query: query, + engine: engine, + stream: stream, + } + + return svc, nil +} + +// Run to fulfil Runner interface +func (s Service) Run() error { + ch, err := events.Consume(s.stream, "policies", events.StartPostprocessingStep{}) + if err != nil { + return err + } + + for e := range ch { + switch ev := e.Event.(type) { + case events.StartPostprocessingStep: + if ev.StepToStart != "policies" { + continue + } + + outcome := events.PPOutcomeContinue + + if s.query != "" { + env := engine.Environment{ + Stage: engine.StagePP, + Resource: engine.Resource{ + Name: ev.Filename, + URL: ev.URL, + Size: ev.Filesize, + }, + } + + if ev.ExecutingUser != nil { + env.User = *ev.ExecutingUser + } + + if ev.ResourceID != nil { + env.Resource.ID = *ev.ResourceID + } + + result, err := s.engine.Evaluate(context.TODO(), s.query, env) + if err != nil { + s.log.Error().Err(err).Msg("unable evaluate policy") + } + + if !result { + outcome = events.PPOutcomeDelete + } + } + + if err := events.Publish(s.stream, events.PostprocessingStepFinished{ + Outcome: outcome, + UploadID: ev.UploadID, + ExecutingUser: ev.ExecutingUser, + Filename: ev.Filename, + FinishedStep: ev.StepToStart, + }); err != nil { + return err + } + } + } + + return nil +} diff --git a/services/policies/pkg/service/grpc/service.go b/services/policies/pkg/service/grpc/service.go new file mode 100644 index 000000000..5a53fe3d0 --- /dev/null +++ b/services/policies/pkg/service/grpc/service.go @@ -0,0 +1,35 @@ +package grpcSVC + +import ( + "context" + + "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0" + "github.com/owncloud/ocis/v2/services/policies/pkg/engine" +) + +// Service defines the service handlers. +type Service struct { + engine engine.Engine +} + +// New returns a service implementation for Service. +func New(engine engine.Engine) (Service, error) { + svc := Service{ + engine: engine, + } + + return svc, nil +} + +// Evaluate exposes the engine policy evaluation. +func (s Service) Evaluate(ctx context.Context, request *v0.EvaluateRequest, response *v0.EvaluateResponse) error { + env, err := engine.NewEnvironmentFromPB(request.Environment) + if err != nil { + return err + } + + result, err := s.engine.Evaluate(ctx, request.Query, env) + response.Result = result + + return err +} diff --git a/services/postprocessing/pkg/config/config.go b/services/postprocessing/pkg/config/config.go index b1fac6a2e..b36eb58fc 100644 --- a/services/postprocessing/pkg/config/config.go +++ b/services/postprocessing/pkg/config/config.go @@ -23,7 +23,7 @@ type Config struct { // Postprocessing defines the config options for the postprocessing service. type Postprocessing struct { Events Events `yaml:"events"` - Steps []string `yaml:"steps" env:"POSTPROCESSING_STEPS" desc:"A comma separated list of postprocessing steps, processed in order of their appearance. Currently supported values by the system are: 'virusscan' and 'delay'. Custom steps are allowed. See the documentation for instructions."` + Steps []string `yaml:"steps" env:"POSTPROCESSING_STEPS" desc:"A comma separated list of postprocessing steps, processed in order of their appearance. Currently supported values by the system are: 'virusscan', 'policies' and 'delay'. Custom steps are allowed. See the documentation for instructions."` Virusscan bool `yaml:"virusscan" env:"POSTPROCESSING_VIRUSSCAN" desc:"After uploading a file but before making it available for download, virus scanning the file can be enabled. Needs as prerequisite the antivirus service to be enabled and configured." deprecationVersion:"master" removalVersion:"master" deprecationInfo:"POSTPROCESSING_VIRUSSCAN is not longer necessary and is replaced by POSTPROCESSING_STEPS which also holds information about the order of steps" deprecationReplacement:"POSTPROCESSING_STEPS"` Delayprocessing time.Duration `yaml:"delayprocessing" env:"POSTPROCESSING_DELAY" desc:"After uploading a file but before making it available for download, a delay step can be added. Intended for developing purposes only. The duration can be set as number followed by a unit identifier like s, m or h. If a duration is set but the keyword 'delay' is not explicitely added to 'POSTPROCESSING_STEPS', the delay step will be processed as last step. In such a case, a log entry will be written on service startup to remind the admin about that situation."` } diff --git a/services/postprocessing/pkg/service/service.go b/services/postprocessing/pkg/service/service.go index 0c286508b..f8a8af0f0 100644 --- a/services/postprocessing/pkg/service/service.go +++ b/services/postprocessing/pkg/service/service.go @@ -23,6 +23,7 @@ func NewPostprocessingService(stream events.Stream, logger log.Logger, c config. events.StartPostprocessingStep{}, events.VirusscanFinished{}, events.UploadReady{}, + events.PostprocessingStepFinished{}, ) if err != nil { return nil, err diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go index 8c265a5a3..05a5b718e 100644 --- a/services/proxy/pkg/command/server.go +++ b/services/proxy/pkg/command/server.go @@ -199,7 +199,6 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) Logger: logger, RevaGatewayClient: revaClient, }) - authenticators = append(authenticators, middleware.SignedURLAuthenticator{ Logger: logger, PreSignedURLConfig: cfg.PreSignedURL, @@ -219,9 +218,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) cfg.OIDC.RewriteWellKnown, oidcHTTPClient, ), - router.Middleware(cfg.PolicySelector, cfg.Policies, logger), - middleware.Authentication( authenticators, middleware.CredentialsByUserAgent(cfg.AuthMiddleware.CredentialsByUserAgent), @@ -237,13 +234,12 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) middleware.UserCS3Claim(cfg.UserCS3Claim), middleware.AutoprovisionAccounts(cfg.AutoprovisionAccounts), ), - middleware.SelectorCookie( middleware.Logger(logger), middleware.UserProvider(userProvider), middleware.PolicySelectorConfig(*cfg.PolicySelector), ), - + middleware.Policies(logger, cfg.PoliciesMiddleware.Query), // finally, trigger home creation when a user logs in middleware.CreateHome( middleware.Logger(logger), diff --git a/services/proxy/pkg/config/config.go b/services/proxy/pkg/config/config.go index d7ac632dd..554caebcc 100644 --- a/services/proxy/pkg/config/config.go +++ b/services/proxy/pkg/config/config.go @@ -21,21 +21,22 @@ type Config struct { Reva *shared.Reva `yaml:"reva"` GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` - RoleQuotas map[string]uint64 `yaml:"role_quotas"` - Policies []Policy `yaml:"policies"` - OIDC OIDC `yaml:"oidc"` - TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` - PolicySelector *PolicySelector `yaml:"policy_selector"` - PreSignedURL PreSignedURL `yaml:"pre_signed_url"` - AccountBackend string `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the PROXY service should use. Currently only 'cs3' is possible here."` - UserOIDCClaim string `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that is used for resolving users with the account backend. The value of the claim must hold a per user unique, stable and non re-assignable identifier. The availability of claims depends on your Identity Provider. There are common claims available for most Identity providers like 'email' or 'preferred_user' but you can also add your own claim."` - UserCS3Claim string `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Supported values are 'username', 'mail' and 'userid'."` - MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."` - AutoprovisionAccounts bool `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provision users that do not yet exist in the users service on-demand upon first sign-in. To use this a write-enabled libregraph user backend needs to be setup an running."` - EnableBasicAuth bool `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic authentication' (username/password)."` - InsecureBackends bool `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."` - BackendHTTPSCACert string `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"Path/File for the root CA certificate used to validate the server’s TLS certificate for https enabled backend services."` - AuthMiddleware AuthMiddleware `yaml:"auth_middleware"` + RoleQuotas map[string]uint64 `yaml:"role_quotas"` + Policies []Policy `yaml:"policies"` + OIDC OIDC `yaml:"oidc"` + TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` + PolicySelector *PolicySelector `yaml:"policy_selector"` + PreSignedURL PreSignedURL `yaml:"pre_signed_url"` + AccountBackend string `yaml:"account_backend" env:"PROXY_ACCOUNT_BACKEND_TYPE" desc:"Account backend the PROXY service should use. Currently only 'cs3' is possible here."` + UserOIDCClaim string `yaml:"user_oidc_claim" env:"PROXY_USER_OIDC_CLAIM" desc:"The name of an OpenID Connect claim that is used for resolving users with the account backend. The value of the claim must hold a per user unique, stable and non re-assignable identifier. The availability of claims depends on your Identity Provider. There are common claims available for most Identity providers like 'email' or 'preferred_user' but you can also add your own claim."` + UserCS3Claim string `yaml:"user_cs3_claim" env:"PROXY_USER_CS3_CLAIM" desc:"The name of a CS3 user attribute (claim) that should be mapped to the 'user_oidc_claim'. Supported values are 'username', 'mail' and 'userid'."` + MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;PROXY_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."` + AutoprovisionAccounts bool `yaml:"auto_provision_accounts" env:"PROXY_AUTOPROVISION_ACCOUNTS" desc:"Set this to 'true' to automatically provision users that do not yet exist in the users service on-demand upon first sign-in. To use this a write-enabled libregraph user backend needs to be setup an running."` + EnableBasicAuth bool `yaml:"enable_basic_auth" env:"PROXY_ENABLE_BASIC_AUTH" desc:"Set this to true to enable 'basic authentication' (username/password)."` + InsecureBackends bool `yaml:"insecure_backends" env:"PROXY_INSECURE_BACKENDS" desc:"Disable TLS certificate validation for all HTTP backend connections."` + BackendHTTPSCACert string `yaml:"backend_https_cacert" env:"PROXY_HTTPS_CACERT" desc:"Path/File for the root CA certificate used to validate the server’s TLS certificate for https enabled backend services."` + AuthMiddleware AuthMiddleware `yaml:"auth_middleware"` + PoliciesMiddleware PoliciesMiddleware `yaml:"policies_middleware"` Context context.Context `yaml:"-" json:"-"` } @@ -84,6 +85,11 @@ type AuthMiddleware struct { CredentialsByUserAgent map[string]string `yaml:"credentials_by_user_agent"` } +// PoliciesMiddleware configures the proxy policies middleware. +type PoliciesMiddleware struct { + Query string `yaml:"query" env:"PROXY_POLICIES_QUERY" desc:"Defines the 'Complete Rules' variable defined in the rego rule set this step uses for its evaluation. Rules default to deny if the variable was not found."` +} + const ( AccessTokenVerificationNone = "none" AccessTokenVerificationJWT = "jwt" diff --git a/services/proxy/pkg/middleware/policies.go b/services/proxy/pkg/middleware/policies.go new file mode 100644 index 000000000..99097cf60 --- /dev/null +++ b/services/proxy/pkg/middleware/policies.go @@ -0,0 +1,62 @@ +package middleware + +import ( + "net/http" + + revactx "github.com/cs3org/reva/v2/pkg/ctx" + "github.com/owncloud/ocis/v2/ocis-pkg/log" + "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc" + pMessage "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/policies/v0" + pService "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0" +) + +// Policies verifies if a request is granted or not. +func Policies(logger log.Logger, qs string) func(next http.Handler) http.Handler { + pClient := pService.NewPoliciesProviderService("com.owncloud.api.policies", grpc.DefaultClient()) + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if qs == "" { + next.ServeHTTP(w, r) + return + } + + req := &pService.EvaluateRequest{ + Query: qs, + Environment: &pMessage.Environment{ + Request: &pMessage.Request{ + Method: r.Method, + Path: r.URL.Path, + }, + Stage: pMessage.Stage_STAGE_HTTP, + }, + } + + if user, ok := revactx.ContextGetUser(r.Context()); ok { + req.Environment.User = &pMessage.User{ + Id: &pMessage.User_ID{ + OpaqueId: user.GetId().GetOpaqueId(), + }, + Username: user.GetUsername(), + Mail: user.GetMail(), + DisplayName: user.GetDisplayName(), + Groups: user.GetGroups(), + } + } + + rsp, err := pClient.Evaluate(r.Context(), req) + if err != nil { + logger.Err(err).Msg("error evaluating request") + w.WriteHeader(http.StatusInternalServerError) + return + } + + if !rsp.Result { + w.WriteHeader(http.StatusForbidden) + return + } + + next.ServeHTTP(w, r) + }) + } +}