From 88308961990fee15e6c41f3e4ce594b58164bfe7 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Tue, 18 Aug 2020 10:04:56 +0200 Subject: [PATCH] feat: setup as separate command (#604) * feat: separate setup from startup * health * move setup config * add env vars to caos_local.sh * fix domain and set devMode explicit --- cmd/zitadel/caos_local.sh | 7 +- cmd/zitadel/main.go | 43 ++++- cmd/zitadel/setup.yaml | 70 ++++++++ cmd/zitadel/system-defaults.yaml | 47 +----- .../repository/eventsourcing/repository.go | 19 +-- internal/api/api.go | 79 +++++++++ internal/api/http/marshal.go | 19 +++ .../config/systemdefaults/system_defaults.go | 3 +- .../types/setup.go => setup/config.go} | 3 +- .../eventsourcing => }/setup/setup.go | 158 ++++++++++-------- .../repository/eventsourcing/eventstore.go | 6 +- 11 files changed, 311 insertions(+), 143 deletions(-) create mode 100644 cmd/zitadel/setup.yaml create mode 100644 internal/api/http/marshal.go rename internal/{config/types/setup.go => setup/config.go} (94%) rename internal/{admin/repository/eventsourcing => }/setup/setup.go (73%) diff --git a/cmd/zitadel/caos_local.sh b/cmd/zitadel/caos_local.sh index 0c920a2292..ffd0302dd5 100755 --- a/cmd/zitadel/caos_local.sh +++ b/cmd/zitadel/caos_local.sh @@ -65,4 +65,9 @@ export ZITADEL_CONSOLE_ENV_DIR=../../console/src/assets/ export ZITADEL_DEFAULT_DOMAIN=zitadel.ch #Tracing -export TRACING_TYPE=google \ No newline at end of file +export TRACING_TYPE=google + +#Setup +export ZITADEL_CONSOLE_RESPONSE_TYPE=ID_TOKEN TOKEN +export ZITADEL_CONSOLE_GRANT_TYPE=IMPLICIT +export ZITADEL_CONSOLE_DEV_MODE=true \ No newline at end of file diff --git a/cmd/zitadel/main.go b/cmd/zitadel/main.go index 1f8816804b..2b14809e0c 100644 --- a/cmd/zitadel/main.go +++ b/cmd/zitadel/main.go @@ -18,8 +18,10 @@ import ( authz_repo "github.com/caos/zitadel/internal/authz/repository/eventsourcing" "github.com/caos/zitadel/internal/config" sd "github.com/caos/zitadel/internal/config/systemdefaults" + es_int "github.com/caos/zitadel/internal/eventstore" mgmt_es "github.com/caos/zitadel/internal/management/repository/eventsourcing" "github.com/caos/zitadel/internal/notification" + "github.com/caos/zitadel/internal/setup" tracing "github.com/caos/zitadel/internal/tracing/config" "github.com/caos/zitadel/internal/ui" "github.com/caos/zitadel/internal/ui/console" @@ -43,8 +45,17 @@ type Config struct { Notification notification.Config } +type setupConfig struct { + Log logging.Config + + Eventstore es_int.Config + SystemDefaults sd.SystemDefaults + SetUp setup.IAMSetUp +} + var ( configPaths = config.NewArrayFlags("authz.yaml", "startup.yaml", "system-defaults.yaml") + setupPaths = config.NewArrayFlags("system-defaults.yaml", "setup.yaml") adminEnabled = flag.Bool("admin", true, "enable admin api") managementEnabled = flag.Bool("management", true, "enable management api") authEnabled = flag.Bool("auth", true, "enable auth api") @@ -55,12 +66,29 @@ var ( localDevMode = flag.Bool("localDevMode", false, "enable local development specific configs") ) +const ( + cmdStart = "start" + cmdSetup = "setup" +) + func main() { flag.Var(configPaths, "config-files", "paths to the config files") + flag.Var(configPaths, "setup-files", "paths to the setup files") flag.Parse() + arg := flag.Arg(0) + switch arg { + case cmdStart: + startZitadel(configPaths.Values()) + case cmdSetup: + startSetup(setupPaths.Values(), *localDevMode) + default: + logging.Log("MAIN-afEQ2").Fatal("please provide an valid argument [start, setup]") + } +} +func startZitadel(configPaths []string) { conf := new(Config) - err := config.Read(conf, configPaths.Values()...) + err := config.Read(conf, configPaths...) logging.Log("MAIN-FaF2r").OnError(err).Fatal("cannot read config") ctx := context.Background() @@ -125,3 +153,16 @@ func startAPI(ctx context.Context, conf *Config, authZRepo *authz_repo.EsReposit } apis.Start(ctx) } + +func startSetup(configPaths []string, localDevMode bool) { + conf := new(setupConfig) + err := config.Read(conf, configPaths...) + logging.Log("MAIN-FaF2r").OnError(err).Fatal("cannot read config") + + ctx := context.Background() + + setup, err := setup.StartSetup(conf.Eventstore, conf.SystemDefaults) + logging.Log("SERVE-fD252").OnError(err).Panic("failed to start setup") + err = setup.Execute(ctx, conf.SetUp) + logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup") +} diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml new file mode 100644 index 0000000000..2a007ff05c --- /dev/null +++ b/cmd/zitadel/setup.yaml @@ -0,0 +1,70 @@ +Log: + Level: $ZITADEL_LOG_LEVEL + Formatter: + Format: text + +Eventstore: + ServiceName: 'Admin' + Repository: + SQL: + Host: $ZITADEL_EVENTSTORE_HOST + Port: $ZITADEL_EVENTSTORE_PORT + User: 'adminapi' + Database: 'eventstore' + Password: $CR_ADMINAPI_PASSWORD + SSL: + Mode: $CR_SSL_MODE + RootCert: $CR_ROOT_CERT + Cert: $CR_ADMINAPI_CERT + Key: $CR_ADMINAPI_KEY + Cache: + Type: 'fastcache' + Config: + MaxCacheSizeInByte: 10485760 #10mb + +SetUp: + GlobalOrg: 'Global' + IAMProject: 'Zitadel' + Orgs: + - Name: 'Global' + Domain: 'global.caos.ch' + Default: true + OrgIamPolicy: true + Users: + - FirstName: 'Global Org' + LastName: 'Administrator' + UserName: 'zitadel-global-org-admin@caos.ch' + Email: 'zitadel-global-org-admin@caos.ch' + Password: 'Password1!' + Owners: + - 'zitadel-global-org-admin@caos.ch' + - Name: 'CAOS AG' + Domain: 'caos.ch' + Users: + - FirstName: 'Zitadel' + LastName: 'Administrator' + UserName: 'zitadel-admin' + Email: 'zitadel-admin@caos.ch' + Password: 'Password1!' + Owners: + - 'zitadel-admin@caos.ch' + Projects: + - Name: 'Zitadel' + OIDCApps: + - Name: 'Management-API' + - Name: 'Auth-API' + - Name: 'Admin-API' + - Name: 'Zitadel Console' + RedirectUris: + - '$ZITADEL_CONSOLE/auth/callback' + PostLogoutRedirectUris: + - '$ZITADEL_CONSOLE/signedout' + ResponseTypes: + - '$ZITADEL_CONSOLE_RESPONSE_TYPE' + GrantTypes: + - '$ZITADEL_CONSOLE_GRANT_TYPE' + ApplicationType: 'USER_AGENT' + AuthMethodType: 'NONE' + DevMode: '$ZITADEL_CONSOLE_DEV_MODE' + Owners: + - 'zitadel-admin@caos.ch' \ No newline at end of file diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index 888b3626f9..1a1b795413 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -1,6 +1,6 @@ SystemDefaults: DefaultLanguage: 'de' - DefaultDomain: $ZITADEL_DEFAULT_DOMAIN + Domain: $ZITADEL_DEFAULT_DOMAIN ZitadelDocs: Issuer: $ZITADEL_ISSUER DiscoveryEndpoint: '$ZITADEL_ISSUER/.well-known/openid-configuration' @@ -81,51 +81,6 @@ SystemDefaults: IncludeUpperLetters: true IncludeDigits: true IncludeSymbols: false - SetUp: - GlobalOrg: 'Global' - IAMProject: 'Zitadel' - Orgs: - - Name: 'Global' - Domain: 'global.caos.ch' - Default: true - OrgIamPolicy: true - Users: - - FirstName: 'Global Org' - LastName: 'Administrator' - UserName: 'zitadel-global-org-admin@caos.ch' - Email: 'zitadel-global-org-admin@caos.ch' - Password: 'Password1!' - Owners: - - 'zitadel-global-org-admin@caos.ch' - - Name: 'CAOS AG' - Domain: 'caos.ch' - Users: - - FirstName: 'Zitadel' - LastName: 'Administrator' - UserName: 'zitadel-admin' - Email: 'zitadel-admin@caos.ch' - Password: 'Password1!' - Owners: - - 'zitadel-admin@caos.ch' - Projects: - - Name: 'Zitadel' - OIDCApps: - - Name: 'Management-API' - - Name: 'Auth-API' - - Name: 'Admin-API' - - Name: 'Zitadel Console' - RedirectUris: - - '$ZITADEL_CONSOLE/auth/callback' - PostLogoutRedirectUris: - - '$ZITADEL_CONSOLE/signedout' - ResponseTypes: - - 'CODE' - GrantTypes: - - 'AUTHORIZATION_CODE' - ApplicationType: 'NATIVE' - AuthMethodType: 'AUTH_TYPE_NONE' - Owners: - - 'zitadel-admin@caos.ch' Notifications: DebugMode: $DEBUG_MODE Endpoints: diff --git a/internal/admin/repository/eventsourcing/repository.go b/internal/admin/repository/eventsourcing/repository.go index 7ff138e711..82b9f2fa5d 100644 --- a/internal/admin/repository/eventsourcing/repository.go +++ b/internal/admin/repository/eventsourcing/repository.go @@ -2,12 +2,9 @@ package eventsourcing import ( "context" - "github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler" - es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing" - "github.com/caos/logging" "github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore" - "github.com/caos/zitadel/internal/admin/repository/eventsourcing/setup" + "github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler" "github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler" admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view" sd "github.com/caos/zitadel/internal/config/systemdefaults" @@ -16,7 +13,7 @@ import ( es_spol "github.com/caos/zitadel/internal/eventstore/spooler" es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" - es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" + es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" ) @@ -51,14 +48,6 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults) - project, err := es_proj.StartProject(es_proj.ProjectConfig{ - Eventstore: es, - Cache: conf.Eventstore.Cache, - }, systemDefaults) - if err != nil { - return nil, err - } - user, err := es_usr.StartUser(es_usr.UserConfig{ Eventstore: es, Cache: conf.Eventstore.Cache, @@ -82,10 +71,6 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r return nil, err } - eventstoreRepos := setup.EventstoreRepos{OrgEvents: org, UserEvents: user, ProjectEvents: project, IamEvents: iam, PolicyEvents: policy} - err = setup.StartSetup(systemDefaults, eventstoreRepos).Execute(ctx) - logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup") - spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, handler.EventstoreRepos{UserEvents: user, OrgEvents: org}) return &EsRepository{ diff --git a/internal/api/api.go b/internal/api/api.go index eae3574629..007b4a2f1e 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -4,14 +4,18 @@ import ( "context" "net/http" + "github.com/caos/logging" "google.golang.org/grpc" "github.com/caos/zitadel/internal/api/authz" grpc_util "github.com/caos/zitadel/internal/api/grpc" "github.com/caos/zitadel/internal/api/grpc/server" + http_util "github.com/caos/zitadel/internal/api/http" "github.com/caos/zitadel/internal/api/oidc" authz_es "github.com/caos/zitadel/internal/authz/repository/eventsourcing" "github.com/caos/zitadel/internal/config/systemdefaults" + "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" ) type Config struct { @@ -24,6 +28,12 @@ type API struct { gatewayHandler *server.GatewayHandler verifier *authz.TokenVerifier serverPort string + health health +} +type health interface { + Health(ctx context.Context) error + IamByID(ctx context.Context) (*iam_model.Iam, error) + VerifierClientID(ctx context.Context, appName string) (string, error) } func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository, sd systemdefaults.SystemDefaults) *API { @@ -31,8 +41,10 @@ func Create(config Config, authZ authz.Config, authZRepo *authz_es.EsRepository, serverPort: config.GRPC.ServerPort, } api.verifier = authz.Start(authZRepo) + api.health = authZRepo api.grpcServer = server.CreateServer(api.verifier, authZ, sd.DefaultLanguage) api.gatewayHandler = server.CreateGatewayHandler(config.GRPC) + api.RegisterHandler("", api.healthHandler()) return api } @@ -51,3 +63,70 @@ func (a *API) Start(ctx context.Context) { server.Serve(ctx, a.grpcServer, a.serverPort) a.gatewayHandler.Serve(ctx) } + +func (a *API) healthHandler() http.Handler { + checks := []ValidationFunction{ + func(ctx context.Context) error { + if err := a.health.Health(ctx); err != nil { + return errors.ThrowInternal(err, "API-F24h2", "DB CONNECTION ERROR") + } + return nil + }, + func(ctx context.Context) error { + iam, err := a.health.IamByID(ctx) + if err != nil && !errors.IsNotFound(err) { + return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED") + } + if iam == nil || !iam.SetUpStarted { + return errors.ThrowPreconditionFailed(nil, "API-HBfs3", "IAM NOT SET UP") + } + if !iam.SetUpDone { + return errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING") + } + return nil + }, + } + handler := http.NewServeMux() + handler.HandleFunc("/healthz", handleHealth) + handler.HandleFunc("/ready", handleReadiness(checks)) + handler.HandleFunc("/clientID", a.handleClientID) + + return handler +} + +func handleHealth(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte("ok")) + logging.Log("API-Hfss2").OnError(err).Error("error writing ok for health") +} + +func handleReadiness(checks []ValidationFunction) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + err := validate(r.Context(), checks) + if err == nil { + http_util.MarshalJSON(w, "ok") + return + } + http_util.MarshalJSON(w, err) + } +} + +func (a *API) handleClientID(w http.ResponseWriter, r *http.Request) { + id, err := a.health.VerifierClientID(r.Context(), "Zitadel Console") + if err != nil { + http_util.MarshalJSON(w, err) + return + } + http_util.MarshalJSON(w, id) +} + +type ValidationFunction func(ctx context.Context) error + +func validate(ctx context.Context, validations []ValidationFunction) error { + for _, validation := range validations { + if err := validation(ctx); err != nil { + logging.Log("API-vf823").WithError(err).Error("validation failed") + return err + } + } + return nil +} diff --git a/internal/api/http/marshal.go b/internal/api/http/marshal.go new file mode 100644 index 0000000000..10df5c8475 --- /dev/null +++ b/internal/api/http/marshal.go @@ -0,0 +1,19 @@ +package http + +import ( + "encoding/json" + "net/http" + + "github.com/caos/logging" +) + +func MarshalJSON(w http.ResponseWriter, i interface{}) { + b, err := json.Marshal(i) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("content-type", "application/json") + _, err = w.Write(b) + logging.Log("HTTP-sdgT2").OnError(err).Error("error writing response") +} diff --git a/internal/config/systemdefaults/system_defaults.go b/internal/config/systemdefaults/system_defaults.go index d309571564..89a5b56793 100644 --- a/internal/config/systemdefaults/system_defaults.go +++ b/internal/config/systemdefaults/system_defaults.go @@ -15,7 +15,7 @@ import ( type SystemDefaults struct { DefaultLanguage language.Tag - DefaultDomain string + Domain string ZitadelDocs ZitadelDocs SecretGenerators SecretGenerators UserVerificationKey *crypto.KeyConfig @@ -24,7 +24,6 @@ type SystemDefaults struct { DefaultPolicies DefaultPolicies DomainVerification DomainVerification IamID string - SetUp types.IAMSetUp Notifications Notifications } diff --git a/internal/config/types/setup.go b/internal/setup/config.go similarity index 94% rename from internal/config/types/setup.go rename to internal/setup/config.go index 7cde46c1a9..442a3a4ed2 100644 --- a/internal/config/types/setup.go +++ b/internal/setup/config.go @@ -1,4 +1,4 @@ -package types +package setup type IAMSetUp struct { GlobalOrg string @@ -39,4 +39,5 @@ type OIDCApp struct { ApplicationType string AuthMethodType string PostLogoutRedirectUris []string + DevMode bool } diff --git a/internal/admin/repository/eventsourcing/setup/setup.go b/internal/setup/setup.go similarity index 73% rename from internal/admin/repository/eventsourcing/setup/setup.go rename to internal/setup/setup.go index 3dab561bd7..913bab847b 100644 --- a/internal/admin/repository/eventsourcing/setup/setup.go +++ b/internal/setup/setup.go @@ -2,34 +2,33 @@ package setup import ( "context" - "time" "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/config/types" caos_errs "github.com/caos/zitadel/internal/errors" + es_int "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/models" iam_model "github.com/caos/zitadel/internal/iam/model" + es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" org_model "github.com/caos/zitadel/internal/org/model" + es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" policy_model "github.com/caos/zitadel/internal/policy/model" + es_policy "github.com/caos/zitadel/internal/policy/repository/eventsourcing" policy_event "github.com/caos/zitadel/internal/policy/repository/eventsourcing" proj_model "github.com/caos/zitadel/internal/project/model" + es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" usr_model "github.com/caos/zitadel/internal/user/model" + es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" ) type Setup struct { - repos EventstoreRepos - iamID string - setUpConfig types.IAMSetUp -} - -type EventstoreRepos struct { + iamID string IamEvents *iam_event.IamEventstore OrgEvents *org_event.OrgEventstore UserEvents *usr_event.UserEventstore @@ -62,30 +61,63 @@ const ( OIDCAuthMethodTypePost = "POST" ) -func StartSetup(sd systemdefaults.SystemDefaults, repos EventstoreRepos) *Setup { - return &Setup{ - repos: repos, - iamID: sd.IamID, - setUpConfig: sd.SetUp, +func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) { + setup := &Setup{ + iamID: sd.IamID, } + es, err := es_int.Start(esConfig) + if err != nil { + return nil, err + } + + setup.IamEvents, err = es_iam.StartIam(es_iam.IamConfig{ + Eventstore: es, + Cache: esConfig.Cache, + }, sd) + if err != nil { + return nil, err + } + + setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd) + + setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{ + Eventstore: es, + Cache: esConfig.Cache, + }, sd) + if err != nil { + return nil, err + } + + setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{ + Eventstore: es, + Cache: esConfig.Cache, + }, sd) + if err != nil { + return nil, err + } + + setup.PolicyEvents, err = es_policy.StartPolicy(es_policy.PolicyConfig{ + Eventstore: es, + Cache: esConfig.Cache, + }, sd) + if err != nil { + return nil, err + } + return setup, nil } -func (s *Setup) Execute(ctx context.Context) error { - iam, err := s.repos.IamEvents.IamByID(ctx, s.iamID) +func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error { + iam, err := s.IamEvents.IamByID(ctx, s.iamID) if err != nil && !caos_errs.IsNotFound(err) { return err } - if iam != nil && iam.SetUpDone { + if iam != nil && (iam.SetUpStarted || iam.SetUpDone) { return nil } - if iam != nil && iam.SetUpStarted { - return s.waitForSetupDone(ctx) - } - logging.Log("SETUP-hwG32").Info("starting setup") ctx = setSetUpContextData(ctx, s.iamID) - iam, err = s.repos.IamEvents.StartSetup(ctx, s.iamID) + iam, err = s.IamEvents.StartSetup(ctx, s.iamID) if err != nil { return err } @@ -97,39 +129,39 @@ func (s *Setup) Execute(ctx context.Context) error { createdProjects: make(map[string]*proj_model.Project), } - pwComplexityPolicy, err := s.repos.PolicyEvents.GetPasswordComplexityPolicy(ctx, policy_model.DefaultPolicy) + pwComplexityPolicy, err := s.PolicyEvents.GetPasswordComplexityPolicy(ctx, policy_model.DefaultPolicy) if err != nil { logging.Log("SETUP-9osWF").WithError(err).Error("unable to read complexity policy") return err } setUp.pwComplexityPolicy = pwComplexityPolicy - err = setUp.orgs(ctx, s.setUpConfig.Orgs) + err = setUp.orgs(ctx, setUpConfig.Orgs) if err != nil { logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up orgs") return err } ctx = setSetUpContextData(ctx, s.iamID) - err = setUp.iamOwners(ctx, s.setUpConfig.Owners) + err = setUp.iamOwners(ctx, setUpConfig.Owners) if err != nil { logging.Log("SETUP-WHr01").WithError(err).Error("unable to set up iam owners") return err } - err = setUp.setGlobalOrg(ctx) + err = setUp.setGlobalOrg(ctx, setUpConfig.GlobalOrg) if err != nil { logging.Log("SETUP-0874m").WithError(err).Error("unable to set global org") return err } - err = setUp.setIamProject(ctx) + err = setUp.setIamProject(ctx, setUpConfig.IAMProject) if err != nil { logging.Log("SETUP-kaWjq").WithError(err).Error("unable to set zitadel project") return err } - iam, err = s.repos.IamEvents.SetupDone(ctx, s.iamID) + iam, err = s.IamEvents.SetupDone(ctx, s.iamID) if err != nil { logging.Log("SETUP-de342").WithError(err).Error("unable to finish setup") return err @@ -138,26 +170,7 @@ func (s *Setup) Execute(ctx context.Context) error { return nil } -func (s *Setup) waitForSetupDone(ctx context.Context) error { - logging.Log("SETUP-hws22").Info("waiting for setup to be done") - ctx, cancel := context.WithDeadline(ctx, time.Now().UTC().Add(10*time.Second)) - defer cancel() - - for { - select { - case <-time.After(1 * time.Second): - iam, _ := s.repos.IamEvents.IamByID(ctx, s.iamID) - if iam != nil && iam.SetUpDone { - return nil - } - logging.Log("SETUP-d23g1").Info("setup not done yet") - case <-ctx.Done(): - return caos_errs.ThrowInternal(ctx.Err(), "SETUP-dsjg3", "Timeout exceeded for setup") - } - } -} - -func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error { +func (setUp *initializer) orgs(ctx context.Context, orgs []Org) error { logging.Log("SETUP-dsTh3").Info("setting up orgs") for _, iamOrg := range orgs { org, err := setUp.org(ctx, iamOrg) @@ -175,7 +188,7 @@ func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error { return err } } else { - policy, err = setUp.repos.OrgEvents.GetOrgIamPolicy(ctx, policy_model.DefaultPolicy) + policy, err = setUp.OrgEvents.GetOrgIamPolicy(ctx, policy_model.DefaultPolicy) if err != nil { logging.LogWithFields("SETUP-IS8wS", "Org Iam Policy", iamOrg.Name).WithError(err).Error("unable to get default iam org policy") return err @@ -205,13 +218,13 @@ func (setUp *initializer) orgs(ctx context.Context, orgs []types.Org) error { return nil } -func (setUp *initializer) org(ctx context.Context, org types.Org) (*org_model.Org, error) { +func (setUp *initializer) org(ctx context.Context, org Org) (*org_model.Org, error) { ctx = setSetUpContextData(ctx, "") createOrg := &org_model.Org{ Name: org.Name, Domains: []*org_model.OrgDomain{{Domain: org.Domain}}, } - return setUp.repos.OrgEvents.CreateOrg(ctx, createOrg, nil) + return setUp.OrgEvents.CreateOrg(ctx, createOrg, nil) } func (setUp *initializer) iamorgpolicy(ctx context.Context, org *org_model.Org) (*org_model.OrgIamPolicy, error) { @@ -220,7 +233,7 @@ func (setUp *initializer) iamorgpolicy(ctx context.Context, org *org_model.Org) ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID}, UserLoginMustBeDomain: false, } - return setUp.repos.OrgEvents.AddOrgIamPolicy(ctx, policy) + return setUp.OrgEvents.AddOrgIamPolicy(ctx, policy) } func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error { @@ -231,7 +244,7 @@ func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members") return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members") } - _, err := setUp.repos.IamEvents.AddIamMember(ctx, &iam_model.IamMember{ObjectRoot: models.ObjectRoot{AggregateID: setUp.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}}) + _, err := setUp.IamEvents.AddIamMember(ctx, &iam_model.IamMember{ObjectRoot: models.ObjectRoot{AggregateID: setUp.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}}) if err != nil { logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner") return err @@ -241,15 +254,15 @@ func (setUp *initializer) iamOwners(ctx context.Context, owners []string) error return nil } -func (setUp *initializer) setGlobalOrg(ctx context.Context) error { +func (setUp *initializer) setGlobalOrg(ctx context.Context, globalOrgName string) error { logging.Log("SETUP-dsj75").Info("setting global org") - globalOrg, ok := setUp.createdOrgs[setUp.setUpConfig.GlobalOrg] + globalOrg, ok := setUp.createdOrgs[globalOrgName] if !ok { - logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", setUp.setUpConfig.GlobalOrg).Error("global org not created") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", setUp.setUpConfig.GlobalOrg) + logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created") + return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName) } - if _, err := setUp.repos.IamEvents.SetGlobalOrg(ctx, setUp.iamID, globalOrg.AggregateID); err != nil { + if _, err := setUp.IamEvents.SetGlobalOrg(ctx, setUp.iamID, globalOrg.AggregateID); err != nil { logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam") return err } @@ -257,15 +270,15 @@ func (setUp *initializer) setGlobalOrg(ctx context.Context) error { return nil } -func (setUp *initializer) setIamProject(ctx context.Context) error { +func (setUp *initializer) setIamProject(ctx context.Context, iamProjectName string) error { logging.Log("SETUP-HE3qa").Info("setting iam project") - iamProject, ok := setUp.createdProjects[setUp.setUpConfig.IAMProject] + iamProject, ok := setUp.createdProjects[iamProjectName] if !ok { - logging.LogWithFields("SETUP-SJFWP", "Iam Project", setUp.setUpConfig.IAMProject).Error("iam project created") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", setUp.setUpConfig.IAMProject) + logging.LogWithFields("SETUP-SJFWP", "Iam Project", iamProjectName).Error("iam project created") + return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName) } - if _, err := setUp.repos.IamEvents.SetIamProject(ctx, setUp.iamID, iamProject.AggregateID); err != nil { + if _, err := setUp.IamEvents.SetIamProject(ctx, setUp.iamID, iamProject.AggregateID); err != nil { logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam") return err } @@ -273,7 +286,7 @@ func (setUp *initializer) setIamProject(ctx context.Context) error { return nil } -func (setUp *initializer) users(ctx context.Context, users []types.User, orgPolicy *org_model.OrgIamPolicy) error { +func (setUp *initializer) users(ctx context.Context, users []User, orgPolicy *org_model.OrgIamPolicy) error { for _, user := range users { created, err := setUp.user(ctx, user, orgPolicy) if err != nil { @@ -285,7 +298,7 @@ func (setUp *initializer) users(ctx context.Context, users []types.User, orgPoli return nil } -func (setUp *initializer) user(ctx context.Context, user types.User, orgPolicy *org_model.OrgIamPolicy) (*usr_model.User, error) { +func (setUp *initializer) user(ctx context.Context, user User, orgPolicy *org_model.OrgIamPolicy) (*usr_model.User, error) { createUser := &usr_model.User{ Profile: &usr_model.Profile{ UserName: user.UserName, @@ -300,7 +313,7 @@ func (setUp *initializer) user(ctx context.Context, user types.User, orgPolicy * SecretString: user.Password, }, } - return setUp.repos.UserEvents.CreateUser(ctx, createUser, setUp.pwComplexityPolicy, orgPolicy) + return setUp.UserEvents.CreateUser(ctx, createUser, setUp.pwComplexityPolicy, orgPolicy) } func (setUp *initializer) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error { @@ -325,11 +338,11 @@ func (setUp *initializer) orgOwner(ctx context.Context, org *org_model.Org, user UserID: user.AggregateID, Roles: []string{OrgOwnerRole}, } - _, err := setUp.repos.OrgEvents.AddOrgMember(ctx, addMember) + _, err := setUp.OrgEvents.AddOrgMember(ctx, addMember) return err } -func (setUp *initializer) projects(ctx context.Context, projects []types.Project) error { +func (setUp *initializer) projects(ctx context.Context, projects []Project) error { for _, project := range projects { createdProject, err := setUp.project(ctx, project) if err != nil { @@ -347,14 +360,14 @@ func (setUp *initializer) projects(ctx context.Context, projects []types.Project return nil } -func (setUp *initializer) project(ctx context.Context, project types.Project) (*proj_model.Project, error) { +func (setUp *initializer) project(ctx context.Context, project Project) (*proj_model.Project, error) { addProject := &proj_model.Project{ Name: project.Name, } - return setUp.repos.ProjectEvents.CreateProject(ctx, addProject) + return setUp.ProjectEvents.CreateProject(ctx, addProject) } -func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Project, oidc types.OIDCApp) (*proj_model.Application, error) { +func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) { addOIDCApp := &proj_model.Application{ ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID}, Name: oidc.Name, @@ -365,9 +378,10 @@ func (setUp *initializer) oidcApp(ctx context.Context, project *proj_model.Proje ApplicationType: getOIDCApplicationType(oidc.ApplicationType), AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType), PostLogoutRedirectUris: oidc.PostLogoutRedirectUris, + DevMode: oidc.DevMode, }, } - return setUp.repos.ProjectEvents.AddApplication(ctx, addOIDCApp) + return setUp.ProjectEvents.AddApplication(ctx, addOIDCApp) } func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType { @@ -431,7 +445,7 @@ func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType { case OIDCAuthMethodTypePost: return proj_model.OIDCAuthMethodTypePost } - return proj_model.OIDCAuthMethodTypeNone + return proj_model.OIDCAuthMethodTypeBasic } func setSetUpContextData(ctx context.Context, orgID string) context.Context { diff --git a/internal/user/repository/eventsourcing/eventstore.go b/internal/user/repository/eventsourcing/eventstore.go index 3132162f63..23613bdfa4 100644 --- a/internal/user/repository/eventsourcing/eventstore.go +++ b/internal/user/repository/eventsourcing/eventstore.go @@ -32,7 +32,7 @@ type UserEventstore struct { es_int.Eventstore userCache *UserCache idGenerator id.Generator - defaultDomain string + domain string PasswordAlg crypto.HashAlgorithm InitializeUserCode crypto.Generator EmailVerificationCode crypto.Generator @@ -68,7 +68,7 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto Eventstore: conf.Eventstore, userCache: userCache, idGenerator: id.SonyFlakeGenerator, - defaultDomain: systemDefaults.DefaultDomain, + domain: systemDefaults.Domain, InitializeUserCode: initCodeGen, EmailVerificationCode: emailVerificationCode, PhoneVerificationCode: phoneVerificationCode, @@ -1115,5 +1115,5 @@ func (es *UserEventstore) generateTemporaryLoginName() (string, error) { if err != nil { return "", err } - return fmt.Sprintf("%s@temporary.%s", id, es.defaultDomain), nil + return fmt.Sprintf("%s@temporary.%s", id, es.domain), nil }