diff --git a/.woodpecker.star b/.woodpecker.star index da42044c1c..d3cb7e5fee 100644 --- a/.woodpecker.star +++ b/.woodpecker.star @@ -318,6 +318,7 @@ config = { "USE_PREPARED_LDAP_USERS": True, }, "extraServerEnvironment": { + "OC_MULTI_TENANT_ENABLED": True, "OC_LDAP_USER_SCHEMA_TENANT_ID": "departmentNumber", "OC_LDAP_URI": "ldaps://ldap-server:1636", "OC_LDAP_INSECURE": True, diff --git a/pkg/shared/shared_types.go b/pkg/shared/shared_types.go index fe0b441f10..2fbc4f7cdc 100644 --- a/pkg/shared/shared_types.go +++ b/pkg/shared/shared_types.go @@ -69,20 +69,21 @@ type Cache struct { // Commons holds configuration that are common to all extensions. Each extension can then decide whether // to overwrite its values. type Commons struct { - Log *Log `yaml:"log"` - Tracing *Tracing `yaml:"tracing"` - Cache *Cache `yaml:"cache"` - GRPCClientTLS *GRPCClientTLS `yaml:"grpc_client_tls"` - GRPCServiceTLS *GRPCServiceTLS `yaml:"grpc_service_tls"` - HTTPServiceTLS HTTPServiceTLS `yaml:"http_service_tls"` - OpenCloudURL string `yaml:"opencloud_url" env:"OC_URL" desc:"URL, where OpenCloud is reachable for users." introductionVersion:"1.0.0"` - TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` - Reva *Reva `yaml:"reva"` - MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services." introductionVersion:"1.0.0"` - TransferSecret string `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET" desc:"The secret used for signing the requests towards the data gateway for up- and downloads." introductionVersion:"1.0.0"` - SystemUserID string `yaml:"system_user_id" env:"OC_SYSTEM_USER_ID" desc:"ID of the OpenCloud storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format." introductionVersion:"1.0.0"` - SystemUserAPIKey string `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY" desc:"API key for all system users." introductionVersion:"1.0.0"` - AdminUserID string `yaml:"admin_user_id" env:"OC_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges. Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand." introductionVersion:"1.0.0"` + Log *Log `yaml:"log"` + Tracing *Tracing `yaml:"tracing"` + Cache *Cache `yaml:"cache"` + GRPCClientTLS *GRPCClientTLS `yaml:"grpc_client_tls"` + GRPCServiceTLS *GRPCServiceTLS `yaml:"grpc_service_tls"` + HTTPServiceTLS HTTPServiceTLS `yaml:"http_service_tls"` + OpenCloudURL string `yaml:"opencloud_url" env:"OC_URL" desc:"URL, where OpenCloud is reachable for users." introductionVersion:"1.0.0"` + TokenManager *TokenManager `mask:"struct" yaml:"token_manager"` + Reva *Reva `yaml:"reva"` + MachineAuthAPIKey string `mask:"password" yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services." introductionVersion:"1.0.0"` + TransferSecret string `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET" desc:"The secret used for signing the requests towards the data gateway for up- and downloads." introductionVersion:"1.0.0"` + SystemUserID string `yaml:"system_user_id" env:"OC_SYSTEM_USER_ID" desc:"ID of the OpenCloud storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format." introductionVersion:"1.0.0"` + SystemUserAPIKey string `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY" desc:"API key for all system users." introductionVersion:"1.0.0"` + AdminUserID string `yaml:"admin_user_id" env:"OC_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges. Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand." introductionVersion:"1.0.0"` + MultiTenantEnabled bool `yaml:"multi_tenant_enabled" env:"OC_MULTI_TENANT_ENABLED" desc:"Set this to true to enable multi-tenant support." introductionVersion:"%%NEXT%%"` // NOTE: you will not fing GRPCMaxReceivedMessageSize size being used in the code. The envvar is actually extracted in revas `pool` package: https://github.com/cs3org/reva/blob/edge/pkg/rgrpc/todo/pool/connection.go // It is mentioned here again so it is documented diff --git a/services/graph/pkg/config/parser/parse.go b/services/graph/pkg/config/parser/parse.go index 0e63ec6cf6..7223df0089 100644 --- a/services/graph/pkg/config/parser/parse.go +++ b/services/graph/pkg/config/parser/parse.go @@ -42,6 +42,10 @@ func Validate(cfg *config.Config) error { return shared.MissingJWTTokenError(cfg.Service.Name) } + // ensure that the "cs3" identity backend is used in multi-tenant setups + if cfg.Commons.MultiTenantEnabled && cfg.Identity.Backend != "cs3" { + return fmt.Errorf("Multi-tenant support is enabled. The identity backend must be set to 'cs3' for the 'graph' service.") + } if cfg.Identity.Backend == "ldap" { if err := validateLDAPSettings(cfg); err != nil { return err diff --git a/services/graph/pkg/config/parser/parse_test.go b/services/graph/pkg/config/parser/parse_test.go new file mode 100644 index 0000000000..0d0ee61ed6 --- /dev/null +++ b/services/graph/pkg/config/parser/parse_test.go @@ -0,0 +1,63 @@ +package parser_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/opencloud-eu/opencloud/pkg/shared" + "github.com/opencloud-eu/opencloud/services/graph/pkg/config" + "github.com/opencloud-eu/opencloud/services/graph/pkg/config/defaults" + "github.com/opencloud-eu/opencloud/services/graph/pkg/config/parser" +) + +var _ = Describe("Validate", func() { + var cfg *config.Config + + BeforeEach(func() { + cfg = defaults.DefaultConfig() + cfg.Application.ID = "graph-app-id" + cfg.ServiceAccount.ServiceAccountID = "graph-service-account" + cfg.ServiceAccount.ServiceAccountSecret = "graph-service-password" + cfg.Commons = &shared.Commons{ + TokenManager: &shared.TokenManager{ + JWTSecret: "jwt-secret", + }, + } + defaults.EnsureDefaults(cfg) + }) + + When("multi-tenant support is disabled", func() { + It("should accept a setup with the 'cs3' identity backend", func() { + cfg.Identity.Backend = "cs3" + err := parser.Validate(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + It("should accept a setup with the 'ldap' identity backend", func() { + cfg.Identity.Backend = "ldap" + // we need to set a password to pass validation + cfg.Identity.LDAP.BindPassword = "bind-password" + err := parser.Validate(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + }) + + When("multi-tenant support is disabled", func() { + BeforeEach(func() { + cfg.Commons.MultiTenantEnabled = true + }) + It("should accept a setup with the 'cs3' identity backend", func() { + cfg.Identity.Backend = "cs3" + err := parser.Validate(cfg) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should reject a setup with the 'ldap' identity backend", func() { + cfg.Identity.Backend = "ldap" + cfg.Identity.LDAP.BindPassword = "bind-password" + err := parser.Validate(cfg) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(ContainSubstring("The identity backend must be set to 'cs3' for the 'graph' service."))) + }) + }) + +}) diff --git a/services/graph/pkg/config/parser/parser_suite_test.go b/services/graph/pkg/config/parser/parser_suite_test.go new file mode 100644 index 0000000000..16e466dffb --- /dev/null +++ b/services/graph/pkg/config/parser/parser_suite_test.go @@ -0,0 +1,13 @@ +package parser_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestParser(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Parser Suite") +}