From 7ef205d2320d1e5a1afa4a8c79e65325810fe9b2 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Tue, 3 May 2022 12:31:53 +0200 Subject: [PATCH] Get rid of hardcoded admin user uuid The UUID is generated by `ocs init` now and stored in the config file. To avoid that every ocis install uses the same UUID Closes: #3524 --- .drone.star | 2 +- changelog/unreleased/change-ocis-init.md | 6 ++++-- extensions/idm/ldif/base.ldif.tmpl | 2 +- extensions/idm/pkg/command/server.go | 2 ++ extensions/idm/pkg/config/parser/parse.go | 5 +++++ extensions/settings/pkg/config/parser/parse.go | 4 ++++ extensions/settings/pkg/service/v0/service.go | 2 +- extensions/settings/pkg/service/v0/settings.go | 4 ++-- extensions/settings/pkg/store/defaults/defaults.go | 5 +++-- extensions/settings/pkg/store/metadata/assignments.go | 6 +++--- .../settings/pkg/store/metadata/assignments_test.go | 8 +++++++- extensions/settings/pkg/store/metadata/store.go | 2 +- ocis-pkg/config/config.go | 1 + ocis-pkg/config/parser/parse.go | 5 +++++ ocis-pkg/shared/errors.go | 8 ++++++++ ocis-pkg/shared/shared_types.go | 1 + ocis/pkg/init/init.go | 3 +++ 17 files changed, 52 insertions(+), 14 deletions(-) diff --git a/.drone.star b/.drone.star index 5781862821e..13366709172 100644 --- a/.drone.star +++ b/.drone.star @@ -1660,7 +1660,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = "name": "wait-for-ocis-server", "image": OC_CI_ALPINE, "commands": [ - "curl -k -u admin:admin --fail --retry-connrefused --retry 10 --retry-all-errors 'https://ocis-server:9200/graph/v1.0/users/ddc2004c-0977-11eb-9d3f-a793888cd0f8'", + "curl -k -u admin:admin --fail --retry-connrefused --retry 10 --retry-all-errors 'https://ocis-server:9200/graph/v1.0/users/admin'", ], "depends_on": depends_on, } diff --git a/changelog/unreleased/change-ocis-init.md b/changelog/unreleased/change-ocis-init.md index a4a81eb3854..9c029b1f623 100644 --- a/changelog/unreleased/change-ocis-init.md +++ b/changelog/unreleased/change-ocis-init.md @@ -1,10 +1,12 @@ Change: Introduce `ocis init` and remove all default secrets -We've removed all default secrets. This means you can't start oCIS any longer -without setting these via environment variable or configuration file. +We've removed all default secrets and the hardcoded UUID of the user `admin`. +This means you can't start oCIS any longer without setting these via +environment variable or configuration file. In order to make this easy for you, we introduced a new command: `ocis init`. You can run this command before starting oCIS with `ocis server` and it will bootstrap you a configuration file for a secure oCIS instance. https://github.com/owncloud/ocis/pull/3551 +https://github.com/owncloud/ocis/issues/3524 diff --git a/extensions/idm/ldif/base.ldif.tmpl b/extensions/idm/ldif/base.ldif.tmpl index e29221c62f8..6e1b9c2059b 100644 --- a/extensions/idm/ldif/base.ldif.tmpl +++ b/extensions/idm/ldif/base.ldif.tmpl @@ -29,7 +29,7 @@ cn: admin displayName: Admin description: An admin for this oCIS instance. mail: admin@example.org -ownCloudUUID: ddc2004c-0977-11eb-9d3f-a793888cd0f8 +ownCloudUUID: {{ .ID }} {{ else -}} dn: uid={{ .Name }},ou=sysusers,o=libregraph-idm objectClass: account diff --git a/extensions/idm/pkg/command/server.go b/extensions/idm/pkg/command/server.go index 90f399dfa93..6286cd1f128 100644 --- a/extensions/idm/pkg/command/server.go +++ b/extensions/idm/pkg/command/server.go @@ -90,12 +90,14 @@ func bootstrap(logger log.Logger, cfg *config.Config, srvcfg server.Config) erro type svcUser struct { Name string Password string + ID string } serviceUsers := []svcUser{ { Name: "admin", Password: cfg.ServiceUserPasswords.OcisAdmin, + ID: cfg.Commons.AdminUserID, }, { Name: "libregraph", diff --git a/extensions/idm/pkg/config/parser/parse.go b/extensions/idm/pkg/config/parser/parse.go index 7d04c55ad4d..9fe4a856657 100644 --- a/extensions/idm/pkg/config/parser/parse.go +++ b/extensions/idm/pkg/config/parser/parse.go @@ -33,6 +33,10 @@ func ParseConfig(cfg *config.Config) error { } func Validate(cfg *config.Config) error { + if cfg.AdminUserID == "" { + return shared.MissingAdminUserID(cfg.Service.Name) + } + if cfg.ServiceUserPasswords.Idm == "" { return shared.MissingServiceUserPassword(cfg.Service.Name, "IDM") } @@ -44,6 +48,7 @@ func Validate(cfg *config.Config) error { if cfg.ServiceUserPasswords.Idp == "" { return shared.MissingServiceUserPassword(cfg.Service.Name, "IDP") } + if cfg.ServiceUserPasswords.Reva == "" { return shared.MissingServiceUserPassword(cfg.Service.Name, "REVA") } diff --git a/extensions/settings/pkg/config/parser/parse.go b/extensions/settings/pkg/config/parser/parse.go index b59d8ee9fd1..5fa45bac680 100644 --- a/extensions/settings/pkg/config/parser/parse.go +++ b/extensions/settings/pkg/config/parser/parse.go @@ -41,5 +41,9 @@ func Validate(cfg *config.Config) error { return shared.MissingMachineAuthApiKeyError(cfg.Service.Name) } + if cfg.AdminUserID == "" { + return shared.MissingAdminUserID(cfg.Service.Name) + } + return nil } diff --git a/extensions/settings/pkg/service/v0/service.go b/extensions/settings/pkg/service/v0/service.go index 213151e9d74..ee3ced9b4e5 100644 --- a/extensions/settings/pkg/service/v0/service.go +++ b/extensions/settings/pkg/service/v0/service.go @@ -126,7 +126,7 @@ func (g Service) RegisterDefaultRoles() { } } - for _, req := range defaultRoleAssignments() { + for _, req := range g.defaultRoleAssignments() { if _, err := g.manager.WriteRoleAssignment(req.AccountUuid, req.RoleId); err != nil { g.logger.Error().Err(err).Msg("failed to register role assignment") } diff --git a/extensions/settings/pkg/service/v0/settings.go b/extensions/settings/pkg/service/v0/settings.go index f28ef661336..04b481c782f 100644 --- a/extensions/settings/pkg/service/v0/settings.go +++ b/extensions/settings/pkg/service/v0/settings.go @@ -532,14 +532,14 @@ func generatePermissionRequests() []*settingssvc.AddSettingToBundleRequest { } } -func defaultRoleAssignments() []*settingsmsg.UserRoleAssignment { +func (g Service) defaultRoleAssignments() []*settingsmsg.UserRoleAssignment { return []*settingsmsg.UserRoleAssignment{ // default admin users { AccountUuid: "058bff95-6708-4fe5-91e4-9ea3d377588b", // demo user "moss" RoleId: BundleUUIDRoleAdmin, }, { - AccountUuid: "ddc2004c-0977-11eb-9d3f-a793888cd0f8", + AccountUuid: g.config.Commons.AdminUserID, RoleId: BundleUUIDRoleAdmin, }, // default users with role "user" diff --git a/extensions/settings/pkg/store/defaults/defaults.go b/extensions/settings/pkg/store/defaults/defaults.go index 6d5f4883edf..2b3e94435fb 100644 --- a/extensions/settings/pkg/store/defaults/defaults.go +++ b/extensions/settings/pkg/store/defaults/defaults.go @@ -1,6 +1,7 @@ package defaults import ( + "github.com/owncloud/ocis/extensions/settings/pkg/config" settingsmsg "github.com/owncloud/ocis/protogen/gen/ocis/messages/settings/v0" ) @@ -496,14 +497,14 @@ var languageSetting = settingsmsg.Setting_SingleChoiceValue{ } // DefaultRoleAssignments returns (as one might guess) the default role assignments -func DefaultRoleAssignments() []*settingsmsg.UserRoleAssignment { +func DefaultRoleAssignments(cfg *config.Config) []*settingsmsg.UserRoleAssignment { return []*settingsmsg.UserRoleAssignment{ // default admin users { AccountUuid: "058bff95-6708-4fe5-91e4-9ea3d377588b", // demo user "moss" RoleId: BundleUUIDRoleAdmin, }, { - AccountUuid: "ddc2004c-0977-11eb-9d3f-a793888cd0f8", + AccountUuid: cfg.Commons.AdminUserID, RoleId: BundleUUIDRoleAdmin, }, // default users with role "user" diff --git a/extensions/settings/pkg/store/metadata/assignments.go b/extensions/settings/pkg/store/metadata/assignments.go index 88ce7e1c18b..63c7b31121e 100644 --- a/extensions/settings/pkg/store/metadata/assignments.go +++ b/extensions/settings/pkg/store/metadata/assignments.go @@ -14,7 +14,7 @@ import ( // ListRoleAssignments loads and returns all role assignments matching the given assignment identifier. func (s *Store) ListRoleAssignments(accountUUID string) ([]*settingsmsg.UserRoleAssignment, error) { if s.mdc == nil { - return defaultRoleAssignments(accountUUID), nil + return s.defaultRoleAssignments(accountUUID), nil } s.Init() ctx := context.TODO() @@ -92,9 +92,9 @@ func (s *Store) RemoveRoleAssignment(assignmentID string) error { return fmt.Errorf("assignmentID '%s' not found", assignmentID) } -func defaultRoleAssignments(accID string) []*settingsmsg.UserRoleAssignment { +func (s *Store) defaultRoleAssignments(accID string) []*settingsmsg.UserRoleAssignment { var assmnts []*settingsmsg.UserRoleAssignment - for _, r := range defaults.DefaultRoleAssignments() { + for _, r := range defaults.DefaultRoleAssignments(s.cfg) { if r.AccountUuid == accID { assmnts = append(assmnts, r) } diff --git a/extensions/settings/pkg/store/metadata/assignments_test.go b/extensions/settings/pkg/store/metadata/assignments_test.go index 2111366e31f..62b0b43682c 100644 --- a/extensions/settings/pkg/store/metadata/assignments_test.go +++ b/extensions/settings/pkg/store/metadata/assignments_test.go @@ -5,8 +5,10 @@ import ( "sync" "testing" + "github.com/gofrs/uuid" "github.com/owncloud/ocis/extensions/settings/pkg/config/defaults" olog "github.com/owncloud/ocis/ocis-pkg/log" + "github.com/owncloud/ocis/ocis-pkg/shared" settingsmsg "github.com/owncloud/ocis/protogen/gen/ocis/messages/settings/v0" "github.com/stretchr/testify/require" ) @@ -18,7 +20,6 @@ var ( s = &Store{ Logger: logger, l: &sync.Mutex{}, - cfg: defaults.DefaultConfig(), } logger = olog.NewLogger( @@ -89,6 +90,11 @@ var ( ) func init() { + s.cfg = defaults.DefaultConfig() + s.cfg.Commons = &shared.Commons{ + AdminUserID: uuid.Must(uuid.NewV4()).String(), + } + _ = NewMDC(s) setupRoles() } diff --git a/extensions/settings/pkg/store/metadata/store.go b/extensions/settings/pkg/store/metadata/store.go index c98615559a7..e9d8739dd35 100644 --- a/extensions/settings/pkg/store/metadata/store.go +++ b/extensions/settings/pkg/store/metadata/store.go @@ -123,7 +123,7 @@ func (s *Store) initMetadataClient(mdc MetadataClient) error { } } - for _, p := range defaults.DefaultRoleAssignments() { + for _, p := range defaults.DefaultRoleAssignments(s.cfg) { accountUUID := p.AccountUuid roleID := p.RoleId err = mdc.MakeDirIfNotExist(ctx, accountPath(accountUUID)) diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go index 24feb82ac2a..7c9b2a477b4 100644 --- a/ocis-pkg/config/config.go +++ b/ocis-pkg/config/config.go @@ -70,6 +70,7 @@ type Config struct { MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY"` TransferSecret string `yaml:"transfer_secret" env:"STORAGE_TRANSFER_SECRET"` SystemUserID string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID"` + AdminUserID string `yaml:"admin_user_id" env:"ADMIN_USER_ID"` Runtime Runtime `yaml:"runtime"` Accounts *accounts.Config `yaml:"accounts"` diff --git a/ocis-pkg/config/parser/parse.go b/ocis-pkg/config/parser/parse.go index 9df81ab3890..e1ba596646d 100644 --- a/ocis-pkg/config/parser/parse.go +++ b/ocis-pkg/config/parser/parse.go @@ -98,6 +98,11 @@ func EnsureCommons(cfg *config.Config) { if cfg.SystemUserID != "" { cfg.Commons.SystemUserID = cfg.SystemUserID } + + // copy admin user id to the commons part if set + if cfg.AdminUserID != "" { + cfg.Commons.AdminUserID = cfg.AdminUserID + } } func Validate(cfg *config.Config) error { diff --git a/ocis-pkg/shared/errors.go b/ocis-pkg/shared/errors.go index c0815c35cc4..394407bba40 100644 --- a/ocis-pkg/shared/errors.go +++ b/ocis-pkg/shared/errors.go @@ -53,3 +53,11 @@ func MissingSystemUserID(service string) error { "the config/corresponding environment variable).", service, defaults.BaseConfigPath()) } + +func MissingAdminUserID(service string) error { + return fmt.Errorf("The admin user ID has not been configured for %s. "+ + "Make sure your %s config contains the proper values "+ + "(e.g. by running ocis init or setting it manually in "+ + "the config/corresponding environment variable).", + service, defaults.BaseConfigPath()) +} diff --git a/ocis-pkg/shared/shared_types.go b/ocis-pkg/shared/shared_types.go index a92f0f4c9af..cdaa5327448 100644 --- a/ocis-pkg/shared/shared_types.go +++ b/ocis-pkg/shared/shared_types.go @@ -45,4 +45,5 @@ type Commons struct { MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY"` TransferSecret string `yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET"` SystemUserID string `yaml:"system_user_id" env:"OCIS_SYSTEM_USER_ID"` + AdminUserID string `yaml:"admin_user_id" env:"ADMIN_USER_ID"` } diff --git a/ocis/pkg/init/init.go b/ocis/pkg/init/init.go index aa961a51d6b..b88acc580dc 100644 --- a/ocis/pkg/init/init.go +++ b/ocis/pkg/init/init.go @@ -100,6 +100,7 @@ type OcisConfig struct { MachineAuthApiKey string `yaml:"machine_auth_api_key"` TransferSecret string `yaml:"transfer_secret"` SystemUserID string `yaml:"system_user_id"` + AdminUserID string `yaml:"admin_user_id"` Graph GraphExtension Idp LdapBasedExtension Idm IdmExtension @@ -162,6 +163,7 @@ func CreateConfig(insecure, forceOverwrite bool, configPath, adminPassword strin } systemUserID := uuid.Must(uuid.NewV4()).String() + adminUserID := uuid.Must(uuid.NewV4()).String() idmServicePassword, err := generators.GenerateRandomPassword(passwordLength) if err != nil { @@ -203,6 +205,7 @@ func CreateConfig(insecure, forceOverwrite bool, configPath, adminPassword strin MachineAuthApiKey: machineAuthApiKey, TransferSecret: revaTransferSecret, SystemUserID: systemUserID, + AdminUserID: adminUserID, Idm: IdmExtension{ ServiceUserPasswords: ServiceUserPasswordsSettings{ AdminPassword: ocisAdminServicePassword,