From 701da2314183ec15a200cf04b3cd80a029f67bbf Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Wed, 10 Nov 2021 13:54:49 +0545 Subject: [PATCH 01/15] test zip archive download --- .../features/apiArchiver/downloadById.feature | 24 ++++++++++++----- .../features/bootstrap/ArchiverContext.php | 27 ++++++++++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/tests/acceptance/features/apiArchiver/downloadById.feature b/tests/acceptance/features/apiArchiver/downloadById.feature index 75dba8189..0937e25ce 100644 --- a/tests/acceptance/features/apiArchiver/downloadById.feature +++ b/tests/acceptance/features/apiArchiver/downloadById.feature @@ -11,21 +11,33 @@ Feature: download multiple resources bundled into an archive Background: Given user "Alice" has been created with default attributes and without skeleton files - Scenario: download a single file + Scenario Outline: download a single file Given user "Alice" has uploaded file with content "some data" to "/textfile0.txt" - When user "Alice" downloads the archive of "/textfile0.txt" using the resource id + When user "Alice" downloads the archive of "/textfile0.txt" using the resource id and setting these headers + | header | value | + | User-Agent | | Then the HTTP status code should be "200" - And the downloaded archive should contain these files: + And the downloaded archive should contain these files: | name | content | | textfile0.txt | some data | + Examples: + | user-agent | archive-type | + | Linux | tar | + | Windows NT | zip | - Scenario: download a single folder + Scenario Outline: download a single folder Given user "Alice" has created folder "my_data" And user "Alice" has uploaded file with content "some data" to "/my_data/textfile0.txt" And user "Alice" has uploaded file with content "more data" to "/my_data/an_other_file.txt" - When user "Alice" downloads the archive of "/my_data" using the resource id + When user "Alice" downloads the archive of "/my_data" using the resource id and setting these headers + | header | value | + | User-Agent | | Then the HTTP status code should be "200" - And the downloaded archive should contain these files: + And the downloaded archive should contain these files: | name | content | | my_data/textfile0.txt | some data | | my_data/an_other_file.txt | more data | + Examples: + | user-agent | archive-type | + | Linux | tar | + | Windows NT | zip | diff --git a/tests/acceptance/features/bootstrap/ArchiverContext.php b/tests/acceptance/features/bootstrap/ArchiverContext.php index 4b737f302..f55540b62 100644 --- a/tests/acceptance/features/bootstrap/ArchiverContext.php +++ b/tests/acceptance/features/bootstrap/ArchiverContext.php @@ -63,16 +63,29 @@ class ArchiverContext implements Context { } /** - * @When user :user downloads the archive of :resourceId using the resource id + * @When user :user downloads the archive of :resourceId using the resource id and setting these headers * * @param string $user * @param string $resource + * @param TableNode $headersTable * * @return void * * @throws \GuzzleHttp\Exception\GuzzleException */ - public function userDownloadsTheArchiveOfUsingTheResourceId(string $user, string $resource): void { + public function userDownloadsTheArchiveOfUsingTheResourceId( + string $user, + string $resource, + TableNode $headersTable + ): void { + $this->featureContext->verifyTableNodeColumns( + $headersTable, + ['header', 'value'] + ); + $headers = []; + foreach ($headersTable as $row) { + $headers[$row['header']] = $row ['value']; + } $resourceId = $this->featureContext->getFileIdForPath($user, $resource); $user = $this->featureContext->getActualUsername($user); $this->featureContext->setResponse( @@ -80,25 +93,27 @@ class ArchiverContext implements Context { $this->featureContext->getBaseUrl() . '/archiver?id=' . $resourceId, '', $user, - $this->featureContext->getPasswordForUser($user) + $this->featureContext->getPasswordForUser($user), + $headers ) ); } /** - * @Then the downloaded archive should contain these files: + * @Then the downloaded :type archive should contain these files: * + * @param string $type * @param TableNode $expectedFiles * * @return void * * @throws Exception */ - public function theDownloadedArchiveShouldContainTheseFiles(TableNode $expectedFiles) { + public function theDownloadedArchiveShouldContainTheseFiles(string $type, TableNode $expectedFiles) { $this->featureContext->verifyTableNodeColumns($expectedFiles, ['name', 'content']); $tempFile = \tempnam(\sys_get_temp_dir(), 'OcAcceptanceTests_'); \unlink($tempFile); // we only need the name - $tempFile = $tempFile . '.tar'; // it needs the extension + $tempFile = $tempFile . '.' . $type; // it needs the extension \file_put_contents($tempFile, $this->featureContext->getResponse()->getBody()->getContents()); $archive = UnifiedArchive::open($tempFile); foreach ($expectedFiles->getHash() as $expectedFile) { From 0ec64fe99fec6a1ac7570a53f7297f7404d45b8a Mon Sep 17 00:00:00 2001 From: David Christofas Date: Wed, 10 Nov 2021 13:18:04 +0100 Subject: [PATCH 02/15] make insecure options configurable --- .drone.star | 5 +++++ .vscode/launch.json | 7 ++++++- changelog/unreleased/insecure-options.md | 14 ++++++++++++++ storage/pkg/command/frontend.go | 6 +++--- storage/pkg/command/storagehome.go | 2 +- storage/pkg/command/storagemetadata.go | 2 +- storage/pkg/config/config.go | 14 +++++++++++--- storage/pkg/flagset/frontend.go | 21 +++++++++++++++++++++ storage/pkg/flagset/storagehome.go | 7 +++++++ storage/pkg/flagset/storagemetadata.go | 7 +++++++ 10 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 changelog/unreleased/insecure-options.md diff --git a/.drone.star b/.drone.star index 11833cabd..db2982e53 100644 --- a/.drone.star +++ b/.drone.star @@ -1474,6 +1474,11 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): "IDP_IDENTIFIER_REGISTRATION_CONF": "/drone/src/tests/config/drone/identifier-registration.yml", "OCIS_LOG_LEVEL": "error", "SETTINGS_DATA_PATH": "/srv/app/tmp/ocis/settings", + "STORAGE_HOME_DATAPROVIDER_INSECURE": True, + "STORAGE_METADATA_DATAPROVIDER_INSECURE": True, + "STORAGE_FRONTEND_OCDAV_INSECURE": True, + "STORAGE_FRONTEND_ARCHIVER_INSECURE": True, + "STORAGE_FRONTEND_APPPROVIDER_INSECURE": True, } # Pass in "default" accounts_hash_difficulty to not set this environment variable. diff --git a/.vscode/launch.json b/.vscode/launch.json index 37d283a4b..2a231cc67 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,12 @@ "OCIS_LOG_LEVEL": "debug", "OCIS_LOG_PRETTY": "true", "OCIS_LOG_COLOR": "true", - "PROXY_ENABLE_BASIC_AUTH": "true" + "PROXY_ENABLE_BASIC_AUTH": "true", + "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", + "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", + "STORAGE_FRONTEND_OCDAV_INSECURE": "true", + "STORAGE_FRONTEND_ARCHIVER_INSECURE": "true", + "STORAGE_FRONTEND_APPPROVIDER_INSECURE": "true", } }, ] diff --git a/changelog/unreleased/insecure-options.md b/changelog/unreleased/insecure-options.md new file mode 100644 index 000000000..34f53f657 --- /dev/null +++ b/changelog/unreleased/insecure-options.md @@ -0,0 +1,14 @@ +Enhancement: Make insecure options configurable + +We had several hard-coded 'insecure' flags. These options are now configurable. In development environments using self signed certs (the default) you need to set these flags: + +``` +STORAGE_HOME_DATAPROVIDER_INSECURE=true +STORAGE_METADATA_DATAPROVIDER_INSECURE=true +STORAGE_FRONTEND_OCDAV_INSECURE=true +STORAGE_FRONTEND_ARCHIVER_INSECURE=true +STORAGE_FRONTEND_APPPROVIDER_INSECURE=true +``` + +https://github.com/owncloud/ocis/issues/2700 +https://github.com/owncloud/ocis/pull/2745 diff --git a/storage/pkg/command/frontend.go b/storage/pkg/command/frontend.go index 43fb59a6f..c9b2d9416 100644 --- a/storage/pkg/command/frontend.go +++ b/storage/pkg/command/frontend.go @@ -170,12 +170,12 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s "prefix": cfg.Reva.Frontend.AppProviderPrefix, "transfer_shared_secret": cfg.Reva.TransferSecret, "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.Frontend.AppProviderInsecure, }, "archiver": map[string]interface{}{ "prefix": cfg.Reva.Frontend.ArchiverPrefix, "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.Frontend.ArchiverInsecure, "max_num_files": cfg.Reva.Archiver.MaxNumFiles, "max_size": cfg.Reva.Archiver.MaxSize, }, @@ -190,7 +190,7 @@ func frontendConfigFromStruct(c *cli.Context, cfg *config.Config, filesCfg map[s "files_namespace": cfg.Reva.OCDav.DavFilesNamespace, "webdav_namespace": cfg.Reva.OCDav.WebdavNamespace, "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.Frontend.OCDavInsecure, "public_url": cfg.Reva.Frontend.PublicURL, }, "ocs": map[string]interface{}{ diff --git a/storage/pkg/command/storagehome.go b/storage/pkg/command/storagehome.go index 4df8524e9..fff984b13 100644 --- a/storage/pkg/command/storagehome.go +++ b/storage/pkg/command/storagehome.go @@ -128,7 +128,7 @@ func storageHomeConfigFromStruct(c *cli.Context, cfg *config.Config) map[string] "driver": cfg.Reva.StorageHome.Driver, "drivers": storagedrivers.HomeDrivers(cfg), "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.StorageHome.DataProvider.Insecure, "disable_tus": false, }, }, diff --git a/storage/pkg/command/storagemetadata.go b/storage/pkg/command/storagemetadata.go index c27b27a42..74af72911 100644 --- a/storage/pkg/command/storagemetadata.go +++ b/storage/pkg/command/storagemetadata.go @@ -150,7 +150,7 @@ func storageMetadataFromStruct(c *cli.Context, cfg *config.Config) map[string]in "driver": cfg.Reva.StorageMetadata.Driver, "drivers": storagedrivers.MetadataDrivers(cfg), "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.StorageMetadata.DataProvider.Insecure, "disable_tus": true, }, }, diff --git a/storage/pkg/config/config.go b/storage/pkg/config/config.go index a18c19ce3..4797b7736 100644 --- a/storage/pkg/config/config.go +++ b/storage/pkg/config/config.go @@ -144,10 +144,13 @@ type Groups struct { type FrontendPort struct { Port + AppProviderInsecure bool AppProviderPrefix string + ArchiverInsecure bool ArchiverPrefix string DatagatewayPrefix string Favorites bool + OCDavInsecure bool OCDavPrefix string OCSPrefix string OCSSharePrefix string @@ -175,6 +178,10 @@ type DataGatewayPort struct { PublicURL string } +type DataProvider struct { + Insecure bool +} + // StoragePort defines the available storage configuration. type StoragePort struct { Port @@ -186,9 +193,10 @@ type StoragePort struct { DataServerURL string // for HTTP ports with only one http service - HTTPPrefix string - TempFolder string - ReadOnly bool + HTTPPrefix string + TempFolder string + ReadOnly bool + DataProvider DataProvider } // PublicStorage configures a public storage provider diff --git a/storage/pkg/flagset/frontend.go b/storage/pkg/flagset/frontend.go index 4f5956aec..928798c8e 100644 --- a/storage/pkg/flagset/frontend.go +++ b/storage/pkg/flagset/frontend.go @@ -119,6 +119,13 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_FRONTEND_APPPROVIDER_PREFIX"}, Destination: &cfg.Reva.Frontend.AppProviderPrefix, }, + &cli.BoolFlag{ + Name: "approvider-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.AppProviderInsecure, false), + Usage: "approvider insecure", + EnvVars: []string{"STORAGE_FRONTEND_APPPROVIDER_INSECURE"}, + Destination: &cfg.Reva.Frontend.AppProviderInsecure, + }, &cli.StringFlag{ Name: "archiver-prefix", Value: flags.OverrideDefaultString(cfg.Reva.Frontend.ArchiverPrefix, "archiver"), @@ -126,6 +133,13 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_FRONTEND_ARCHIVER_PREFIX"}, Destination: &cfg.Reva.Frontend.ArchiverPrefix, }, + &cli.BoolFlag{ + Name: "archiver-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.ArchiverInsecure, false), + Usage: "archiver insecure", + EnvVars: []string{"STORAGE_FRONTEND_ARCHIVER_INSECURE"}, + Destination: &cfg.Reva.Frontend.ArchiverInsecure, + }, &cli.StringFlag{ Name: "datagateway-prefix", Value: flags.OverrideDefaultString(cfg.Reva.Frontend.DatagatewayPrefix, "data"), @@ -147,6 +161,13 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_FRONTEND_OCDAV_PREFIX"}, Destination: &cfg.Reva.Frontend.OCDavPrefix, }, + &cli.BoolFlag{ + Name: "ocdav-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.OCDavInsecure, false), + Usage: "owncloud webdav insecure", + EnvVars: []string{"STORAGE_FRONTEND_OCDAV_INSECURE"}, + Destination: &cfg.Reva.Frontend.OCDavInsecure, + }, &cli.StringFlag{ Name: "ocs-prefix", Value: flags.OverrideDefaultString(cfg.Reva.Frontend.OCSPrefix, "ocs"), diff --git a/storage/pkg/flagset/storagehome.go b/storage/pkg/flagset/storagehome.go index 6df9bf0c5..2ec1b71ac 100644 --- a/storage/pkg/flagset/storagehome.go +++ b/storage/pkg/flagset/storagehome.go @@ -130,6 +130,13 @@ func StorageHomeWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_HOME_TMP_FOLDER"}, Destination: &cfg.Reva.StorageHome.TempFolder, }, + &cli.BoolFlag{ + Name: "dataprovider-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.StorageHome.DataProvider.Insecure, false), + Usage: "dataprovider insecure", + EnvVars: []string{"STORAGE_HOME_DATAPROVIDER_INSECURE"}, + Destination: &cfg.Reva.StorageHome.DataProvider.Insecure, + }, // some drivers need to look up users at the gateway diff --git a/storage/pkg/flagset/storagemetadata.go b/storage/pkg/flagset/storagemetadata.go index 6af75d2e3..10b07441a 100644 --- a/storage/pkg/flagset/storagemetadata.go +++ b/storage/pkg/flagset/storagemetadata.go @@ -69,6 +69,13 @@ func StorageMetadata(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_METADATA_DRIVER"}, Destination: &cfg.Reva.StorageMetadata.Driver, }, + &cli.BoolFlag{ + Name: "dataprovider-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.StorageMetadata.DataProvider.Insecure, false), + Usage: "dataprovider insecure", + EnvVars: []string{"STORAGE_METADATA_DATAPROVIDER_INSECURE"}, + Destination: &cfg.Reva.StorageMetadata.DataProvider.Insecure, + }, // some drivers need to look up users at the gateway From 69cc11dbe6c59f574442598ff5c280e5f7c4f93c Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Wed, 10 Nov 2021 15:45:55 +0100 Subject: [PATCH 03/15] make more insecure options configurable and change insecure defaults from true to false --- .drone.star | 16 +++++++++---- .vscode/launch.json | 13 +++++++++- changelog/unreleased/insecure-options.md | 14 +++++++---- graph/pkg/cs3/client.go | 26 -------------------- graph/pkg/service/v0/graph.go | 4 ++-- idp/pkg/flagset/flagset.go | 1 + ocs/pkg/config/config.go | 7 +++++- ocs/pkg/flagset/flagset.go | 4 ++-- ocs/pkg/service/v0/service.go | 6 ++--- ocs/pkg/service/v0/users.go | 4 ++-- proxy/pkg/command/server.go | 2 +- proxy/pkg/config/config.go | 1 + proxy/pkg/cs3/client.go | 29 ++++++++++++++--------- proxy/pkg/flagset/flagset.go | 9 ++++++- storage/pkg/command/storageusers.go | 2 +- storage/pkg/flagset/authbearer.go | 2 +- storage/pkg/flagset/storageusers.go | 7 ++++++ thumbnails/pkg/config/config.go | 1 + thumbnails/pkg/flagset/flagset.go | 9 ++++++- thumbnails/pkg/server/grpc/server.go | 4 ++-- thumbnails/pkg/thumbnail/imgsource/cs3.go | 13 ++++++---- 21 files changed, 106 insertions(+), 68 deletions(-) delete mode 100644 graph/pkg/cs3/client.go diff --git a/.drone.star b/.drone.star index db2982e53..34ab845f4 100644 --- a/.drone.star +++ b/.drone.star @@ -1474,11 +1474,17 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): "IDP_IDENTIFIER_REGISTRATION_CONF": "/drone/src/tests/config/drone/identifier-registration.yml", "OCIS_LOG_LEVEL": "error", "SETTINGS_DATA_PATH": "/srv/app/tmp/ocis/settings", - "STORAGE_HOME_DATAPROVIDER_INSECURE": True, - "STORAGE_METADATA_DATAPROVIDER_INSECURE": True, - "STORAGE_FRONTEND_OCDAV_INSECURE": True, - "STORAGE_FRONTEND_ARCHIVER_INSECURE": True, - "STORAGE_FRONTEND_APPPROVIDER_INSECURE": True, + "PROXY_OIDC_INSECURE": "true", + "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", + "THUMBNAILS_CS3SOURCE_INSECURE": "true", + "REVA_GATEWAY_INSECURE": "true", + "STORAGE_OIDC_INSECURE": "true", + "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", + "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", + "STORAGE_USERS_DATAPROVIDER_INSECURE": "true", + "STORAGE_FRONTEND_OCDAV_INSECURE": "true", + "STORAGE_FRONTEND_ARCHIVER_INSECURE": "true", + "STORAGE_FRONTEND_APPPROVIDER_INSECURE": "true", } # Pass in "default" accounts_hash_difficulty to not set this environment variable. diff --git a/.vscode/launch.json b/.vscode/launch.json index 2a231cc67..d00d1d4f4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,14 +7,25 @@ "request": "launch", "mode": "debug", "program": "${workspaceFolder}/ocis/cmd/ocis", - "args": ["server"], + "args": [ + "server" + ], "env": { + // log settings for human developers "OCIS_LOG_LEVEL": "debug", "OCIS_LOG_PRETTY": "true", "OCIS_LOG_COLOR": "true", + // enable basic auth for dev setup so that we can use curl for testing "PROXY_ENABLE_BASIC_AUTH": "true", + // set insecure options because we don't have valid certificates in dev environments + "PROXY_OIDC_INSECURE": "true", + "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", + "THUMBNAILS_CS3SOURCE_INSECURE": "true", + "REVA_GATEWAY_INSECURE": "true", + "STORAGE_OIDC_INSECURE": "true", "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", + "STORAGE_USERS_DATAPROVIDER_INSECURE": "true", "STORAGE_FRONTEND_OCDAV_INSECURE": "true", "STORAGE_FRONTEND_ARCHIVER_INSECURE": "true", "STORAGE_FRONTEND_APPPROVIDER_INSECURE": "true", diff --git a/changelog/unreleased/insecure-options.md b/changelog/unreleased/insecure-options.md index 34f53f657..ec7e032e5 100644 --- a/changelog/unreleased/insecure-options.md +++ b/changelog/unreleased/insecure-options.md @@ -1,13 +1,19 @@ Enhancement: Make insecure options configurable -We had several hard-coded 'insecure' flags. These options are now configurable. In development environments using self signed certs (the default) you need to set these flags: +We had several hard-coded 'insecure' flags. These options are now configurable and default to false. Also we changed all other 'insecure' flags with a previous default of true to false. In development environments using self signed certs (the default) you need to set these flags: ``` +PROXY_OIDC_INSECURE=true +REVA_GATEWAY_INSECURE=true +STORAGE_FRONTEND_APPPROVIDER_INSECURE=true +STORAGE_FRONTEND_ARCHIVER_INSECURE=true +STORAGE_FRONTEND_OCDAV_INSECURE=true STORAGE_HOME_DATAPROVIDER_INSECURE=true STORAGE_METADATA_DATAPROVIDER_INSECURE=true -STORAGE_FRONTEND_OCDAV_INSECURE=true -STORAGE_FRONTEND_ARCHIVER_INSECURE=true -STORAGE_FRONTEND_APPPROVIDER_INSECURE=true +STORAGE_OIDC_INSECURE=true +STORAGE_USERS_DATAPROVIDER_INSECURE=true +THUMBNAILS_CS3SOURCE_INSECURE=true +THUMBNAILS_WEBDAVSOURCE_INSECURE=true ``` https://github.com/owncloud/ocis/issues/2700 diff --git a/graph/pkg/cs3/client.go b/graph/pkg/cs3/client.go deleted file mode 100644 index 9eed1a361..000000000 --- a/graph/pkg/cs3/client.go +++ /dev/null @@ -1,26 +0,0 @@ -package cs3 - -import ( - gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - - "google.golang.org/grpc" -) - -func newConn(endpoint string) (*grpc.ClientConn, error) { - conn, err := grpc.Dial(endpoint, grpc.WithInsecure()) - if err != nil { - return nil, err - } - - return conn, nil -} - -// GetGatewayServiceClient returns a new cs3 gateway client -func GetGatewayServiceClient(endpoint string) (gateway.GatewayAPIClient, error) { - conn, err := newConn(endpoint) - if err != nil { - return nil, err - } - - return gateway.NewGatewayAPIClient(conn), nil -} diff --git a/graph/pkg/service/v0/graph.go b/graph/pkg/service/v0/graph.go index 97005ce5a..fb0c1c505 100644 --- a/graph/pkg/service/v0/graph.go +++ b/graph/pkg/service/v0/graph.go @@ -4,9 +4,9 @@ import ( "net/http" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" + "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/go-chi/chi/v5" "github.com/owncloud/ocis/graph/pkg/config" - "github.com/owncloud/ocis/graph/pkg/cs3" "github.com/owncloud/ocis/ocis-pkg/log" ) @@ -24,7 +24,7 @@ func (g Graph) ServeHTTP(w http.ResponseWriter, r *http.Request) { // GetClient returns a gateway client to talk to reva func (g Graph) GetClient() (gateway.GatewayAPIClient, error) { - return cs3.GetGatewayServiceClient(g.config.Reva.Address) + return pool.GetGatewayServiceClient(g.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 } // The key type is unexported to prevent collisions with context keys defined in diff --git a/idp/pkg/flagset/flagset.go b/idp/pkg/flagset/flagset.go index fbb36d219..d9c9af81b 100644 --- a/idp/pkg/flagset/flagset.go +++ b/idp/pkg/flagset/flagset.go @@ -355,6 +355,7 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { &cli.BoolFlag{ Name: "insecure", Usage: "Disable TLS certificate and hostname validation", + Value: flags.OverrideDefaultBool(cfg.IDP.Insecure, false), EnvVars: []string{"IDP_INSECURE"}, Destination: &cfg.IDP.Insecure, }, diff --git a/ocs/pkg/config/config.go b/ocs/pkg/config/config.go index 6ee0377a4..5b3e9affc 100644 --- a/ocs/pkg/config/config.go +++ b/ocs/pkg/config/config.go @@ -49,6 +49,11 @@ type Tracing struct { Service string } +// Reva defines all available REVA configuration. +type Reva struct { + Address string +} + // TokenManager is the config for using the reva token manager type TokenManager struct { JWTSecret string @@ -71,7 +76,7 @@ type Config struct { TokenManager TokenManager Service Service AccountBackend string - RevaAddress string + Reva Reva StorageUsersDriver string MachineAuthAPIKey string IdentityManagement IdentityManagement diff --git a/ocs/pkg/flagset/flagset.go b/ocs/pkg/flagset/flagset.go index 378d07eaf..4eef288e2 100644 --- a/ocs/pkg/flagset/flagset.go +++ b/ocs/pkg/flagset/flagset.go @@ -184,10 +184,10 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.StringFlag{ Name: "reva-gateway-addr", - Value: flags.OverrideDefaultString(cfg.RevaAddress, "127.0.0.1:9142"), + Value: flags.OverrideDefaultString(cfg.Reva.Address, "127.0.0.1:9142"), Usage: "Address of REVA gateway endpoint", EnvVars: []string{"REVA_GATEWAY"}, - Destination: &cfg.RevaAddress, + Destination: &cfg.Reva.Address, }, &cli.StringFlag{ Name: "machine-auth-api-key", diff --git a/ocs/pkg/service/v0/service.go b/ocs/pkg/service/v0/service.go index a6875cc4b..1262ccdf1 100644 --- a/ocs/pkg/service/v0/service.go +++ b/ocs/pkg/service/v0/service.go @@ -4,6 +4,7 @@ import ( "net/http" "time" + "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/owncloud/ocis/ocis-pkg/service/grpc" "github.com/go-chi/chi/v5" @@ -19,7 +20,6 @@ import ( ocsm "github.com/owncloud/ocis/ocs/pkg/middleware" "github.com/owncloud/ocis/ocs/pkg/service/v0/data" "github.com/owncloud/ocis/ocs/pkg/service/v0/response" - "github.com/owncloud/ocis/proxy/pkg/cs3" "github.com/owncloud/ocis/proxy/pkg/user/backend" settings "github.com/owncloud/ocis/settings/pkg/proto/v0" ) @@ -161,9 +161,9 @@ func (o Ocs) getAccountService() accounts.AccountsService { } func (o Ocs) getCS3Backend() backend.UserBackend { - revaClient, err := cs3.GetGatewayServiceClient(o.config.RevaAddress) + revaClient, err := pool.GetGatewayServiceClient(o.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 if err != nil { - o.logger.Fatal().Msgf("could not get reva client at address %s", o.config.RevaAddress) + o.logger.Fatal().Msgf("could not get reva client at address %s", o.config.Reva.Address) } return backend.NewCS3UserBackend(nil, revaClient, o.config.MachineAuthAPIKey, o.logger) } diff --git a/ocs/pkg/service/v0/users.go b/ocs/pkg/service/v0/users.go index 78763f47d..5b039016c 100644 --- a/ocs/pkg/service/v0/users.go +++ b/ocs/pkg/service/v0/users.go @@ -375,7 +375,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) { return } - if o.config.RevaAddress != "" && o.config.StorageUsersDriver != "owncloud" { + if o.config.Reva.Address != "" && o.config.StorageUsersDriver != "owncloud" { t, err := o.mintTokenForUser(r.Context(), account) if err != nil { mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, errors.Wrap(err, "error minting token").Error()))) @@ -384,7 +384,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) { ctx := metadata.AppendToOutgoingContext(r.Context(), revactx.TokenHeader, t) - gwc, err := pool.GetGatewayServiceClient(o.config.RevaAddress) + gwc, err := pool.GetGatewayServiceClient(o.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 if err != nil { o.logger.Error().Err(err).Msg("error securing a connection to Reva gateway") } diff --git a/proxy/pkg/command/server.go b/proxy/pkg/command/server.go index 8b4341103..162ee2843 100644 --- a/proxy/pkg/command/server.go +++ b/proxy/pkg/command/server.go @@ -149,7 +149,7 @@ func Server(cfg *config.Config) *cli.Command { func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) alice.Chain { rolesClient := settings.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient) - revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address) + revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address, cfg.Reva.Insecure) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 var userProvider backend.UserBackend switch cfg.AccountBackend { case "accounts": diff --git a/proxy/pkg/config/config.go b/proxy/pkg/config/config.go index 9dd370118..7f839ef54 100644 --- a/proxy/pkg/config/config.go +++ b/proxy/pkg/config/config.go @@ -81,6 +81,7 @@ var ( // Reva defines all available REVA configuration. type Reva struct { Address string + Insecure bool Middleware Middleware } diff --git a/proxy/pkg/cs3/client.go b/proxy/pkg/cs3/client.go index 68f52d2d7..91a5c566a 100644 --- a/proxy/pkg/cs3/client.go +++ b/proxy/pkg/cs3/client.go @@ -7,17 +7,24 @@ import ( "google.golang.org/grpc" ) -func newConn(endpoint string) (*grpc.ClientConn, error) { - conn, err := grpc.Dial( - endpoint, - grpc.WithInsecure(), - grpc.WithUnaryInterceptor( - otelgrpc.UnaryClientInterceptor( - otelgrpc.WithTracerProvider( - proxytracing.TraceProvider, - ), +func newConn(endpoint string, insecure bool) (*grpc.ClientConn, error) { + opts := []grpc.DialOption{} + + opts = append(opts, grpc.WithUnaryInterceptor( + otelgrpc.UnaryClientInterceptor( + otelgrpc.WithTracerProvider( + proxytracing.TraceProvider, ), ), + )) + + if insecure { + opts = append(opts, grpc.WithInsecure()) + } + + conn, err := grpc.Dial( + endpoint, + opts..., ) if err != nil { return nil, err @@ -27,8 +34,8 @@ func newConn(endpoint string) (*grpc.ClientConn, error) { } // GetGatewayServiceClient returns a new cs3 gateway client -func GetGatewayServiceClient(endpoint string) (gateway.GatewayAPIClient, error) { - conn, err := newConn(endpoint) +func GetGatewayServiceClient(endpoint string, insecure bool) (gateway.GatewayAPIClient, error) { + conn, err := newConn(endpoint, insecure) if err != nil { return nil, err } diff --git a/proxy/pkg/flagset/flagset.go b/proxy/pkg/flagset/flagset.go index 2f1d6b885..c16699f24 100644 --- a/proxy/pkg/flagset/flagset.go +++ b/proxy/pkg/flagset/flagset.go @@ -189,6 +189,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"REVA_GATEWAY"}, Destination: &cfg.Reva.Address, }, + &cli.BoolFlag{ + Name: "reva-gateway-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.Insecure, false), + Usage: "allow insecure communication to REVA gateway endpoint", + EnvVars: []string{"REVA_GATEWAY_INSECURE"}, + Destination: &cfg.Reva.Insecure, + }, &cli.BoolFlag{ Name: "insecure", Value: flags.OverrideDefaultBool(cfg.InsecureBackends, false), @@ -208,7 +215,7 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.BoolFlag{ Name: "oidc-insecure", - Value: flags.OverrideDefaultBool(cfg.OIDC.Insecure, true), + Value: flags.OverrideDefaultBool(cfg.OIDC.Insecure, false), Usage: "OIDC allow insecure communication", EnvVars: []string{"PROXY_OIDC_INSECURE"}, Destination: &cfg.OIDC.Insecure, diff --git a/storage/pkg/command/storageusers.go b/storage/pkg/command/storageusers.go index 6f01defad..99ae03348 100644 --- a/storage/pkg/command/storageusers.go +++ b/storage/pkg/command/storageusers.go @@ -128,7 +128,7 @@ func storageUsersConfigFromStruct(c *cli.Context, cfg *config.Config) map[string "driver": cfg.Reva.StorageUsers.Driver, "drivers": storagedrivers.UserDrivers(cfg), "timeout": 86400, - "insecure": true, + "insecure": cfg.Reva.StorageUsers.DataProvider.Insecure, "disable_tus": false, }, }, diff --git a/storage/pkg/flagset/authbearer.go b/storage/pkg/flagset/authbearer.go index 73bfeb91e..90b14b7af 100644 --- a/storage/pkg/flagset/authbearer.go +++ b/storage/pkg/flagset/authbearer.go @@ -30,7 +30,7 @@ func AuthBearerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.BoolFlag{ Name: "oidc-insecure", - Value: flags.OverrideDefaultBool(cfg.Reva.OIDC.Insecure, true), + Value: flags.OverrideDefaultBool(cfg.Reva.OIDC.Insecure, false), Usage: "OIDC allow insecure communication", EnvVars: []string{"STORAGE_OIDC_INSECURE"}, Destination: &cfg.Reva.OIDC.Insecure, diff --git a/storage/pkg/flagset/storageusers.go b/storage/pkg/flagset/storageusers.go index b801d2dd8..9c6e7d1ed 100644 --- a/storage/pkg/flagset/storageusers.go +++ b/storage/pkg/flagset/storageusers.go @@ -78,6 +78,13 @@ func StorageUsersWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"STORAGE_USERS_DRIVER"}, Destination: &cfg.Reva.StorageUsers.Driver, }, + &cli.BoolFlag{ + Name: "dataprovider-insecure", + Value: flags.OverrideDefaultBool(cfg.Reva.StorageUsers.DataProvider.Insecure, false), + Usage: "dataprovider insecure", + EnvVars: []string{"STORAGE_USERS_DATAPROVIDER_INSECURE"}, + Destination: &cfg.Reva.StorageUsers.DataProvider.Insecure, + }, &cli.BoolFlag{ Name: "read-only", Value: flags.OverrideDefaultBool(cfg.Reva.StorageUsers.ReadOnly, false), diff --git a/thumbnails/pkg/config/config.go b/thumbnails/pkg/config/config.go index 7f8a97a81..4a19e13f4 100644 --- a/thumbnails/pkg/config/config.go +++ b/thumbnails/pkg/config/config.go @@ -63,6 +63,7 @@ type Thumbnail struct { Resolutions []string FileSystemStorage FileSystemStorage WebdavAllowInsecure bool + CS3AllowInsecure bool RevaGateway string WebdavNamespace string } diff --git a/thumbnails/pkg/flagset/flagset.go b/thumbnails/pkg/flagset/flagset.go index 6a877400e..c9e0edc0d 100644 --- a/thumbnails/pkg/flagset/flagset.go +++ b/thumbnails/pkg/flagset/flagset.go @@ -154,11 +154,18 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { }, &cli.BoolFlag{ Name: "webdavsource-insecure", - Value: flags.OverrideDefaultBool(cfg.Thumbnail.WebdavAllowInsecure, true), + Value: flags.OverrideDefaultBool(cfg.Thumbnail.WebdavAllowInsecure, false), Usage: "Whether to skip certificate checks", EnvVars: []string{"THUMBNAILS_WEBDAVSOURCE_INSECURE"}, Destination: &cfg.Thumbnail.WebdavAllowInsecure, }, + &cli.BoolFlag{ + Name: "cs3source-insecure", + Value: flags.OverrideDefaultBool(cfg.Thumbnail.CS3AllowInsecure, false), + Usage: "Whether to skip certificate checks", + EnvVars: []string{"THUMBNAILS_CS3SOURCE_INSECURE"}, + Destination: &cfg.Thumbnail.CS3AllowInsecure, + }, &cli.StringSliceFlag{ Name: "thumbnail-resolution", Value: cli.NewStringSlice("16x16", "32x32", "64x64", "128x128", "1920x1080", "3840x2160", "7680x4320"), diff --git a/thumbnails/pkg/server/grpc/server.go b/thumbnails/pkg/server/grpc/server.go index 866868d12..ccc99cbae 100644 --- a/thumbnails/pkg/server/grpc/server.go +++ b/thumbnails/pkg/server/grpc/server.go @@ -25,7 +25,7 @@ func NewService(opts ...Option) grpc.Service { grpc.Version(options.Config.Server.Version), ) tconf := options.Config.Thumbnail - gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway) + gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 if err != nil { options.Logger.Error().Err(err).Msg("could not get gateway client") return grpc.Service{} @@ -42,7 +42,7 @@ func NewService(opts ...Option) grpc.Service { options.Logger, ), ), - svc.CS3Source(imgsource.NewCS3Source(gc)), + svc.CS3Source(imgsource.NewCS3Source(tconf, gc)), svc.CS3Client(gc), ) thumbnail = svc.NewInstrument(thumbnail, options.Metrics) diff --git a/thumbnails/pkg/thumbnail/imgsource/cs3.go b/thumbnails/pkg/thumbnail/imgsource/cs3.go index 68cf63750..072713978 100644 --- a/thumbnails/pkg/thumbnail/imgsource/cs3.go +++ b/thumbnails/pkg/thumbnail/imgsource/cs3.go @@ -12,6 +12,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" revactx "github.com/cs3org/reva/pkg/ctx" "github.com/cs3org/reva/pkg/rhttp" + "github.com/owncloud/ocis/thumbnails/pkg/config" "github.com/pkg/errors" "google.golang.org/grpc/metadata" ) @@ -23,12 +24,14 @@ const ( ) type CS3 struct { - client gateway.GatewayAPIClient + client gateway.GatewayAPIClient + insecure bool } -func NewCS3Source(c gateway.GatewayAPIClient) CS3 { +func NewCS3Source(cfg config.Thumbnail, c gateway.GatewayAPIClient) CS3 { return CS3{ - client: c, + client: c, + insecure: cfg.CS3AllowInsecure, } } @@ -67,7 +70,9 @@ func (s CS3) Get(ctx context.Context, path string) (io.ReadCloser, error) { httpReq.Header.Set(revactx.TokenHeader, auth) httpReq.Header.Set(TokenTransportHeader, tk) - http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint:gosec + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{ + InsecureSkipVerify: s.insecure, //nolint:gosec + } client := &http.Client{} resp, err := client.Do(httpReq) // nolint:bodyclose From e35d4fd0ac99d43a029eae09365bc0291b4ac1eb Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Wed, 10 Nov 2021 16:12:29 +0100 Subject: [PATCH 04/15] remove GRPC insecure config options, since it always needs to be set to insecure --- .drone.star | 1 - .vscode/launch.json | 1 - changelog/unreleased/insecure-options.md | 1 - graph/pkg/service/v0/graph.go | 2 +- ocs/pkg/service/v0/service.go | 2 +- ocs/pkg/service/v0/users.go | 2 +- proxy/pkg/command/server.go | 2 +- proxy/pkg/config/config.go | 1 - proxy/pkg/cs3/client.go | 29 +++++++++--------------- proxy/pkg/flagset/flagset.go | 7 ------ thumbnails/pkg/server/grpc/server.go | 2 +- 11 files changed, 16 insertions(+), 34 deletions(-) diff --git a/.drone.star b/.drone.star index 34ab845f4..40721e154 100644 --- a/.drone.star +++ b/.drone.star @@ -1477,7 +1477,6 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): "PROXY_OIDC_INSECURE": "true", "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", "THUMBNAILS_CS3SOURCE_INSECURE": "true", - "REVA_GATEWAY_INSECURE": "true", "STORAGE_OIDC_INSECURE": "true", "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", diff --git a/.vscode/launch.json b/.vscode/launch.json index d00d1d4f4..06ddad706 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,7 +21,6 @@ "PROXY_OIDC_INSECURE": "true", "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", "THUMBNAILS_CS3SOURCE_INSECURE": "true", - "REVA_GATEWAY_INSECURE": "true", "STORAGE_OIDC_INSECURE": "true", "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", diff --git a/changelog/unreleased/insecure-options.md b/changelog/unreleased/insecure-options.md index ec7e032e5..5dde184e6 100644 --- a/changelog/unreleased/insecure-options.md +++ b/changelog/unreleased/insecure-options.md @@ -4,7 +4,6 @@ We had several hard-coded 'insecure' flags. These options are now configurable a ``` PROXY_OIDC_INSECURE=true -REVA_GATEWAY_INSECURE=true STORAGE_FRONTEND_APPPROVIDER_INSECURE=true STORAGE_FRONTEND_ARCHIVER_INSECURE=true STORAGE_FRONTEND_OCDAV_INSECURE=true diff --git a/graph/pkg/service/v0/graph.go b/graph/pkg/service/v0/graph.go index fb0c1c505..51f5cc604 100644 --- a/graph/pkg/service/v0/graph.go +++ b/graph/pkg/service/v0/graph.go @@ -24,7 +24,7 @@ func (g Graph) ServeHTTP(w http.ResponseWriter, r *http.Request) { // GetClient returns a gateway client to talk to reva func (g Graph) GetClient() (gateway.GatewayAPIClient, error) { - return pool.GetGatewayServiceClient(g.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 + return pool.GetGatewayServiceClient(g.config.Reva.Address) } // The key type is unexported to prevent collisions with context keys defined in diff --git a/ocs/pkg/service/v0/service.go b/ocs/pkg/service/v0/service.go index 1262ccdf1..146561f15 100644 --- a/ocs/pkg/service/v0/service.go +++ b/ocs/pkg/service/v0/service.go @@ -161,7 +161,7 @@ func (o Ocs) getAccountService() accounts.AccountsService { } func (o Ocs) getCS3Backend() backend.UserBackend { - revaClient, err := pool.GetGatewayServiceClient(o.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 + revaClient, err := pool.GetGatewayServiceClient(o.config.Reva.Address) if err != nil { o.logger.Fatal().Msgf("could not get reva client at address %s", o.config.Reva.Address) } diff --git a/ocs/pkg/service/v0/users.go b/ocs/pkg/service/v0/users.go index 5b039016c..c9108a156 100644 --- a/ocs/pkg/service/v0/users.go +++ b/ocs/pkg/service/v0/users.go @@ -384,7 +384,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) { ctx := metadata.AppendToOutgoingContext(r.Context(), revactx.TokenHeader, t) - gwc, err := pool.GetGatewayServiceClient(o.config.Reva.Address) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 + gwc, err := pool.GetGatewayServiceClient(o.config.Reva.Address) if err != nil { o.logger.Error().Err(err).Msg("error securing a connection to Reva gateway") } diff --git a/proxy/pkg/command/server.go b/proxy/pkg/command/server.go index 162ee2843..8b4341103 100644 --- a/proxy/pkg/command/server.go +++ b/proxy/pkg/command/server.go @@ -149,7 +149,7 @@ func Server(cfg *config.Config) *cli.Command { func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) alice.Chain { rolesClient := settings.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient) - revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address, cfg.Reva.Insecure) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 + revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address) var userProvider backend.UserBackend switch cfg.AccountBackend { case "accounts": diff --git a/proxy/pkg/config/config.go b/proxy/pkg/config/config.go index 7f839ef54..9dd370118 100644 --- a/proxy/pkg/config/config.go +++ b/proxy/pkg/config/config.go @@ -81,7 +81,6 @@ var ( // Reva defines all available REVA configuration. type Reva struct { Address string - Insecure bool Middleware Middleware } diff --git a/proxy/pkg/cs3/client.go b/proxy/pkg/cs3/client.go index 91a5c566a..68f52d2d7 100644 --- a/proxy/pkg/cs3/client.go +++ b/proxy/pkg/cs3/client.go @@ -7,24 +7,17 @@ import ( "google.golang.org/grpc" ) -func newConn(endpoint string, insecure bool) (*grpc.ClientConn, error) { - opts := []grpc.DialOption{} - - opts = append(opts, grpc.WithUnaryInterceptor( - otelgrpc.UnaryClientInterceptor( - otelgrpc.WithTracerProvider( - proxytracing.TraceProvider, - ), - ), - )) - - if insecure { - opts = append(opts, grpc.WithInsecure()) - } - +func newConn(endpoint string) (*grpc.ClientConn, error) { conn, err := grpc.Dial( endpoint, - opts..., + grpc.WithInsecure(), + grpc.WithUnaryInterceptor( + otelgrpc.UnaryClientInterceptor( + otelgrpc.WithTracerProvider( + proxytracing.TraceProvider, + ), + ), + ), ) if err != nil { return nil, err @@ -34,8 +27,8 @@ func newConn(endpoint string, insecure bool) (*grpc.ClientConn, error) { } // GetGatewayServiceClient returns a new cs3 gateway client -func GetGatewayServiceClient(endpoint string, insecure bool) (gateway.GatewayAPIClient, error) { - conn, err := newConn(endpoint, insecure) +func GetGatewayServiceClient(endpoint string) (gateway.GatewayAPIClient, error) { + conn, err := newConn(endpoint) if err != nil { return nil, err } diff --git a/proxy/pkg/flagset/flagset.go b/proxy/pkg/flagset/flagset.go index c16699f24..0d4b82992 100644 --- a/proxy/pkg/flagset/flagset.go +++ b/proxy/pkg/flagset/flagset.go @@ -189,13 +189,6 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"REVA_GATEWAY"}, Destination: &cfg.Reva.Address, }, - &cli.BoolFlag{ - Name: "reva-gateway-insecure", - Value: flags.OverrideDefaultBool(cfg.Reva.Insecure, false), - Usage: "allow insecure communication to REVA gateway endpoint", - EnvVars: []string{"REVA_GATEWAY_INSECURE"}, - Destination: &cfg.Reva.Insecure, - }, &cli.BoolFlag{ Name: "insecure", Value: flags.OverrideDefaultBool(cfg.InsecureBackends, false), diff --git a/thumbnails/pkg/server/grpc/server.go b/thumbnails/pkg/server/grpc/server.go index ccc99cbae..0c905c06e 100644 --- a/thumbnails/pkg/server/grpc/server.go +++ b/thumbnails/pkg/server/grpc/server.go @@ -25,7 +25,7 @@ func NewService(opts ...Option) grpc.Service { grpc.Version(options.Config.Server.Version), ) tconf := options.Config.Thumbnail - gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway) //TODO: insecure defaults to true, https://github.com/cs3org/reva/issues/2216 + gc, err := pool.GetGatewayServiceClient(tconf.RevaGateway) if err != nil { options.Logger.Error().Err(err).Msg("could not get gateway client") return grpc.Service{} From a6b2ea98956c2dff79184cb60f6406d1abeae432 Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Wed, 10 Nov 2021 16:23:37 +0100 Subject: [PATCH 05/15] set insecure options on deployment examples --- .../examples/cs3_users_ocis/docker-compose.yml | 12 +++++++++++- .../examples/oc10_ocis_parallel/docker-compose.yml | 12 +++++++++++- deployments/examples/ocis_hello/docker-compose.yml | 12 +++++++++++- .../examples/ocis_keycloak/docker-compose.yml | 12 +++++++++++- deployments/examples/ocis_s3/docker-compose.yml | 12 +++++++++++- deployments/examples/ocis_traefik/docker-compose.yml | 12 +++++++++++- deployments/examples/ocis_wopi/docker-compose.yml | 12 +++++++++++- 7 files changed, 77 insertions(+), 7 deletions(-) diff --git a/deployments/examples/cs3_users_ocis/docker-compose.yml b/deployments/examples/cs3_users_ocis/docker-compose.yml index 501e4af7f..1ff0a61ad 100644 --- a/deployments/examples/cs3_users_ocis/docker-compose.yml +++ b/deployments/examples/cs3_users_ocis/docker-compose.yml @@ -81,12 +81,22 @@ services: OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_DOMAIN: ${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS # change default secrets OCIS_JWT_SECRET: ${OCIS_JWT_SECRET:-Pive-Fumkiu4} STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/web-config.dist.json:/config/web-config.dist.json diff --git a/deployments/examples/oc10_ocis_parallel/docker-compose.yml b/deployments/examples/oc10_ocis_parallel/docker-compose.yml index cd02bd92b..66c6a4ce6 100644 --- a/deployments/examples/oc10_ocis_parallel/docker-compose.yml +++ b/deployments/examples/oc10_ocis_parallel/docker-compose.yml @@ -110,13 +110,23 @@ services: OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose PROXY_LOG_LEVEL: ${PROXY_LOG_LEVEL:-error} OCIS_URL: https://${CLOUD_DOMAIN:-cloud.owncloud.test} - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS PROXY_CONFIG_FILE: "/var/tmp/ocis/.config/proxy-config.json" # change default secrets OCIS_JWT_SECRET: ${OCIS_JWT_SECRET:-Pive-Fumkiu4} STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/proxy-config.dist.json:/config/proxy-config.dist.json diff --git a/deployments/examples/ocis_hello/docker-compose.yml b/deployments/examples/ocis_hello/docker-compose.yml index bde3af9d8..be4b88a3b 100644 --- a/deployments/examples/ocis_hello/docker-compose.yml +++ b/deployments/examples/ocis_hello/docker-compose.yml @@ -53,7 +53,6 @@ services: OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_DOMAIN: ${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS # change default secrets IDP_LDAP_BIND_PASSWORD: ${IDP_LDAP_BIND_PASSWORD:-idp} @@ -67,6 +66,17 @@ services: PROXY_CONFIG_FILE: "/var/tmp/ocis/.config/proxy-config.json" # make settings service available to oCIS Hello SETTINGS_GRPC_ADDR: 0.0.0.0:9191 + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/web-config.dist.json:/config/web-config.dist.json diff --git a/deployments/examples/ocis_keycloak/docker-compose.yml b/deployments/examples/ocis_keycloak/docker-compose.yml index 00301fa35..ae1fdb267 100644 --- a/deployments/examples/ocis_keycloak/docker-compose.yml +++ b/deployments/examples/ocis_keycloak/docker-compose.yml @@ -62,7 +62,6 @@ services: # general config OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS ACCOUNTS_DEMO_USERS_AND_GROUPS: false # don't generate demo users # change default secrets @@ -71,6 +70,17 @@ services: OCIS_JWT_SECRET: ${OCIS_JWT_SECRET:-Pive-Fumkiu4} STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_s3/docker-compose.yml b/deployments/examples/ocis_s3/docker-compose.yml index 51b3a7c55..0effba9f3 100644 --- a/deployments/examples/ocis_s3/docker-compose.yml +++ b/deployments/examples/ocis_s3/docker-compose.yml @@ -52,7 +52,6 @@ services: environment: OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS # change default secrets IDP_LDAP_BIND_PASSWORD: ${IDP_LDAP_BIND_PASSWORD:-idp} @@ -70,6 +69,17 @@ services: STORAGE_USERS_DRIVER_S3NG_ACCESS_KEY: ${MINIO_ACCESS_KEY:-ocis} STORAGE_USERS_DRIVER_S3NG_SECRET_KEY: ${MINIO_SECRET_KEY:-ocis-secret-key} STORAGE_USERS_DRIVER_S3NG_BUCKET: ${MINIO_BUCKET:-ocis-bucket} + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_traefik/docker-compose.yml b/deployments/examples/ocis_traefik/docker-compose.yml index 029f718b2..7982533ba 100644 --- a/deployments/examples/ocis_traefik/docker-compose.yml +++ b/deployments/examples/ocis_traefik/docker-compose.yml @@ -52,7 +52,6 @@ services: environment: OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS # change default secrets IDP_LDAP_BIND_PASSWORD: ${IDP_LDAP_BIND_PASSWORD:-idp} @@ -60,6 +59,17 @@ services: OCIS_JWT_SECRET: ${OCIS_JWT_SECRET:-Pive-Fumkiu4} STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_wopi/docker-compose.yml b/deployments/examples/ocis_wopi/docker-compose.yml index 473f9db59..42bd8354e 100644 --- a/deployments/examples/ocis_wopi/docker-compose.yml +++ b/deployments/examples/ocis_wopi/docker-compose.yml @@ -58,7 +58,6 @@ services: OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_DOMAIN: ${OCIS_DOMAIN:-ocis.owncloud.test} OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-error} # make oCIS less verbose - PROXY_OIDC_INSECURE: "${INSECURE:-false}" # needed if Traefik is using self generated certificates PROXY_TLS: "false" # do not use SSL between Traefik and oCIS # change default secrets IDP_LDAP_BIND_PASSWORD: ${IDP_LDAP_BIND_PASSWORD:-idp} @@ -69,6 +68,17 @@ services: # app registry STORAGE_GATEWAY_GRPC_ADDR: 0.0.0.0:9142 # make the REVA gateway accessible to the app drivers STORAGE_APP_REGISTRY_MIMETYPES_JSON: /var/tmp/ocis/app-config/mimetypes.json + # INSECURE: needed if oCIS / Traefik is using self generated certificates + PROXY_OIDC_INSECURE: "${INSECURE:-false}" + THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" + THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" + STORAGE_OIDC_INSECURE: "${INSECURE:-false}" + STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" + STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/mimetypes.json:/var/tmp/ocis/app-config/mimetypes.json From 6590565a2fe5dc2649e3aa26de8af371ebaf24f5 Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Wed, 10 Nov 2021 16:55:12 +0100 Subject: [PATCH 06/15] introduce OCIS_INSECURE option --- .drone.star | 11 +---------- .vscode/launch.json | 11 +---------- changelog/unreleased/insecure-options.md | 8 +++++++- .../examples/cs3_users_ocis/docker-compose.yml | 11 +---------- .../examples/oc10_ocis_parallel/docker-compose.yml | 11 +---------- deployments/examples/ocis_hello/docker-compose.yml | 11 +---------- deployments/examples/ocis_keycloak/docker-compose.yml | 11 +---------- deployments/examples/ocis_s3/docker-compose.yml | 11 +---------- deployments/examples/ocis_traefik/docker-compose.yml | 11 +---------- deployments/examples/ocis_wopi/docker-compose.yml | 11 +---------- docs/ocis/deployment/basic-remote-setup.md | 6 +++++- docs/ocis/deployment/systemd.md | 3 ++- proxy/pkg/flagset/flagset.go | 2 +- storage/pkg/flagset/authbearer.go | 2 +- storage/pkg/flagset/frontend.go | 6 +++--- storage/pkg/flagset/storagehome.go | 2 +- storage/pkg/flagset/storagemetadata.go | 2 +- storage/pkg/flagset/storageusers.go | 2 +- tests/acceptance/docker/src/ocis-base.yml | 1 + thumbnails/pkg/flagset/flagset.go | 4 ++-- 20 files changed, 34 insertions(+), 103 deletions(-) diff --git a/.drone.star b/.drone.star index 40721e154..1c8873e94 100644 --- a/.drone.star +++ b/.drone.star @@ -1474,16 +1474,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = []): "IDP_IDENTIFIER_REGISTRATION_CONF": "/drone/src/tests/config/drone/identifier-registration.yml", "OCIS_LOG_LEVEL": "error", "SETTINGS_DATA_PATH": "/srv/app/tmp/ocis/settings", - "PROXY_OIDC_INSECURE": "true", - "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", - "THUMBNAILS_CS3SOURCE_INSECURE": "true", - "STORAGE_OIDC_INSECURE": "true", - "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", - "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", - "STORAGE_USERS_DATAPROVIDER_INSECURE": "true", - "STORAGE_FRONTEND_OCDAV_INSECURE": "true", - "STORAGE_FRONTEND_ARCHIVER_INSECURE": "true", - "STORAGE_FRONTEND_APPPROVIDER_INSECURE": "true", + "OCIS_INSECURE": "true", } # Pass in "default" accounts_hash_difficulty to not set this environment variable. diff --git a/.vscode/launch.json b/.vscode/launch.json index 06ddad706..011c22d18 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,16 +18,7 @@ // enable basic auth for dev setup so that we can use curl for testing "PROXY_ENABLE_BASIC_AUTH": "true", // set insecure options because we don't have valid certificates in dev environments - "PROXY_OIDC_INSECURE": "true", - "THUMBNAILS_WEBDAVSOURCE_INSECURE": "true", - "THUMBNAILS_CS3SOURCE_INSECURE": "true", - "STORAGE_OIDC_INSECURE": "true", - "STORAGE_HOME_DATAPROVIDER_INSECURE": "true", - "STORAGE_METADATA_DATAPROVIDER_INSECURE": "true", - "STORAGE_USERS_DATAPROVIDER_INSECURE": "true", - "STORAGE_FRONTEND_OCDAV_INSECURE": "true", - "STORAGE_FRONTEND_ARCHIVER_INSECURE": "true", - "STORAGE_FRONTEND_APPPROVIDER_INSECURE": "true", + "OCIS_INSECURE": "true", } }, ] diff --git a/changelog/unreleased/insecure-options.md b/changelog/unreleased/insecure-options.md index 5dde184e6..3d66ab32f 100644 --- a/changelog/unreleased/insecure-options.md +++ b/changelog/unreleased/insecure-options.md @@ -1,4 +1,4 @@ -Enhancement: Make insecure options configurable +Change: Make insecure options configurable We had several hard-coded 'insecure' flags. These options are now configurable and default to false. Also we changed all other 'insecure' flags with a previous default of true to false. In development environments using self signed certs (the default) you need to set these flags: @@ -15,5 +15,11 @@ THUMBNAILS_CS3SOURCE_INSECURE=true THUMBNAILS_WEBDAVSOURCE_INSECURE=true ``` +As an alternative you also can set a single flag, which configures all options together: + +``` +OCIS_INSECURE=true +``` + https://github.com/owncloud/ocis/issues/2700 https://github.com/owncloud/ocis/pull/2745 diff --git a/deployments/examples/cs3_users_ocis/docker-compose.yml b/deployments/examples/cs3_users_ocis/docker-compose.yml index 1ff0a61ad..e0a4dcc1e 100644 --- a/deployments/examples/cs3_users_ocis/docker-compose.yml +++ b/deployments/examples/cs3_users_ocis/docker-compose.yml @@ -87,16 +87,7 @@ services: STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/web-config.dist.json:/config/web-config.dist.json diff --git a/deployments/examples/oc10_ocis_parallel/docker-compose.yml b/deployments/examples/oc10_ocis_parallel/docker-compose.yml index 66c6a4ce6..86b448a4f 100644 --- a/deployments/examples/oc10_ocis_parallel/docker-compose.yml +++ b/deployments/examples/oc10_ocis_parallel/docker-compose.yml @@ -117,16 +117,7 @@ services: STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/proxy-config.dist.json:/config/proxy-config.dist.json diff --git a/deployments/examples/ocis_hello/docker-compose.yml b/deployments/examples/ocis_hello/docker-compose.yml index be4b88a3b..d6c1c35f1 100644 --- a/deployments/examples/ocis_hello/docker-compose.yml +++ b/deployments/examples/ocis_hello/docker-compose.yml @@ -67,16 +67,7 @@ services: # make settings service available to oCIS Hello SETTINGS_GRPC_ADDR: 0.0.0.0:9191 # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/web-config.dist.json:/config/web-config.dist.json diff --git a/deployments/examples/ocis_keycloak/docker-compose.yml b/deployments/examples/ocis_keycloak/docker-compose.yml index ae1fdb267..dd2be4da7 100644 --- a/deployments/examples/ocis_keycloak/docker-compose.yml +++ b/deployments/examples/ocis_keycloak/docker-compose.yml @@ -71,16 +71,7 @@ services: STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_s3/docker-compose.yml b/deployments/examples/ocis_s3/docker-compose.yml index 0effba9f3..996262072 100644 --- a/deployments/examples/ocis_s3/docker-compose.yml +++ b/deployments/examples/ocis_s3/docker-compose.yml @@ -70,16 +70,7 @@ services: STORAGE_USERS_DRIVER_S3NG_SECRET_KEY: ${MINIO_SECRET_KEY:-ocis-secret-key} STORAGE_USERS_DRIVER_S3NG_BUCKET: ${MINIO_BUCKET:-ocis-bucket} # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_traefik/docker-compose.yml b/deployments/examples/ocis_traefik/docker-compose.yml index 7982533ba..53b8ca154 100644 --- a/deployments/examples/ocis_traefik/docker-compose.yml +++ b/deployments/examples/ocis_traefik/docker-compose.yml @@ -60,16 +60,7 @@ services: STORAGE_TRANSFER_SECRET: ${STORAGE_TRANSFER_SECRET:-replace-me-with-a-transfer-secret} OCIS_MACHINE_AUTH_API_KEY: ${OCIS_MACHINE_AUTH_API_KEY:-change-me-please} # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ocis-data:/var/lib/ocis diff --git a/deployments/examples/ocis_wopi/docker-compose.yml b/deployments/examples/ocis_wopi/docker-compose.yml index 42bd8354e..cc2cc7dab 100644 --- a/deployments/examples/ocis_wopi/docker-compose.yml +++ b/deployments/examples/ocis_wopi/docker-compose.yml @@ -69,16 +69,7 @@ services: STORAGE_GATEWAY_GRPC_ADDR: 0.0.0.0:9142 # make the REVA gateway accessible to the app drivers STORAGE_APP_REGISTRY_MIMETYPES_JSON: /var/tmp/ocis/app-config/mimetypes.json # INSECURE: needed if oCIS / Traefik is using self generated certificates - PROXY_OIDC_INSECURE: "${INSECURE:-false}" - THUMBNAILS_WEBDAVSOURCE_INSECURE: "${INSECURE:-false}" - THUMBNAILS_CS3SOURCE_INSECURE: "${INSECURE:-false}" - STORAGE_OIDC_INSECURE: "${INSECURE:-false}" - STORAGE_HOME_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_METADATA_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_USERS_DATAPROVIDER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_OCDAV_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_ARCHIVER_INSECURE: "${INSECURE:-false}" - STORAGE_FRONTEND_APPPROVIDER_INSECURE: "${INSECURE:-false}" + OCIS_INSECURE: "${INSECURE:-false}" volumes: - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh - ./config/ocis/mimetypes.json:/var/tmp/ocis/app-config/mimetypes.json diff --git a/docs/ocis/deployment/basic-remote-setup.md b/docs/ocis/deployment/basic-remote-setup.md index 96974c153..6569309ab 100644 --- a/docs/ocis/deployment/basic-remote-setup.md +++ b/docs/ocis/deployment/basic-remote-setup.md @@ -29,9 +29,10 @@ For the following examples you need to have the oCIS binary in your current work ### Using automatically generated certificates -In order to run oCIS with automatically generated and self signed certificates please execute following command. You need to replace `your-host` with an IP or hostname. +In order to run oCIS with automatically generated and self signed certificates please execute following command. You need to replace `your-host` with an IP or hostname. Since you have only self signed certificates you need to have `OCIS_INSECURE` set to `true`. ```bash +OCIS_INSECURE=true \ PROXY_HTTP_ADDR=0.0.0.0:9200 \ OCIS_URL=https://your-host:9200 \ ./ocis server @@ -42,6 +43,7 @@ OCIS_URL=https://your-host:9200 \ If you have your own certificates already in place, you may want to make oCIS use them: ```bash +OCIS_INSECURE=false \ PROXY_HTTP_ADDR=0.0.0.0:9200 \ OCIS_URL=https://your-host:9200 \ PROXY_TRANSPORT_TLS_KEY=./certs/your-host.key \ @@ -49,6 +51,8 @@ PROXY_TRANSPORT_TLS_CERT=./certs/your-host.crt \ ./ocis server ``` +If you generated these certificates on your own, you might need to set `OCIS_INSECURE` to `true`. + For more configuration options check the configuration section in [oCIS]({{< ref "../configuration" >}}) and the oCIS extensions. ## Start the oCIS fullstack server with Docker Compose diff --git a/docs/ocis/deployment/systemd.md b/docs/ocis/deployment/systemd.md index 716e690ef..8ac0a1d8f 100644 --- a/docs/ocis/deployment/systemd.md +++ b/docs/ocis/deployment/systemd.md @@ -45,6 +45,7 @@ In order to create the file we need first to create the folder `/etc/ocis/` and ``` OCIS_URL=https://some-hostname-or-ip:9200 PROXY_HTTP_ADDR=0.0.0.0:9200 +OCIS_INSECURE=false OCIS_LOG_LEVEL=error @@ -56,7 +57,7 @@ PROXY_TRANSPORT_TLS_CERT=/etc/ocis/proxy/server.crt PROXY_TRANSPORT_TLS_KEY=/etc/ocis/proxy/server.key ``` -Please change your `OCIS_URL` in order to reflect your actual deployment. +Please change your `OCIS_URL` in order to reflect your actual deployment. If you are using self signed certificates you need to set `OCIS_INSECURE=true` in `/etc/ocis/ocis.env`. ## Starting the oCIS service diff --git a/proxy/pkg/flagset/flagset.go b/proxy/pkg/flagset/flagset.go index 0d4b82992..62e5f0d37 100644 --- a/proxy/pkg/flagset/flagset.go +++ b/proxy/pkg/flagset/flagset.go @@ -210,7 +210,7 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { Name: "oidc-insecure", Value: flags.OverrideDefaultBool(cfg.OIDC.Insecure, false), Usage: "OIDC allow insecure communication", - EnvVars: []string{"PROXY_OIDC_INSECURE"}, + EnvVars: []string{"PROXY_OIDC_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.OIDC.Insecure, }, &cli.IntFlag{ diff --git a/storage/pkg/flagset/authbearer.go b/storage/pkg/flagset/authbearer.go index 90b14b7af..d41a89558 100644 --- a/storage/pkg/flagset/authbearer.go +++ b/storage/pkg/flagset/authbearer.go @@ -32,7 +32,7 @@ func AuthBearerWithConfig(cfg *config.Config) []cli.Flag { Name: "oidc-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.OIDC.Insecure, false), Usage: "OIDC allow insecure communication", - EnvVars: []string{"STORAGE_OIDC_INSECURE"}, + EnvVars: []string{"STORAGE_OIDC_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.OIDC.Insecure, }, &cli.StringFlag{ diff --git a/storage/pkg/flagset/frontend.go b/storage/pkg/flagset/frontend.go index 928798c8e..3baa80ae2 100644 --- a/storage/pkg/flagset/frontend.go +++ b/storage/pkg/flagset/frontend.go @@ -123,7 +123,7 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { Name: "approvider-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.AppProviderInsecure, false), Usage: "approvider insecure", - EnvVars: []string{"STORAGE_FRONTEND_APPPROVIDER_INSECURE"}, + EnvVars: []string{"STORAGE_FRONTEND_APPPROVIDER_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.Frontend.AppProviderInsecure, }, &cli.StringFlag{ @@ -137,7 +137,7 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { Name: "archiver-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.ArchiverInsecure, false), Usage: "archiver insecure", - EnvVars: []string{"STORAGE_FRONTEND_ARCHIVER_INSECURE"}, + EnvVars: []string{"STORAGE_FRONTEND_ARCHIVER_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.Frontend.ArchiverInsecure, }, &cli.StringFlag{ @@ -165,7 +165,7 @@ func FrontendWithConfig(cfg *config.Config) []cli.Flag { Name: "ocdav-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.Frontend.OCDavInsecure, false), Usage: "owncloud webdav insecure", - EnvVars: []string{"STORAGE_FRONTEND_OCDAV_INSECURE"}, + EnvVars: []string{"STORAGE_FRONTEND_OCDAV_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.Frontend.OCDavInsecure, }, &cli.StringFlag{ diff --git a/storage/pkg/flagset/storagehome.go b/storage/pkg/flagset/storagehome.go index 2ec1b71ac..76eb53d70 100644 --- a/storage/pkg/flagset/storagehome.go +++ b/storage/pkg/flagset/storagehome.go @@ -134,7 +134,7 @@ func StorageHomeWithConfig(cfg *config.Config) []cli.Flag { Name: "dataprovider-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.StorageHome.DataProvider.Insecure, false), Usage: "dataprovider insecure", - EnvVars: []string{"STORAGE_HOME_DATAPROVIDER_INSECURE"}, + EnvVars: []string{"STORAGE_HOME_DATAPROVIDER_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.StorageHome.DataProvider.Insecure, }, diff --git a/storage/pkg/flagset/storagemetadata.go b/storage/pkg/flagset/storagemetadata.go index 10b07441a..4b80756f0 100644 --- a/storage/pkg/flagset/storagemetadata.go +++ b/storage/pkg/flagset/storagemetadata.go @@ -73,7 +73,7 @@ func StorageMetadata(cfg *config.Config) []cli.Flag { Name: "dataprovider-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.StorageMetadata.DataProvider.Insecure, false), Usage: "dataprovider insecure", - EnvVars: []string{"STORAGE_METADATA_DATAPROVIDER_INSECURE"}, + EnvVars: []string{"STORAGE_METADATA_DATAPROVIDER_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.StorageMetadata.DataProvider.Insecure, }, diff --git a/storage/pkg/flagset/storageusers.go b/storage/pkg/flagset/storageusers.go index 9c6e7d1ed..6be58bc33 100644 --- a/storage/pkg/flagset/storageusers.go +++ b/storage/pkg/flagset/storageusers.go @@ -82,7 +82,7 @@ func StorageUsersWithConfig(cfg *config.Config) []cli.Flag { Name: "dataprovider-insecure", Value: flags.OverrideDefaultBool(cfg.Reva.StorageUsers.DataProvider.Insecure, false), Usage: "dataprovider insecure", - EnvVars: []string{"STORAGE_USERS_DATAPROVIDER_INSECURE"}, + EnvVars: []string{"STORAGE_USERS_DATAPROVIDER_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Reva.StorageUsers.DataProvider.Insecure, }, &cli.BoolFlag{ diff --git a/tests/acceptance/docker/src/ocis-base.yml b/tests/acceptance/docker/src/ocis-base.yml index 4154bd0d7..7cd72650c 100644 --- a/tests/acceptance/docker/src/ocis-base.yml +++ b/tests/acceptance/docker/src/ocis-base.yml @@ -14,6 +14,7 @@ services: WEB_UI_CONFIG: /drone/src/tests/config/drone/ocis-config.json IDP_IDENTIFIER_REGISTRATION_CONF: /drone/src/tests/config/drone/identifier-registration.yml ACCOUNTS_HASH_DIFFICULTY: 4 + OCIS_INSECURE: "true" # s3ng specific settings STORAGE_USERS_DRIVER_S3NG_ENDPOINT: http://ceph:8080 STORAGE_USERS_DRIVER_S3NG_REGION: default diff --git a/thumbnails/pkg/flagset/flagset.go b/thumbnails/pkg/flagset/flagset.go index c9e0edc0d..9efd680a1 100644 --- a/thumbnails/pkg/flagset/flagset.go +++ b/thumbnails/pkg/flagset/flagset.go @@ -156,14 +156,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { Name: "webdavsource-insecure", Value: flags.OverrideDefaultBool(cfg.Thumbnail.WebdavAllowInsecure, false), Usage: "Whether to skip certificate checks", - EnvVars: []string{"THUMBNAILS_WEBDAVSOURCE_INSECURE"}, + EnvVars: []string{"THUMBNAILS_WEBDAVSOURCE_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Thumbnail.WebdavAllowInsecure, }, &cli.BoolFlag{ Name: "cs3source-insecure", Value: flags.OverrideDefaultBool(cfg.Thumbnail.CS3AllowInsecure, false), Usage: "Whether to skip certificate checks", - EnvVars: []string{"THUMBNAILS_CS3SOURCE_INSECURE"}, + EnvVars: []string{"THUMBNAILS_CS3SOURCE_INSECURE", "OCIS_INSECURE"}, Destination: &cfg.Thumbnail.CS3AllowInsecure, }, &cli.StringSliceFlag{ From 28af5f74f372e43c47f4ee892074b7e49d64987e Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Wed, 10 Nov 2021 16:58:45 +0100 Subject: [PATCH 07/15] change change title --- changelog/unreleased/insecure-options.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/changelog/unreleased/insecure-options.md b/changelog/unreleased/insecure-options.md index 3d66ab32f..ae56ea1ea 100644 --- a/changelog/unreleased/insecure-options.md +++ b/changelog/unreleased/insecure-options.md @@ -1,6 +1,8 @@ -Change: Make insecure options configurable +Change: Make all insecure options configurable and change the default to false -We had several hard-coded 'insecure' flags. These options are now configurable and default to false. Also we changed all other 'insecure' flags with a previous default of true to false. In development environments using self signed certs (the default) you need to set these flags: +We had several hard-coded 'insecure' flags. These options are now configurable and default to false. Also we changed all other 'insecure' flags with a previous default of true to false. + +In development environments using self signed certs (the default) you now need to set these flags: ``` PROXY_OIDC_INSECURE=true From 6bf0515f94abc7e694860a9d12c327e809b78e27 Mon Sep 17 00:00:00 2001 From: David Christofas Date: Wed, 10 Nov 2021 16:54:00 +0000 Subject: [PATCH 08/15] Automated changelog update [skip ci] --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db025ace..1421fdd48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The following sections list the changes for unreleased. * Bugfix - Fix opening images in media viewer for some usernames: [#2738](https://github.com/owncloud/ocis/pull/2738) * Bugfix - Fix error logging when there is no thumbnail for a file: [#2702](https://github.com/owncloud/ocis/pull/2702) * Bugfix - Don't announce resharing via capabilities: [#2690](https://github.com/owncloud/ocis/pull/2690) +* Change - Make all insecure options configurable and change the default to false: [#2700](https://github.com/owncloud/ocis/issues/2700) * Enhancement - Add API to list all spaces: [#2692](https://github.com/owncloud/ocis/pull/2692) * Enhancement - Update reva to v1.16: [#2737](https://github.com/owncloud/ocis/pull/2737) @@ -62,6 +63,28 @@ The following sections list the changes for unreleased. https://github.com/owncloud/ocis/pull/2690 +* Change - Make all insecure options configurable and change the default to false: [#2700](https://github.com/owncloud/ocis/issues/2700) + + We had several hard-coded 'insecure' flags. These options are now configurable and default to + false. Also we changed all other 'insecure' flags with a previous default of true to false. + + In development environments using self signed certs (the default) you now need to set these + flags: + + ``` PROXY_OIDC_INSECURE=true STORAGE_FRONTEND_APPPROVIDER_INSECURE=true + STORAGE_FRONTEND_ARCHIVER_INSECURE=true STORAGE_FRONTEND_OCDAV_INSECURE=true + STORAGE_HOME_DATAPROVIDER_INSECURE=true + STORAGE_METADATA_DATAPROVIDER_INSECURE=true STORAGE_OIDC_INSECURE=true + STORAGE_USERS_DATAPROVIDER_INSECURE=true THUMBNAILS_CS3SOURCE_INSECURE=true + THUMBNAILS_WEBDAVSOURCE_INSECURE=true ``` + + As an alternative you also can set a single flag, which configures all options together: + + ``` OCIS_INSECURE=true ``` + + https://github.com/owncloud/ocis/issues/2700 + https://github.com/owncloud/ocis/pull/2745 + * Enhancement - Add API to list all spaces: [#2692](https://github.com/owncloud/ocis/pull/2692) Added a graph endpoint to enable users with the `list-all-spaces` permission to list all From 0f08d38db95fc2b081653493ba43912cae639d0b Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 11:50:40 +0545 Subject: [PATCH 09/15] [docs-only] mention insecure option --- docs/ocis/development/testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/development/testing.md b/docs/ocis/development/testing.md index d61d7eff4..60a68c476 100644 --- a/docs/ocis/development/testing.md +++ b/docs/ocis/development/testing.md @@ -98,7 +98,7 @@ git clone https://github.com/owncloud/core.git To start ocis: ``` -PROXY_ENABLE_BASIC_AUTH=true bin/ocis server +OCIS_INSECURE=true PROXY_ENABLE_BASIC_AUTH=true bin/ocis server ``` `PROXY_ENABLE_BASIC_AUTH` will allow the acceptance tests to make requests against the provisioning api (and other endpoints) using basic auth. From 021fa50e9ddba1d17eb6cd3cdcee4131ea9e3243 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 12:06:46 +0545 Subject: [PATCH 10/15] [tests-only] test downloading multiple items with archiver --- .../features/apiArchiver/downloadById.feature | 20 ++++++++++++ .../features/bootstrap/ArchiverContext.php | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/acceptance/features/apiArchiver/downloadById.feature b/tests/acceptance/features/apiArchiver/downloadById.feature index 0937e25ce..355783f62 100644 --- a/tests/acceptance/features/apiArchiver/downloadById.feature +++ b/tests/acceptance/features/apiArchiver/downloadById.feature @@ -41,3 +41,23 @@ Feature: download multiple resources bundled into an archive | user-agent | archive-type | | Linux | tar | | Windows NT | zip | + + Scenario: download multiple files and folders + Given user "Alice" has uploaded file with content "some data" to "/textfile0.txt" + And user "Alice" has uploaded file with content "other data" to "/textfile1.txt" + And user "Alice" has created folder "my_data" + And user "Alice" has uploaded file with content "some data" to "/my_data/textfile2.txt" + And user "Alice" has created folder "more_data" + And user "Alice" has uploaded file with content "more data" to "/more_data/an_other_file.txt" + When user "Alice" downloads the archive of these items using the resource ids + | textfile0.txt | + | textfile1.txt | + | my_data | + | more_data | + Then the HTTP status code should be "200" + And the downloaded tar archive should contain these files: + | name | content | + | textfile0.txt | some data | + | textfile1.txt | other data | + | my_data/textfile2.txt | some data | + | more_data/an_other_file.txt | more data | diff --git a/tests/acceptance/features/bootstrap/ArchiverContext.php b/tests/acceptance/features/bootstrap/ArchiverContext.php index f55540b62..4202c26b6 100644 --- a/tests/acceptance/features/bootstrap/ArchiverContext.php +++ b/tests/acceptance/features/bootstrap/ArchiverContext.php @@ -99,6 +99,37 @@ class ArchiverContext implements Context { ); } + /** + * @When user :arg1 downloads the archive of these items using the resource ids + * + * @param string $user + * @param TableNode $items + * + * @return void + * + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function userDownloadsTheArchiveOfTheseItemsUsingTheResourceIds( + string $user, + TableNode $items + ): void { + $user = $this->featureContext->getActualUsername($user); + $resourceIdsString = ''; + foreach ($items->getRows() as $item) { + $fileId = $this->featureContext->getFileIdForPath($user, $item[0]); + $resourceIdsString .= 'id=' . $fileId . '&'; + } + $resourceIdsString = \rtrim($resourceIdsString, '&'); + $this->featureContext->setResponse( + HttpRequestHelper::get( + $this->featureContext->getBaseUrl() . '/archiver?' . $resourceIdsString, + '', + $user, + $this->featureContext->getPasswordForUser($user), + ) + ); + } + /** * @Then the downloaded :type archive should contain these files: * From b5427075a7ee91773665854029034d930db6c3b3 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 12:14:58 +0545 Subject: [PATCH 11/15] run phpcbf on make test-php-style-fix --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 258d2f66c..491210e3a 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ OCIS_MODULES = \ # bin file definitions PHP_CS_FIXER=php -d zend.enable_gc=0 vendor-bin/owncloud-codestyle/vendor/bin/php-cs-fixer PHP_CODESNIFFER=vendor-bin/php_codesniffer/vendor/bin/phpcs +PHP_CODEBEAUTIFIER=vendor-bin/php_codesniffer/vendor/bin/phpcbf PHAN=php -d zend.enable_gc=0 vendor-bin/phan/vendor/bin/phan PHPSTAN=php -d zend.enable_gc=0 vendor-bin/phpstan/vendor/bin/phpstan @@ -213,7 +214,7 @@ test-php-style: vendor-bin/owncloud-codestyle/vendor vendor-bin/php_codesniffer/ .PHONY: test-php-style-fix test-php-style-fix: vendor-bin/owncloud-codestyle/vendor $(PHP_CS_FIXER) fix -v --diff --allow-risky yes - + $(PHP_CODEBEAUTIFIER) --cache --runtime-set ignore_warnings_on_exit --standard=phpcs.xml tests/acceptance vendor-bin/owncloud-codestyle/vendor: vendor/bamarni/composer-bin-plugin vendor-bin/owncloud-codestyle/composer.lock composer bin owncloud-codestyle install --no-progress From 9a548ec4cf866ab517dee4fbc883503adf412d29 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 12:15:15 +0545 Subject: [PATCH 12/15] fix codestyle of SpacesContext --- .../features/bootstrap/SpacesContext.php | 1414 +++++++++-------- 1 file changed, 710 insertions(+), 704 deletions(-) diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 047c9505e..1e2774738 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -36,753 +36,759 @@ require_once 'bootstrap.php'; */ class SpacesContext implements Context { - /** - * @var FeatureContext - */ - private FeatureContext $featureContext; + /** + * @var FeatureContext + */ + private FeatureContext $featureContext; - /** - * @var array - */ - private array $availableSpaces; + /** + * @var array + */ + private array $availableSpaces; - /** - * @return array - */ - public function getAvailableSpaces(): array { - return $this->availableSpaces; - } + /** + * @return array + */ + public function getAvailableSpaces(): array { + return $this->availableSpaces; + } - /** - * @param array $availableSpaces - * - * @return void - */ - public function setAvailableSpaces(array $availableSpaces): void { - $this->availableSpaces = $availableSpaces; - } + /** + * @param array $availableSpaces + * + * @return void + */ + public function setAvailableSpaces(array $availableSpaces): void { + $this->availableSpaces = $availableSpaces; + } - /** - * response content parsed from XML to an array - * - * @var array - */ - private array $responseXml = []; + /** + * response content parsed from XML to an array + * + * @var array + */ + private array $responseXml = []; - /** - * @return array - */ - public function getResponseXml(): array { - return $this->responseXml; - } + /** + * @return array + */ + public function getResponseXml(): array { + return $this->responseXml; + } - /** - * @param array $responseXml - * - * @return void - */ - public function setResponseXml(array $responseXml): void { - $this->responseXml = $responseXml; - } + /** + * @param array $responseXml + * + * @return void + */ + public function setResponseXml(array $responseXml): void { + $this->responseXml = $responseXml; + } - /** - * space id from last propfind request - * - * @var string - */ - private string $responseSpaceId; + /** + * space id from last propfind request + * + * @var string + */ + private string $responseSpaceId; - /** - * @param string $responseSpaceId - * - * @return void - */ - public function setResponseSpaceId(string $responseSpaceId): void { - $this->responseSpaceId = $responseSpaceId; - } + /** + * @param string $responseSpaceId + * + * @return void + */ + public function setResponseSpaceId(string $responseSpaceId): void { + $this->responseSpaceId = $responseSpaceId; + } - /** - * @return string - */ - public function getResponseSpaceId(): string { - return $this->responseSpaceId; - } + /** + * @return string + */ + public function getResponseSpaceId(): string { + return $this->responseSpaceId; + } - /** - * Get SpaceId by Name - * - * @param $name string - * @return string - * @throws Exception - */ - public function getSpaceIdByNameFromResponse(string $name): string - { - $space = $this->getSpaceByNameFromResponse($name); - Assert::assertIsArray($space, "Space with name $name not found"); - if (!isset($space["id"])) { - throw new Exception(__METHOD__ . " space with name $name not found"); - } - return $space["id"]; - } + /** + * Get SpaceId by Name + * + * @param $name string + * + * @return string + * + * @throws Exception + */ + public function getSpaceIdByNameFromResponse(string $name): string { + $space = $this->getSpaceByNameFromResponse($name); + Assert::assertIsArray($space, "Space with name $name not found"); + if (!isset($space["id"])) { + throw new Exception(__METHOD__ . " space with name $name not found"); + } + return $space["id"]; + } - /** - * Get Space Array by name - * - * @param string $name - * @return array - * @throws Exception - */ - public function getSpaceByNameFromResponse(string $name): array - { - $response = json_decode($this->featureContext->getResponse()->getBody(), true, 512, JSON_THROW_ON_ERROR); - $spaceAsArray = $response; - if (isset($response['name']) && $response['name'] === $name) { - return $response; - } - foreach ($spaceAsArray["value"] as $spaceCandidate) { - if ($spaceCandidate['name'] === $name) { - return $spaceCandidate; - } - } - return []; - } + /** + * Get Space Array by name + * + * @param string $name + * + * @return array + * + * @throws Exception + */ + public function getSpaceByNameFromResponse(string $name): array { + $response = json_decode($this->featureContext->getResponse()->getBody(), true, 512, JSON_THROW_ON_ERROR); + $spaceAsArray = $response; + if (isset($response['name']) && $response['name'] === $name) { + return $response; + } + foreach ($spaceAsArray["value"] as $spaceCandidate) { + if ($spaceCandidate['name'] === $name) { + return $spaceCandidate; + } + } + return []; + } - /** - * @param string $name - * @return array - */ - public function getSpaceByName(string $name): array { - $spaces = $this->getAvailableSpaces(); - Assert::assertIsArray($spaces[$name]); - return $spaces[$name]; - } + /** + * @param string $name + * + * @return array + */ + public function getSpaceByName(string $name): array { + $spaces = $this->getAvailableSpaces(); + Assert::assertIsArray($spaces[$name]); + return $spaces[$name]; + } - /** - * @BeforeScenario - * - * @param BeforeScenarioScope $scope - * - * @return void - * @throws Exception - */ - public function setUpScenario(BeforeScenarioScope $scope): void - { - // Get the environment - $environment = $scope->getEnvironment(); - // Get all the contexts you need in this context - $this->featureContext = $environment->getContext('FeatureContext'); - SetupHelper::init( - $this->featureContext->getAdminUsername(), - $this->featureContext->getAdminPassword(), - $this->featureContext->getBaseUrl(), - $this->featureContext->getOcPath() - ); - } + /** + * @BeforeScenario + * + * @param BeforeScenarioScope $scope + * + * @return void + * + * @throws Exception + */ + public function setUpScenario(BeforeScenarioScope $scope): void { + // Get the environment + $environment = $scope->getEnvironment(); + // Get all the contexts you need in this context + $this->featureContext = $environment->getContext('FeatureContext'); + SetupHelper::init( + $this->featureContext->getAdminUsername(), + $this->featureContext->getAdminPassword(), + $this->featureContext->getBaseUrl(), + $this->featureContext->getOcPath() + ); + } - /** - * Send Graph List Spaces Request - * - * @param string $baseUrl - * @param string $user - * @param string $password - * @param string $urlArguments - * @param string $xRequestId - * @param array $body - * @param array $headers - * - * @return ResponseInterface - * - * @throws GuzzleException - */ - public function listSpacesRequest( - string $baseUrl, - string $user, - string $password, - string $urlArguments, - string $xRequestId = '', - array $body = [], - array $headers = [] - ): ResponseInterface { - $fullUrl = $baseUrl; - if (!str_ends_with($fullUrl, '/')) { - $fullUrl .= '/'; - } - $fullUrl .= "graph/v1.0/me/drives/" . $urlArguments; + /** + * Send Graph List Spaces Request + * + * @param string $baseUrl + * @param string $user + * @param string $password + * @param string $urlArguments + * @param string $xRequestId + * @param array $body + * @param array $headers + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function listSpacesRequest( + string $baseUrl, + string $user, + string $password, + string $urlArguments, + string $xRequestId = '', + array $body = [], + array $headers = [] + ): ResponseInterface { + $fullUrl = $baseUrl; + if (!str_ends_with($fullUrl, '/')) { + $fullUrl .= '/'; + } + $fullUrl .= "graph/v1.0/me/drives/" . $urlArguments; - return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body); - } + return HttpRequestHelper::get($fullUrl, $xRequestId, $user, $password, $headers, $body); + } - /** - * Send Graph Create Space Request - * - * @param string $baseUrl - * @param string $user - * @param string $password - * @param string $body - * @param string $xRequestId - * @param array $headers - * - * @return ResponseInterface - * - * @throws GuzzleException - */ - public function sendCreateSpaceRequest( - string $baseUrl, - string $user, - string $password, - string $body, - string $xRequestId = '', - array $headers = [] - ): ResponseInterface { - $fullUrl = $baseUrl; - if (!str_ends_with($fullUrl, '/')) { - $fullUrl .= '/'; - } - $fullUrl .= "graph/v1.0/drives/"; + /** + * Send Graph Create Space Request + * + * @param string $baseUrl + * @param string $user + * @param string $password + * @param string $body + * @param string $xRequestId + * @param array $headers + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendCreateSpaceRequest( + string $baseUrl, + string $user, + string $password, + string $body, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface { + $fullUrl = $baseUrl; + if (!str_ends_with($fullUrl, '/')) { + $fullUrl .= '/'; + } + $fullUrl .= "graph/v1.0/drives/"; - return HttpRequestHelper::post($fullUrl, $xRequestId, $user, $password, $headers, $body); - } + return HttpRequestHelper::post($fullUrl, $xRequestId, $user, $password, $headers, $body); + } - /** - * Send Propfind Request to Url - * - * @param string $fullUrl - * @param string $user - * @param string $password - * @param string $xRequestId - * @param array $headers - * - * @return ResponseInterface - * - * @throws GuzzleException - */ - public function sendPropfindRequestToUrl( - string $fullUrl, - string $user, - string $password, - string $xRequestId = '', - array $headers = [] - ): ResponseInterface { - return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PROPFIND', $user, $password, $headers); - } + /** + * Send Propfind Request to Url + * + * @param string $fullUrl + * @param string $user + * @param string $password + * @param string $xRequestId + * @param array $headers + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendPropfindRequestToUrl( + string $fullUrl, + string $user, + string $password, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface { + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PROPFIND', $user, $password, $headers); + } - /** - * Send Put Request to Url - * - * @param string $fullUrl - * @param string $user - * @param string $password - * @param string $xRequestId - * @param array $headers - * @param string $content - * @return ResponseInterface - * @throws GuzzleException - */ - public function sendPutRequestToUrl( - string $fullUrl, - string $user, - string $password, - string $xRequestId = '', - array $headers = [], - string $content = "" - ): ResponseInterface - { - return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PUT', $user, $password, $headers, $content); - } + /** + * Send Put Request to Url + * + * @param string $fullUrl + * @param string $user + * @param string $password + * @param string $xRequestId + * @param array $headers + * @param string $content + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendPutRequestToUrl( + string $fullUrl, + string $user, + string $password, + string $xRequestId = '', + array $headers = [], + string $content = "" + ): ResponseInterface { + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, 'PUT', $user, $password, $headers, $content); + } - /** - * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/ - * - * @param string $user - * @return void - * @throws GuzzleException - */ - public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user): void - { - $this->featureContext->setResponse( - $this->listSpacesRequest( - $this->featureContext->getBaseUrl(), - $user, - $this->featureContext->getPasswordForUser($user), - "", - "" - ) - ); - $this->rememberTheAvailableSpaces(); - } + /** + * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/ + * + * @param string $user + * + * @return void + * + * @throws GuzzleException + */ + public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user): void { + $this->featureContext->setResponse( + $this->listSpacesRequest( + $this->featureContext->getBaseUrl(), + $user, + $this->featureContext->getPasswordForUser($user), + "", + "" + ) + ); + $this->rememberTheAvailableSpaces(); + } - /** - * @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with the default quota using the GraphApi$/ - * - * @param string $user - * @param string $spaceName - * @param string $spaceType - * - * @return void - * - * @throws GuzzleException - * @throws Exception - */ - public function theUserCreatesASpaceUsingTheGraphApi( - string $user, - string $spaceName, - string $spaceType - ): void { - $space = ["Name" => $spaceName, "driveType" => $spaceType]; - $body = json_encode($space, JSON_THROW_ON_ERROR); - $this->featureContext->setResponse( - $this->sendCreateSpaceRequest( - $this->featureContext->getBaseUrl(), - $user, - $this->featureContext->getPasswordForUser($user), - $body, - "" - ) - ); - } + /** + * @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with the default quota using the GraphApi$/ + * + * @param string $user + * @param string $spaceName + * @param string $spaceType + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function theUserCreatesASpaceUsingTheGraphApi( + string $user, + string $spaceName, + string $spaceType + ): void { + $space = ["Name" => $spaceName, "driveType" => $spaceType]; + $body = json_encode($space, JSON_THROW_ON_ERROR); + $this->featureContext->setResponse( + $this->sendCreateSpaceRequest( + $this->featureContext->getBaseUrl(), + $user, + $this->featureContext->getPasswordForUser($user), + $body, + "" + ) + ); + } - /** - * @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with quota "([^"]*)" using the GraphApi$/ - * - * @param string $user - * @param string $spaceName - * @param string $spaceType - * @param int $quota - * - * @return void - * - * @throws GuzzleException - * @throws Exception - */ - public function theUserCreatesASpaceWithQuotaUsingTheGraphApi( - string $user, - string $spaceName, - string $spaceType, - int $quota - ): void { - $space = ["Name" => $spaceName, "driveType" => $spaceType, "quota" => ["total" => $quota]]; - $body = json_encode($space); - $this->featureContext->setResponse( - $this->sendCreateSpaceRequest( - $this->featureContext->getBaseUrl(), - $user, - $this->featureContext->getPasswordForUser($user), - $body, - "" - ) - ); - } + /** + * @When /^user "([^"]*)" creates a space "([^"]*)" of type "([^"]*)" with quota "([^"]*)" using the GraphApi$/ + * + * @param string $user + * @param string $spaceName + * @param string $spaceType + * @param int $quota + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function theUserCreatesASpaceWithQuotaUsingTheGraphApi( + string $user, + string $spaceName, + string $spaceType, + int $quota + ): void { + $space = ["Name" => $spaceName, "driveType" => $spaceType, "quota" => ["total" => $quota]]; + $body = json_encode($space); + $this->featureContext->setResponse( + $this->sendCreateSpaceRequest( + $this->featureContext->getBaseUrl(), + $user, + $this->featureContext->getPasswordForUser($user), + $body, + "" + ) + ); + } - /** - * @When /^the administrator gives "([^"]*)" the role "([^"]*)" using the settings api$/ - * - * @param string $user - * @param string $role - * - * @return void - * - * @throws GuzzleException - * @throws Exception - */ - public function theAdministratorGivesUserTheRole(string $user, string $role): void { - $admin = $this->featureContext->getAdminUsername(); - $password = $this->featureContext->getAdminPassword(); - $headers = []; - $bundles = []; - $accounts = []; - $assignment = []; + /** + * @When /^the administrator gives "([^"]*)" the role "([^"]*)" using the settings api$/ + * + * @param string $user + * @param string $role + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function theAdministratorGivesUserTheRole(string $user, string $role): void { + $admin = $this->featureContext->getAdminUsername(); + $password = $this->featureContext->getAdminPassword(); + $headers = []; + $bundles = []; + $accounts = []; + $assignment = []; - $baseUrl = $this->featureContext->getBaseUrl(); - if (!str_ends_with($baseUrl, '/')) { - $baseUrl .= '/'; - } - // get the roles list first - $fullUrl = $baseUrl . "api/v0/settings/roles-list"; - $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, "{}")); - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"])) { - $bundles = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"]; - } - } - $roleToAssign = ""; - foreach ($bundles as $value) { - // find the selected role - if ($value["displayName"] === $role) { - $roleToAssign = $value; - } - } - Assert::assertNotEmpty($roleToAssign, "The selected role $role could not be found"); + $baseUrl = $this->featureContext->getBaseUrl(); + if (!str_ends_with($baseUrl, '/')) { + $baseUrl .= '/'; + } + // get the roles list first + $fullUrl = $baseUrl . "api/v0/settings/roles-list"; + $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, "{}")); + if ($this->featureContext->getResponse()) { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"])) { + $bundles = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"]; + } + } + $roleToAssign = ""; + foreach ($bundles as $value) { + // find the selected role + if ($value["displayName"] === $role) { + $roleToAssign = $value; + } + } + Assert::assertNotEmpty($roleToAssign, "The selected role $role could not be found"); - // get the accounts list first - $fullUrl = $baseUrl . "api/v0/accounts/accounts-list"; - $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, "{}")); - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["accounts"])) { - $accounts = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["accounts"]; - } - } - $accountToChange = ""; - foreach ($accounts as $account) { - // find the selected user - if ($account["preferredName"] === $user) { - $accountToChange = $account; - } - } - Assert::assertNotEmpty($accountToChange, "The selected account $user does not exist"); + // get the accounts list first + $fullUrl = $baseUrl . "api/v0/accounts/accounts-list"; + $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, "{}")); + if ($this->featureContext->getResponse()) { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["accounts"])) { + $accounts = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["accounts"]; + } + } + $accountToChange = ""; + foreach ($accounts as $account) { + // find the selected user + if ($account["preferredName"] === $user) { + $accountToChange = $account; + } + } + Assert::assertNotEmpty($accountToChange, "The selected account $user does not exist"); - // set the new role - $fullUrl = $baseUrl . "api/v0/settings/assignments-add"; - $body = json_encode(["account_uuid" => $accountToChange["id"], "role_id" => $roleToAssign["id"]], JSON_THROW_ON_ERROR); + // set the new role + $fullUrl = $baseUrl . "api/v0/settings/assignments-add"; + $body = json_encode(["account_uuid" => $accountToChange["id"], "role_id" => $roleToAssign["id"]], JSON_THROW_ON_ERROR); - $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, $body)); - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"])) { - $assignment = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"]; - } - } + $this->featureContext->setResponse(HttpRequestHelper::post($fullUrl, "", $admin, $password, $headers, $body)); + if ($this->featureContext->getResponse()) { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"])) { + $assignment = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"]; + } + } - Assert::assertEquals($accountToChange["id"], $assignment["accountUuid"]); - Assert::assertEquals($roleToAssign["id"], $assignment["roleId"]); - } + Assert::assertEquals($accountToChange["id"], $assignment["accountUuid"]); + Assert::assertEquals($roleToAssign["id"], $assignment["roleId"]); + } - /** - * Remember the available Spaces - * - * @return void - * - * @throws Exception - */ - public function rememberTheAvailableSpaces(): void { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - $drives = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR); - if (isset($drives["value"])) { - $drives = $drives["value"]; - } + /** + * Remember the available Spaces + * + * @return void + * + * @throws Exception + */ + public function rememberTheAvailableSpaces(): void { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + $drives = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR); + if (isset($drives["value"])) { + $drives = $drives["value"]; + } - Assert::assertArrayHasKey(0, $drives, "No drives were found on that endpoint"); - $spaces = []; - foreach ($drives as $drive) { - $spaces[$drive["name"]] = $drive; - } - $this->setAvailableSpaces($spaces); - Assert::assertNotEmpty($spaces, "No spaces have been found"); - } + Assert::assertArrayHasKey(0, $drives, "No drives were found on that endpoint"); + $spaces = []; + foreach ($drives as $drive) { + $spaces[$drive["name"]] = $drive; + } + $this->setAvailableSpaces($spaces); + Assert::assertNotEmpty($spaces, "No spaces have been found"); + } - /** - * @When /^user "([^"]*)" lists the content of the space with the name "([^"]*)" using the WebDav Api$/ - * - * @param string $user - * @param string $name - * @return void - * @throws GuzzleException - */ - public function theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( - string $user, - string $name - ): void - { - $space = $this->getSpaceByName($name); - Assert::assertIsArray($space); - Assert::assertNotEmpty($spaceId = $space["id"]); - Assert::assertNotEmpty($spaceWebDavUrl = $space["root"]["webDavUrl"]); - $this->featureContext->setResponse( - $this->sendPropfindRequestToUrl( - $spaceWebDavUrl, - $user, - $this->featureContext->getPasswordForUser($user), - "", - [], - ) - ); - $this->setResponseSpaceId($spaceId); - $this->setResponseXml(HttpRequestHelper::parseResponseAsXml($this->featureContext->getResponse()) - ); - } + /** + * @When /^user "([^"]*)" lists the content of the space with the name "([^"]*)" using the WebDav Api$/ + * + * @param string $user + * @param string $name + * + * @return void + * + * @throws GuzzleException + */ + public function theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( + string $user, + string $name + ): void { + $space = $this->getSpaceByName($name); + Assert::assertIsArray($space); + Assert::assertNotEmpty($spaceId = $space["id"]); + Assert::assertNotEmpty($spaceWebDavUrl = $space["root"]["webDavUrl"]); + $this->featureContext->setResponse( + $this->sendPropfindRequestToUrl( + $spaceWebDavUrl, + $user, + $this->featureContext->getPasswordForUser($user), + "", + [], + ) + ); + $this->setResponseSpaceId($spaceId); + $this->setResponseXml( + HttpRequestHelper::parseResponseAsXml($this->featureContext->getResponse()) + ); + } - /** - * @Then /^the (?:propfind|search) result of the space should (not|)\s?contain these (?:files|entries):$/ - * - * @param string $shouldOrNot (not|) - * @param TableNode $expectedFiles - * - * @return void - * - * @throws Exception - */ - public function thePropfindResultShouldContainEntries( - string $shouldOrNot, - TableNode $expectedFiles - ):void { - $this->propfindResultShouldContainEntries( - $shouldOrNot, - $expectedFiles, - ); - } + /** + * @Then /^the (?:propfind|search) result of the space should (not|)\s?contain these (?:files|entries):$/ + * + * @param string $shouldOrNot (not|) + * @param TableNode $expectedFiles + * + * @return void + * + * @throws Exception + */ + public function thePropfindResultShouldContainEntries( + string $shouldOrNot, + TableNode $expectedFiles + ):void { + $this->propfindResultShouldContainEntries( + $shouldOrNot, + $expectedFiles, + ); + } - /** - * @Then /^the json responded should contain a space "([^"]*)" with these key and value pairs:$/ - * - * @param string $spaceName - * @param TableNode $table - * - * @return void - * @throws Exception - */ - public function jsonRespondedShouldContain( - string $spaceName, - TableNode $table - ): void { - $this->featureContext->verifyTableNodeColumns($table, ['key', 'value']); - Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName), "No space with name $spaceName found"); - foreach ($table->getHash() as $row) { - // remember the original Space Array - $original = $spaceAsArray; - $row['value'] = $this->featureContext->substituteInLineCodes( - $row['value'], - $this->featureContext->getCurrentUser(), - [], - [ - [ - "code" => "%space_id%", - "function" => - [$this, "getSpaceIdByNameFromResponse"], - "parameter" => [$spaceName] - ] - ] - ); - $segments = explode("@@@", $row["key"]); - // traverse down in the array - foreach ($segments as $segment) { - $arrayKeyExists = array_key_exists($segment, $spaceAsArray); - $key = $row["key"]; - Assert::assertTrue($arrayKeyExists, "The key $key does not exist on the response"); - if ($arrayKeyExists) { - $spaceAsArray = $spaceAsArray[$segment]; - } - } - Assert::assertEquals($row["value"], $spaceAsArray); - // set the spaceArray to the point before traversing - $spaceAsArray = $original; - } - } + /** + * @Then /^the json responded should contain a space "([^"]*)" with these key and value pairs:$/ + * + * @param string $spaceName + * @param TableNode $table + * + * @return void + * @throws Exception + */ + public function jsonRespondedShouldContain( + string $spaceName, + TableNode $table + ): void { + $this->featureContext->verifyTableNodeColumns($table, ['key', 'value']); + Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName), "No space with name $spaceName found"); + foreach ($table->getHash() as $row) { + // remember the original Space Array + $original = $spaceAsArray; + $row['value'] = $this->featureContext->substituteInLineCodes( + $row['value'], + $this->featureContext->getCurrentUser(), + [], + [ + [ + "code" => "%space_id%", + "function" => + [$this, "getSpaceIdByNameFromResponse"], + "parameter" => [$spaceName] + ] + ] + ); + $segments = explode("@@@", $row["key"]); + // traverse down in the array + foreach ($segments as $segment) { + $arrayKeyExists = \array_key_exists($segment, $spaceAsArray); + $key = $row["key"]; + Assert::assertTrue($arrayKeyExists, "The key $key does not exist on the response"); + if ($arrayKeyExists) { + $spaceAsArray = $spaceAsArray[$segment]; + } + } + Assert::assertEquals($row["value"], $spaceAsArray); + // set the spaceArray to the point before traversing + $spaceAsArray = $original; + } + } - /** - * @param string $shouldOrNot (not|) - * @param TableNode $expectedFiles - * - * @return void - * - * @throws Exception - */ - public function propfindResultShouldContainEntries( - string $shouldOrNot, - TableNode $expectedFiles - ): void { - $this->verifyTableNodeColumnsCount($expectedFiles, 1); - $elementRows = $expectedFiles->getRows(); - $should = ($shouldOrNot !== "not"); + /** + * @param string $shouldOrNot (not|) + * @param TableNode $expectedFiles + * + * @return void + * + * @throws Exception + */ + public function propfindResultShouldContainEntries( + string $shouldOrNot, + TableNode $expectedFiles + ): void { + $this->verifyTableNodeColumnsCount($expectedFiles, 1); + $elementRows = $expectedFiles->getRows(); + $should = ($shouldOrNot !== "not"); - foreach ($elementRows as $expectedFile) { - $fileFound = $this->findEntryFromPropfindResponse( - $expectedFile[0] - ); - if ($should) { - Assert::assertNotEmpty( - $fileFound, - "response does not contain the entry '$expectedFile[0]'" - ); - } else { - Assert::assertEmpty( - $fileFound, - "response does contain the entry '$expectedFile[0]' but should not" - ); - } - } - } + foreach ($elementRows as $expectedFile) { + $fileFound = $this->findEntryFromPropfindResponse( + $expectedFile[0] + ); + if ($should) { + Assert::assertNotEmpty( + $fileFound, + "response does not contain the entry '$expectedFile[0]'" + ); + } else { + Assert::assertEmpty( + $fileFound, + "response does contain the entry '$expectedFile[0]' but should not" + ); + } + } + } - /** - * Verify that the tableNode contains expected number of columns - * - * @param TableNode $table - * @param int $count - * - * @return void - * - * @throws Exception - */ - public function verifyTableNodeColumnsCount( - TableNode $table, - int $count - ): void { - if (\count($table->getRows()) < 1) { - throw new Exception("Table should have at least one row."); - } - $rowCount = \count($table->getRows()[0]); - if ($count !== $rowCount) { - throw new Exception("Table expected to have $count rows but found $rowCount"); - } - } + /** + * Verify that the tableNode contains expected number of columns + * + * @param TableNode $table + * @param int $count + * + * @return void + * + * @throws Exception + */ + public function verifyTableNodeColumnsCount( + TableNode $table, + int $count + ): void { + if (\count($table->getRows()) < 1) { + throw new Exception("Table should have at least one row."); + } + $rowCount = \count($table->getRows()[0]); + if ($count !== $rowCount) { + throw new Exception("Table expected to have $count rows but found $rowCount"); + } + } - /** - * parses a PROPFIND response from $this->response into xml - * and returns found search results if found else returns false - * - * @param string|null $entryNameToSearch - * - * @return array - * string if $entryNameToSearch is given and is found - * array if $entryNameToSearch is not given - * boolean false if $entryNameToSearch is given and is not found - */ - public function findEntryFromPropfindResponse( - string $entryNameToSearch = null - ): array { - $spaceId = $this->getResponseSpaceId(); - //if we are using that step the second time in a scenario e.g. 'But ... should not' - //then don't parse the result again, because the result in a ResponseInterface - if (empty($this->getResponseXml())) { - $this->setResponseXml( - HttpRequestHelper::parseResponseAsXml($this->featureContext->getResponse()) - ); - } - Assert::assertNotEmpty($this->getResponseXml(), __METHOD__ . ' Response is empty'); - Assert::assertNotEmpty($spaceId, __METHOD__ . ' SpaceId is empty'); + /** + * parses a PROPFIND response from $this->response into xml + * and returns found search results if found else returns false + * + * @param string|null $entryNameToSearch + * + * @return array + * string if $entryNameToSearch is given and is found + * array if $entryNameToSearch is not given + * boolean false if $entryNameToSearch is given and is not found + */ + public function findEntryFromPropfindResponse( + string $entryNameToSearch = null + ): array { + $spaceId = $this->getResponseSpaceId(); + //if we are using that step the second time in a scenario e.g. 'But ... should not' + //then don't parse the result again, because the result in a ResponseInterface + if (empty($this->getResponseXml())) { + $this->setResponseXml( + HttpRequestHelper::parseResponseAsXml($this->featureContext->getResponse()) + ); + } + Assert::assertNotEmpty($this->getResponseXml(), __METHOD__ . ' Response is empty'); + Assert::assertNotEmpty($spaceId, __METHOD__ . ' SpaceId is empty'); - // trim any leading "/" passed by the caller, we can just match the "raw" name - $trimmedEntryNameToSearch = \trim($entryNameToSearch, "/"); + // trim any leading "/" passed by the caller, we can just match the "raw" name + $trimmedEntryNameToSearch = \trim($entryNameToSearch, "/"); - // topWebDavPath should be something like /remote.php/webdav/ or - // /remote.php/dav/files/alice/ - $topWebDavPath = "/" . "dav/spaces/" . $spaceId . "/"; + // topWebDavPath should be something like /remote.php/webdav/ or + // /remote.php/dav/files/alice/ + $topWebDavPath = "/" . "dav/spaces/" . $spaceId . "/"; - Assert::assertIsArray( - $this->responseXml, - __METHOD__ . " responseXml for space $spaceId is not an array" - ); - Assert::assertArrayHasKey( - "value", - $this->responseXml, - __METHOD__ . " responseXml for space $spaceId does not have key 'value'" - ); - $multistatusResults = $this->responseXml["value"]; - $results = []; - if ($multistatusResults !== null) { - foreach ($multistatusResults as $multistatusResult) { - $entryPath = $multistatusResult['value'][0]['value']; - $entryName = \str_replace($topWebDavPath, "", $entryPath); - $entryName = \rawurldecode($entryName); - $entryName = \trim($entryName, "/"); - if ($trimmedEntryNameToSearch === $entryName) { - return $multistatusResult; - } - $results[] = $entryName; - } - } - if ($entryNameToSearch === null) { - return $results; - } - return []; - } + Assert::assertIsArray( + $this->responseXml, + __METHOD__ . " responseXml for space $spaceId is not an array" + ); + Assert::assertArrayHasKey( + "value", + $this->responseXml, + __METHOD__ . " responseXml for space $spaceId does not have key 'value'" + ); + $multistatusResults = $this->responseXml["value"]; + $results = []; + if ($multistatusResults !== null) { + foreach ($multistatusResults as $multistatusResult) { + $entryPath = $multistatusResult['value'][0]['value']; + $entryName = \str_replace($topWebDavPath, "", $entryPath); + $entryName = \rawurldecode($entryName); + $entryName = \trim($entryName, "/"); + if ($trimmedEntryNameToSearch === $entryName) { + return $multistatusResult; + } + $results[] = $entryName; + } + } + if ($entryNameToSearch === null) { + return $results; + } + return []; + } - /** - * @When /^user "([^"]*)" creates a folder "([^"]*)" in space "([^"]*)" using the WebDav Api$/ - * - * @param string $user - * @param string $folder - * @param string $spaceName - * - * @return void - * - * @throws GuzzleException - */ - public function theUserCreatesAFolderUsingTheGraphApi( - string $user, - string $folder, - string $spaceName - ): void { - $this->featureContext->setResponse( - $this->sendCreateFolderRequest( - $this->featureContext->getBaseUrl(), - "MKCOL", - $user, - $this->featureContext->getPasswordForUser($user), - $folder, - $spaceName - ) - ); - } + /** + * @When /^user "([^"]*)" creates a folder "([^"]*)" in space "([^"]*)" using the WebDav Api$/ + * + * @param string $user + * @param string $folder + * @param string $spaceName + * + * @return void + * + * @throws GuzzleException + */ + public function theUserCreatesAFolderUsingTheGraphApi( + string $user, + string $folder, + string $spaceName + ): void { + $this->featureContext->setResponse( + $this->sendCreateFolderRequest( + $this->featureContext->getBaseUrl(), + "MKCOL", + $user, + $this->featureContext->getPasswordForUser($user), + $folder, + $spaceName + ) + ); + } - /** - * @When /^user "([^"]*)" uploads a file inside space "([^"]*)" with content "([^"]*)" to "([^"]*)" using the WebDAV API$/ - * - * @param string $user - * @param string $spaceName - * @param string $content - * @param string $destination - * - * @return void - * @throws GuzzleException - * @throws Exception - */ - public function theUserUploadsAFileToSpace( - string $user, - string $spaceName, - string $content, - string $destination - ): void - { - $space = $this->getSpaceByName($spaceName); - Assert::assertIsArray($space, "Space with name $spaceName not found"); - Assert::assertNotEmpty($space["root"]["webDavUrl"], "WebDavUrl for space with name $spaceName not found"); + /** + * @When /^user "([^"]*)" uploads a file inside space "([^"]*)" with content "([^"]*)" to "([^"]*)" using the WebDAV API$/ + * + * @param string $user + * @param string $spaceName + * @param string $content + * @param string $destination + * + * @return void + * @throws GuzzleException + * @throws Exception + */ + public function theUserUploadsAFileToSpace( + string $user, + string $spaceName, + string $content, + string $destination + ): void { + $space = $this->getSpaceByName($spaceName); + Assert::assertIsArray($space, "Space with name $spaceName not found"); + Assert::assertNotEmpty($space["root"]["webDavUrl"], "WebDavUrl for space with name $spaceName not found"); - $this->featureContext->setResponse( - $this->sendPutRequestToUrl( - $space["root"]["webDavUrl"] . "/" . $destination, - $user, - $this->featureContext->getPasswordForUser($user), - "", - [], - $content - ) - ); - } + $this->featureContext->setResponse( + $this->sendPutRequestToUrl( + $space["root"]["webDavUrl"] . "/" . $destination, + $user, + $this->featureContext->getPasswordForUser($user), + "", + [], + $content + ) + ); + } - /** - * Send Graph Create Folder Request - * - * @param string $baseUrl - * @param string $method - * @param string $user - * @param string $password - * @param string $folder - * @param string $spaceName - * @param string $xRequestId - * @param array $headers - * - * @return ResponseInterface - * - * @throws GuzzleException - */ - public function sendCreateFolderRequest( - string $baseUrl, - string $method, - string $user, - string $password, - string $folder, - string $spaceName, - string $xRequestId = '', - array $headers = [] - ): ResponseInterface { - $spaceId = $this->getAvailableSpaces()[$spaceName]["id"]; - $fullUrl = $baseUrl; - if (!str_ends_with($fullUrl, '/')) { - $fullUrl .= '/'; - } - $fullUrl .= "dav/spaces/" . $spaceId . '/' . $folder; + /** + * Send Graph Create Folder Request + * + * @param string $baseUrl + * @param string $method + * @param string $user + * @param string $password + * @param string $folder + * @param string $spaceName + * @param string $xRequestId + * @param array $headers + * + * @return ResponseInterface + * + * @throws GuzzleException + */ + public function sendCreateFolderRequest( + string $baseUrl, + string $method, + string $user, + string $password, + string $folder, + string $spaceName, + string $xRequestId = '', + array $headers = [] + ): ResponseInterface { + $spaceId = $this->getAvailableSpaces()[$spaceName]["id"]; + $fullUrl = $baseUrl; + if (!str_ends_with($fullUrl, '/')) { + $fullUrl .= '/'; + } + $fullUrl .= "dav/spaces/" . $spaceId . '/' . $folder; - return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, $method, $user, $password, $headers); - } + return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, $method, $user, $password, $headers); + } } From d732c40f624695f29d36cd860091a6a7e6b40d65 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Thu, 11 Nov 2021 12:19:54 +0545 Subject: [PATCH 13/15] Refactor spaces API tests --- .../features/apiSpaces/uploadSpaces.feature | 18 ++---- .../features/bootstrap/SpacesContext.php | 63 +++++++++++++++++-- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/tests/acceptance/features/apiSpaces/uploadSpaces.feature b/tests/acceptance/features/apiSpaces/uploadSpaces.feature index 721d5345a..4a0da5ea3 100644 --- a/tests/acceptance/features/apiSpaces/uploadSpaces.feature +++ b/tests/acceptance/features/apiSpaces/uploadSpaces.feature @@ -16,19 +16,16 @@ Feature: Upload files into a space And user "Alice" lists all available spaces via the GraphApi And user "Alice" creates a folder "mainFolder" in space "Project Venus" using the WebDav Api Then the HTTP status code should be "201" - When user "Alice" lists the content of the space with the name "Project Venus" using the WebDav Api - Then the propfind result of the space should contain these entries: + And the space "Project Venus" should contain these entries: | mainFolder | - Scenario: Bob creates a folder via the Graph api in a space, he expects a 404 code and - Alice checks that this folder does not exist + Scenario: Bob creates a folder via the Graph api in a space, he expects a 404 code and Alice checks that this folder does not exist Given the administrator gives "Alice" the role "Admin" using the settings api When user "Alice" creates a space "Project Merkur" of type "project" with quota "2000" using the GraphApi And user "Alice" lists all available spaces via the GraphApi And user "Bob" creates a folder "forAlice" in space "Project Merkur" using the WebDav Api Then the HTTP status code should be "404" - When user "Alice" lists the content of the space with the name "Project Merkur" using the WebDav Api - Then the propfind result of the space should not contain these entries: + And the space "Project Merkur" should not contain these entries: | forAlice | Scenario: Alice creates a folder via Graph api and uploads a file @@ -39,20 +36,17 @@ Feature: Upload files into a space Then the HTTP status code should be "201" And user "Alice" uploads a file inside space "Project Moon" with content "Test" to "test.txt" using the WebDAV API Then the HTTP status code should be "201" - When user "Alice" lists the content of the space with the name "Project Moon" using the WebDav Api - Then the propfind result of the space should contain these entries: + And the space "Project Moon" should contain these entries: | NewFolder | | test.txt | - Scenario: Bob uploads a file via the Graph api in a space, he expects a 404 code and - Alice checks that this file does not exist + Scenario: Bob uploads a file via the Graph api in a space, he expects a 404 code and Alice checks that this file does not exist Given the administrator gives "Alice" the role "Admin" using the settings api When user "Alice" creates a space "Project Pluto" of type "project" with quota "2000" using the GraphApi And user "Alice" lists all available spaces via the GraphApi And user "Bob" uploads a file inside space "Project Pluto" with content "Test" to "test.txt" using the WebDAV API Then the HTTP status code should be "404" - When user "Alice" lists the content of the space with the name "Project Pluto" using the WebDav Api - Then the propfind result of the space should not contain these entries: + And the space "Project Pluto" should not contain these entries: | test.txt | Scenario: Alice creates uploads a file and checks her quota diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 1e2774738..1731d74ec 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -20,7 +20,6 @@ * */ use Behat\Behat\Context\Context; -use Behat\Behat\Hook\Scope\AfterScenarioScope; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Exception\GuzzleException; @@ -41,6 +40,34 @@ class SpacesContext implements Context { */ private FeatureContext $featureContext; + /** + * @var array key is space name and value is the username that created the space + */ + private array $createdSpaces; + + /** + * @param string $spaceName + * + * @return string name of the user that created the space + * @throws Exception + */ + public function getSpaceCreator(string $spaceName): string { + if (!\array_key_exists($spaceName, $this->createdSpaces)) { + throw new Exception(__METHOD__ . " space '$spaceName' has not been created in this scenario"); + } + return $this->createdSpaces[$spaceName]; + } + + /** + * @param string $spaceName + * @param string $spaceCreator + * + * @return void + */ + public function setSpaceCreator(string $spaceName, string $spaceCreator): void { + $this->createdSpaces[$spaceName] = $spaceCreator; + } + /** * @var array */ @@ -344,6 +371,7 @@ class SpacesContext implements Context { "" ) ); + $this->setSpaceCreator($spaceName, $user); } /** @@ -376,6 +404,7 @@ class SpacesContext implements Context { "" ) ); + $this->setSpaceCreator($spaceName, $user); } /** @@ -480,7 +509,7 @@ class SpacesContext implements Context { * @When /^user "([^"]*)" lists the content of the space with the name "([^"]*)" using the WebDav Api$/ * * @param string $user - * @param string $name + * @param string $spaceName * * @return void * @@ -488,9 +517,9 @@ class SpacesContext implements Context { */ public function theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( string $user, - string $name + string $spaceName ): void { - $space = $this->getSpaceByName($name); + $space = $this->getSpaceByName($spaceName); Assert::assertIsArray($space); Assert::assertNotEmpty($spaceId = $space["id"]); Assert::assertNotEmpty($spaceWebDavUrl = $space["root"]["webDavUrl"]); @@ -529,6 +558,32 @@ class SpacesContext implements Context { ); } + /** + * @Then /^the space "([^"]*)" should (not|)\s?contain these (?:files|entries):$/ + * + * @param string $spaceName + * @param string $shouldOrNot (not|) + * @param TableNode $expectedFiles + * + * @return void + * + * @throws Exception|GuzzleException + */ + public function theSpaceShouldContainEntries( + string $spaceName, + string $shouldOrNot, + TableNode $expectedFiles + ):void { + $this->theUserListsTheContentOfAPersonalSpaceRootUsingTheWebDAvApi( + $this->getSpaceCreator($spaceName), + $spaceName + ); + $this->propfindResultShouldContainEntries( + $shouldOrNot, + $expectedFiles, + ); + } + /** * @Then /^the json responded should contain a space "([^"]*)" with these key and value pairs:$/ * From f056d6c79ee1427b6067973702bbbc04ec0e1442 Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 12:45:52 +0545 Subject: [PATCH 14/15] [tests-only] test downloading a file as not owner --- .../features/apiArchiver/downloadById.feature | 7 +++++ .../features/bootstrap/ArchiverContext.php | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/acceptance/features/apiArchiver/downloadById.feature b/tests/acceptance/features/apiArchiver/downloadById.feature index 355783f62..fe46f6a9c 100644 --- a/tests/acceptance/features/apiArchiver/downloadById.feature +++ b/tests/acceptance/features/apiArchiver/downloadById.feature @@ -61,3 +61,10 @@ Feature: download multiple resources bundled into an archive | textfile1.txt | other data | | my_data/textfile2.txt | some data | | more_data/an_other_file.txt | more data | + + Scenario: download a single file as different user + Given user "Brian" has been created with default attributes and without skeleton files + And user "Alice" has uploaded file with content "some data" to "/textfile0.txt" + When user "Brian" downloads the archive of "/textfile0.txt" of user "Alice" using the resource id + Then the HTTP status code should be "400" + diff --git a/tests/acceptance/features/bootstrap/ArchiverContext.php b/tests/acceptance/features/bootstrap/ArchiverContext.php index 4202c26b6..f2c5f9ed9 100644 --- a/tests/acceptance/features/bootstrap/ArchiverContext.php +++ b/tests/acceptance/features/bootstrap/ArchiverContext.php @@ -99,6 +99,34 @@ class ArchiverContext implements Context { ); } + /** + * @When user :downloader downloads the archive of :item of user :owner using the resource id + * + * @param string $downloader Who sends the request + * @param string $resource + * @param string $owner Who is the real owner of the file + * + * @return void + * + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function userDownloadsTheArchiveOfItemOfUserUsingTheResourceId( + string $downloader, + string $resource, + string $owner + ): void { + $resourceId = $this->featureContext->getFileIdForPath($owner, $resource); + $downloader = $this->featureContext->getActualUsername($downloader); + $this->featureContext->setResponse( + HttpRequestHelper::get( + $this->featureContext->getBaseUrl() . '/archiver?id=' . $resourceId, + '', + $downloader, + $this->featureContext->getPasswordForUser($downloader), + ) + ); + } + /** * @When user :arg1 downloads the archive of these items using the resource ids * From 67441a7877e48ca1d983d5fec35d262ee6ee375f Mon Sep 17 00:00:00 2001 From: Artur Neumann Date: Thu, 11 Nov 2021 14:39:22 +0545 Subject: [PATCH 15/15] [tests-only] test archiver endpoint with shares --- .drone.star | 1 + ...ected-failures-localAPI-on-OCIS-storage.md | 5 ++ .../features/apiArchiver/downloadById.feature | 65 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md diff --git a/.drone.star b/.drone.star index e591646d7..f6dda6c54 100644 --- a/.drone.star +++ b/.drone.star @@ -453,6 +453,7 @@ def localApiTests(ctx, storage, suite, accounts_hash_difficulty = 4): "BEHAT_SUITE": suite, "BEHAT_FILTER_TAGS": "~@skip&&~@skipOnOcis-%s-Storage" % ("OC" if storage == "owncloud" else "OCIS"), "PATH_TO_CORE": "/srv/app/testrunner", + "EXPECTED_FAILURES_FILE": "/drone/src/tests/acceptance/expected-failures-localAPI-on-%s-storage.md" % (storage.upper()), "UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0, }, "commands": [ diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md new file mode 100644 index 000000000..a8a479882 --- /dev/null +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -0,0 +1,5 @@ +## Scenarios from OCIS API tests that are expected to fail with OCIS storage + +#### [downloading the /Shares folder using the archiver endpoint does not work](https://github.com/owncloud/ocis/issues/2751) +- [apiArchiver/downloadById.feature:134](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L134) +- [apiArchiver/downloadById.feature:135](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiArchiver/downloadById.feature#L135) diff --git a/tests/acceptance/features/apiArchiver/downloadById.feature b/tests/acceptance/features/apiArchiver/downloadById.feature index fe46f6a9c..518241951 100644 --- a/tests/acceptance/features/apiArchiver/downloadById.feature +++ b/tests/acceptance/features/apiArchiver/downloadById.feature @@ -11,6 +11,7 @@ Feature: download multiple resources bundled into an archive Background: Given user "Alice" has been created with default attributes and without skeleton files + Scenario Outline: download a single file Given user "Alice" has uploaded file with content "some data" to "/textfile0.txt" When user "Alice" downloads the archive of "/textfile0.txt" using the resource id and setting these headers @@ -25,6 +26,7 @@ Feature: download multiple resources bundled into an archive | Linux | tar | | Windows NT | zip | + Scenario Outline: download a single folder Given user "Alice" has created folder "my_data" And user "Alice" has uploaded file with content "some data" to "/my_data/textfile0.txt" @@ -42,6 +44,7 @@ Feature: download multiple resources bundled into an archive | Linux | tar | | Windows NT | zip | + Scenario: download multiple files and folders Given user "Alice" has uploaded file with content "some data" to "/textfile0.txt" And user "Alice" has uploaded file with content "other data" to "/textfile1.txt" @@ -62,9 +65,71 @@ Feature: download multiple resources bundled into an archive | my_data/textfile2.txt | some data | | more_data/an_other_file.txt | more data | + Scenario: download a single file as different user Given user "Brian" has been created with default attributes and without skeleton files And user "Alice" has uploaded file with content "some data" to "/textfile0.txt" When user "Brian" downloads the archive of "/textfile0.txt" of user "Alice" using the resource id Then the HTTP status code should be "400" + + Scenario: download multiple shared items as share receiver + Given user "Brian" has been created with default attributes and without skeleton files + And user "Alice" has uploaded file with content "some data" to "/textfile0.txt" + And user "Alice" has uploaded file with content "other data" to "/textfile1.txt" + And user "Alice" has created folder "my_data" + And user "Alice" has uploaded file with content "some data" to "/my_data/textfile2.txt" + And user "Alice" has created folder "more_data" + And user "Alice" has uploaded file with content "more data" to "/more_data/an_other_file.txt" + And user "Alice" has shared file "textfile0.txt" with user "Brian" + And user "Alice" has shared file "textfile1.txt" with user "Brian" + And user "Alice" has shared folder "my_data" with user "Brian" + And user "Alice" has shared folder "more_data" with user "Brian" + And user "Brian" has accepted share "/textfile0.txt" offered by user "Alice" + And user "Brian" has accepted share "/textfile1.txt" offered by user "Alice" + And user "Brian" has accepted share "/my_data" offered by user "Alice" + And user "Brian" has accepted share "/more_data" offered by user "Alice" + When user "Brian" downloads the archive of these items using the resource ids + | /Shares/textfile0.txt | + | /Shares/textfile1.txt | + | /Shares/my_data | + | /Shares/more_data | + Then the HTTP status code should be "200" + And the downloaded tar archive should contain these files: + | name | content | + | textfile0.txt | some data | + | textfile1.txt | other data | + | my_data/textfile2.txt | some data | + | more_data/an_other_file.txt | more data | + + + Scenario Outline: download the Shares folder as share receiver + Given user "Brian" has been created with default attributes and without skeleton files + And user "Alice" has uploaded file with content "some data" to "/textfile0.txt" + And user "Alice" has uploaded file with content "other data" to "/textfile1.txt" + And user "Alice" has created folder "my_data" + And user "Alice" has uploaded file with content "some data" to "/my_data/textfile2.txt" + And user "Alice" has created folder "more_data" + And user "Alice" has uploaded file with content "more data" to "/more_data/an_other_file.txt" + And user "Alice" has shared file "textfile0.txt" with user "Brian" + And user "Alice" has shared file "textfile1.txt" with user "Brian" + And user "Alice" has shared folder "my_data" with user "Brian" + And user "Alice" has shared folder "more_data" with user "Brian" + And user "Brian" has accepted share "/textfile0.txt" offered by user "Alice" + And user "Brian" has accepted share "/textfile1.txt" offered by user "Alice" + And user "Brian" has accepted share "/my_data" offered by user "Alice" + And user "Brian" has accepted share "/more_data" offered by user "Alice" + When user "Brian" downloads the archive of "/Shares" using the resource id and setting these headers + | header | value | + | User-Agent | | + Then the HTTP status code should be "200" + And the downloaded archive should contain these files: + | name | content | + | Shares/textfile0.txt | some data | + | Shares/textfile1.txt | other data | + | Shares/my_data/textfile0.txt | some data | + | Shares/my_data/an_other_file.txt | more data | + Examples: + | user-agent | archive-type | + | Linux | tar | + | Windows NT | zip |