diff --git a/cmd/admin/initialise/sql/09_events_table.sql b/cmd/admin/initialise/sql/09_events_table.sql index e31cc8c722..e1d79e5ea3 100644 --- a/cmd/admin/initialise/sql/09_events_table.sql +++ b/cmd/admin/initialise/sql/09_events_table.sql @@ -12,13 +12,13 @@ CREATE TABLE eventstore.events ( , editor_user TEXT NOT NULL , editor_service TEXT NOT NULL , resource_owner TEXT NOT NULL - , tenant TEXT + , instance_id TEXT , PRIMARY KEY (event_sequence DESC) USING HASH WITH BUCKET_COUNT = 10 , INDEX agg_type_agg_id (aggregate_type, aggregate_id) , INDEX agg_type (aggregate_type) , INDEX agg_type_seq (aggregate_type, event_sequence DESC) - STORING (id, event_type, aggregate_id, aggregate_version, previous_aggregate_sequence, creation_date, event_data, editor_user, editor_service, resource_owner, tenant, previous_aggregate_type_sequence) + STORING (id, event_type, aggregate_id, aggregate_version, previous_aggregate_sequence, creation_date, event_data, editor_user, editor_service, resource_owner, instance_id, previous_aggregate_type_sequence) , INDEX max_sequence (aggregate_type, aggregate_id, event_sequence DESC) , CONSTRAINT previous_sequence_unique UNIQUE (previous_aggregate_sequence DESC) , CONSTRAINT prev_agg_type_seq_unique UNIQUE(previous_aggregate_type_sequence) diff --git a/cmd/admin/key/key_test.go b/cmd/admin/key/key_test.go index b1019deed1..47b1b00205 100644 --- a/cmd/admin/key/key_test.go +++ b/cmd/admin/key/key_test.go @@ -155,7 +155,7 @@ func Test_keysFromYAML(t *testing.T) { if tt.res.err != nil && !tt.res.err(err) { t.Errorf("got wrong err: %v ", err) } - assert.EqualValues(t, got, tt.res.keys) + assert.ElementsMatch(t, got, tt.res.keys) }) } } diff --git a/cmd/admin/setup/01_projection_tables.go b/cmd/admin/setup/01_projection_tables.go new file mode 100644 index 0000000000..a34b478b35 --- /dev/null +++ b/cmd/admin/setup/01_projection_tables.go @@ -0,0 +1,34 @@ +package setup + +import ( + "context" + "database/sql" + _ "embed" +) + +var ( + //go:embed 01_sql/adminapi.sql + createAdminViews string + //go:embed 01_sql/auth.sql + createAuthViews string + //go:embed 01_sql/authz.sql + createAuthzViews string + //go:embed 01_sql/notification.sql + createNotificationViews string + //go:embed 01_sql/projections.sql + createProjections string +) + +type ProjectionTable struct { + dbClient *sql.DB +} + +func (mig *ProjectionTable) Execute(ctx context.Context) error { + stmt := createAdminViews + createAuthViews + createAuthzViews + createNotificationViews + createProjections + _, err := mig.dbClient.ExecContext(ctx, stmt) + return err +} + +func (mig *ProjectionTable) String() string { + return "01_tables" +} diff --git a/cmd/admin/setup/01_sql/adminapi.sql b/cmd/admin/setup/01_sql/adminapi.sql new file mode 100644 index 0000000000..05d243210f --- /dev/null +++ b/cmd/admin/setup/01_sql/adminapi.sql @@ -0,0 +1,54 @@ +CREATE SCHEMA adminapi; + +CREATE TABLE adminapi.locks ( + locker_id TEXT, + locked_until TIMESTAMPTZ(3), + projection_name TEXT, + + PRIMARY KEY (projection_name) +); + +CREATE TABLE adminapi.current_sequences ( + projection_name TEXT, + aggregate_type TEXT, + current_sequence BIGINT, + timestamp TIMESTAMPTZ, + + PRIMARY KEY (projection_name, aggregate_type) +); + +CREATE TABLE adminapi.failed_events ( + projection_name TEXT, + failed_sequence BIGINT, + failure_count SMALLINT, + error TEXT, + + PRIMARY KEY (projection_name, failed_sequence) +); + +CREATE TABLE adminapi.styling ( + aggregate_id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + label_policy_state INT2 NOT NULL DEFAULT 0:::INT2, + sequence INT8 NULL, + primary_color STRING NULL, + background_color STRING NULL, + warn_color STRING NULL, + font_color STRING NULL, + primary_color_dark STRING NULL, + background_color_dark STRING NULL, + warn_color_dark STRING NULL, + font_color_dark STRING NULL, + logo_url STRING NULL, + icon_url STRING NULL, + logo_dark_url STRING NULL, + icon_dark_url STRING NULL, + font_url STRING NULL, + err_msg_popup BOOL NULL, + disable_watermark BOOL NULL, + hide_login_name_suffix BOOL NULL, + instance_id STRING NOT NULL, + + PRIMARY KEY (aggregate_id, label_policy_state) +); diff --git a/cmd/admin/setup/01_sql/auth.sql b/cmd/admin/setup/01_sql/auth.sql new file mode 100644 index 0000000000..ec91cc3185 --- /dev/null +++ b/cmd/admin/setup/01_sql/auth.sql @@ -0,0 +1,222 @@ +CREATE SCHEMA auth; + +CREATE TABLE auth.locks ( + locker_id TEXT, + locked_until TIMESTAMPTZ(3), + projection_name TEXT, + + PRIMARY KEY (projection_name) +); + +CREATE TABLE auth.current_sequences ( + projection_name TEXT, + aggregate_type TEXT, + current_sequence BIGINT, + timestamp TIMESTAMPTZ, + + PRIMARY KEY (projection_name, aggregate_type) +); + +CREATE TABLE auth.failed_events ( + projection_name TEXT, + failed_sequence BIGINT, + failure_count SMALLINT, + error TEXT, + + PRIMARY KEY (projection_name, failed_sequence) +); + +CREATE TABLE auth.users ( + id STRING NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + resource_owner STRING NULL, + user_state INT2 NULL, + password_set BOOL NULL, + password_change_required BOOL NULL, + password_change TIMESTAMPTZ NULL, + last_login TIMESTAMPTZ NULL, + user_name STRING NULL, + login_names STRING[] NULL, + preferred_login_name STRING NULL, + first_name STRING NULL, + last_name STRING NULL, + nick_name STRING NULL, + display_name STRING NULL, + preferred_language STRING NULL, + gender INT2 NULL, + email STRING NULL, + is_email_verified BOOL NULL, + phone STRING NULL, + is_phone_verified BOOL NULL, + country STRING NULL, + locality STRING NULL, + postal_code STRING NULL, + region STRING NULL, + street_address STRING NULL, + otp_state INT2 NULL, + mfa_max_set_up INT2 NULL, + mfa_init_skipped TIMESTAMPTZ NULL, + sequence INT8 NULL, + init_required BOOL NULL, + username_change_required BOOL NULL, + machine_name STRING NULL, + machine_description STRING NULL, + user_type STRING NULL, + u2f_tokens BYTES NULL, + passwordless_tokens BYTES NULL, + avatar_key STRING NULL, + passwordless_init_required BOOL NULL, + password_init_required BOOL NULL, + instance_id STRING NULL, + + PRIMARY KEY (id) +); + +CREATE TABLE auth.user_sessions ( + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + resource_owner STRING NULL, + state INT2 NULL, + user_agent_id STRING NULL, + user_id STRING NULL, + user_name STRING NULL, + password_verification TIMESTAMPTZ NULL, + second_factor_verification TIMESTAMPTZ NULL, + multi_factor_verification TIMESTAMPTZ NULL, + sequence INT8 NULL, + second_factor_verification_type INT2 NULL, + multi_factor_verification_type INT2 NULL, + user_display_name STRING NULL, + login_name STRING NULL, + external_login_verification TIMESTAMPTZ NULL, + selected_idp_config_id STRING NULL, + passwordless_verification TIMESTAMPTZ NULL, + avatar_key STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (user_agent_id, user_id) +); + +CREATE TABLE auth.user_external_idps ( + external_user_id STRING NOT NULL, + idp_config_id STRING NOT NULL, + user_id STRING NULL, + idp_name STRING NULL, + user_display_name STRING NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + sequence INT8 NULL, + resource_owner STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (external_user_id, idp_config_id) +); + +CREATE TABLE auth.tokens ( + id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + resource_owner STRING NULL, + application_id STRING NULL, + user_agent_id STRING NULL, + user_id STRING NULL, + expiration TIMESTAMPTZ NULL, + sequence INT8 NULL, + scopes STRING[] NULL, + audience STRING[] NULL, + preferred_language STRING NULL, + refresh_token_id STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (id), + INDEX user_user_agent_idx (user_id, user_agent_id) +); + +CREATE TABLE auth.refresh_tokens ( + id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + resource_owner STRING NULL, + token STRING NULL, + client_id STRING NOT NULL, + user_agent_id STRING NOT NULL, + user_id STRING NOT NULL, + auth_time TIMESTAMPTZ NULL, + idle_expiration TIMESTAMPTZ NULL, + expiration TIMESTAMPTZ NULL, + sequence INT8 NULL, + scopes STRING[] NULL, + audience STRING[] NULL, + amr STRING[] NULL, + instance_id STRING NULL, + + PRIMARY KEY (id), + UNIQUE INDEX unique_client_user_index (client_id ASC, user_agent_id ASC, user_id ASC) +); + +CREATE TABLE auth.org_project_mapping ( + org_id STRING NOT NULL, + project_id STRING NOT NULL, + project_grant_id STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (org_id, project_id) +); + +CREATE TABLE auth.idp_providers ( + aggregate_id STRING NOT NULL, + idp_config_id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + sequence INT8 NULL, + name STRING NULL, + idp_config_type INT2 NULL, + idp_provider_type INT2 NULL, + idp_state INT2 NULL, + styling_type INT2 NULL, + instance_id STRING NULL, + + PRIMARY KEY (aggregate_id, idp_config_id) +); + +CREATE TABLE auth.idp_configs ( + idp_config_id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + sequence INT8 NULL, + aggregate_id STRING NULL, + name STRING NULL, + idp_state INT2 NULL, + idp_provider_type INT2 NULL, + is_oidc BOOL NULL, + oidc_client_id STRING NULL, + oidc_client_secret JSONB NULL, + oidc_issuer STRING NULL, + oidc_scopes STRING[] NULL, + oidc_idp_display_name_mapping INT2 NULL, + oidc_idp_username_mapping INT2 NULL, + styling_type INT2 NULL, + oauth_authorization_endpoint STRING NULL, + oauth_token_endpoint STRING NULL, + auto_register BOOL NULL, + jwt_endpoint STRING NULL, + jwt_keys_endpoint STRING NULL, + jwt_header_name STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (idp_config_id) +); + +CREATE TABLE auth.auth_requests ( + id STRING NOT NULL, + request JSONB NULL, + code STRING NULL, + request_type INT2 NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + instance_id STRING NULL, + + PRIMARY KEY (id), + INDEX auth_code_idx (code) +); diff --git a/cmd/admin/setup/01_sql/authz.sql b/cmd/admin/setup/01_sql/authz.sql new file mode 100644 index 0000000000..1e944b8007 --- /dev/null +++ b/cmd/admin/setup/01_sql/authz.sql @@ -0,0 +1,44 @@ +CREATE SCHEMA authz; + +CREATE TABLE authz.locks ( + locker_id TEXT, + locked_until TIMESTAMPTZ(3), + projection_name TEXT, + + PRIMARY KEY (projection_name) +); + +CREATE TABLE authz.current_sequences ( + projection_name TEXT, + aggregate_type TEXT, + current_sequence BIGINT, + timestamp TIMESTAMPTZ, + + PRIMARY KEY (projection_name, aggregate_type) +); + +CREATE TABLE authz.failed_events ( + projection_name TEXT, + failed_sequence BIGINT, + failure_count SMALLINT, + error TEXT, + + PRIMARY KEY (projection_name, failed_sequence) +); + +CREATE TABLE authz.user_memberships ( + user_id STRING NOT NULL, + member_type INT2 NOT NULL, + aggregate_id STRING NOT NULL, + object_id STRING NOT NULL, + roles STRING[] NULL, + display_name STRING NULL, + resource_owner STRING NULL, + resource_owner_name STRING NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + sequence INT8 NULL, + instance_id STRING NULL, + + PRIMARY KEY (user_id, member_type, aggregate_id, object_id) +); diff --git a/cmd/admin/setup/01_sql/notification.sql b/cmd/admin/setup/01_sql/notification.sql new file mode 100644 index 0000000000..b9697179dd --- /dev/null +++ b/cmd/admin/setup/01_sql/notification.sql @@ -0,0 +1,52 @@ +CREATE SCHEMA notification; + +CREATE TABLE notification.locks ( + locker_id TEXT, + locked_until TIMESTAMPTZ(3), + projection_name TEXT, + + PRIMARY KEY (projection_name) +); + +CREATE TABLE notification.current_sequences ( + projection_name TEXT, + aggregate_type TEXT, + current_sequence BIGINT, + timestamp TIMESTAMPTZ, + + PRIMARY KEY (projection_name, aggregate_type) +); + +CREATE TABLE notification.failed_events ( + projection_name TEXT, + failed_sequence BIGINT, + failure_count SMALLINT, + error TEXT, + + PRIMARY KEY (projection_name, failed_sequence) +); + +CREATE TABLE notification.notify_users ( + id STRING NOT NULL, + creation_date TIMESTAMPTZ NULL, + change_date TIMESTAMPTZ NULL, + resource_owner STRING NULL, + user_name STRING NULL, + first_name STRING NULL, + last_name STRING NULL, + nick_name STRING NULL, + display_name STRING NULL, + preferred_language STRING NULL, + gender INT2 NULL, + last_email STRING NULL, + verified_email STRING NULL, + last_phone STRING NULL, + verified_phone STRING NULL, + sequence INT8 NULL, + password_set BOOL NULL, + login_names STRING NULL, + preferred_login_name STRING NULL, + instance_id STRING NULL, + + PRIMARY KEY (id) +); diff --git a/migrations/cockroach/V1.63__zitadel_schema.sql b/cmd/admin/setup/01_sql/projections.sql similarity index 51% rename from migrations/cockroach/V1.63__zitadel_schema.sql rename to cmd/admin/setup/01_sql/projections.sql index 27eacf1b5e..03678a0ae8 100644 --- a/migrations/cockroach/V1.63__zitadel_schema.sql +++ b/cmd/admin/setup/01_sql/projections.sql @@ -1,10 +1,4 @@ -CREATE DATABASE zitadel; -GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE zitadel TO queries; -use zitadel; - -CREATE SCHEMA zitadel.projections AUTHORIZATION queries; - -CREATE TABLE zitadel.projections.locks ( +CREATE TABLE projections.locks ( locker_id TEXT, locked_until TIMESTAMPTZ(3), projection_name TEXT, @@ -12,7 +6,7 @@ CREATE TABLE zitadel.projections.locks ( PRIMARY KEY (projection_name) ); -CREATE TABLE zitadel.projections.current_sequences ( +CREATE TABLE projections.current_sequences ( projection_name TEXT, aggregate_type TEXT, current_sequence BIGINT, @@ -21,11 +15,12 @@ CREATE TABLE zitadel.projections.current_sequences ( PRIMARY KEY (projection_name, aggregate_type) ); -CREATE TABLE zitadel.projections.failed_events ( +CREATE TABLE projections.failed_events ( projection_name TEXT, failed_sequence BIGINT, failure_count SMALLINT, error TEXT, + instance_id TEXT, - PRIMARY KEY (projection_name, failed_sequence) + PRIMARY KEY (projection_name, failed_sequence, instance_id) ); diff --git a/cmd/admin/setup/config.go b/cmd/admin/setup/config.go new file mode 100644 index 0000000000..85878bc1ef --- /dev/null +++ b/cmd/admin/setup/config.go @@ -0,0 +1,13 @@ +package setup + +import ( + "github.com/caos/zitadel/internal/database" +) + +type Config struct { + Database database.Config +} + +type Steps struct { + S1ProjectionTable *ProjectionTable +} diff --git a/cmd/admin/setup/setup.go b/cmd/admin/setup/setup.go index c15815e637..14494f2fb6 100644 --- a/cmd/admin/setup/setup.go +++ b/cmd/admin/setup/setup.go @@ -1,10 +1,22 @@ package setup import ( + "bytes" + "context" _ "embed" "github.com/caos/logging" "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/caos/zitadel/internal/database" + "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/migration" +) + +var ( + //go:embed steps.yaml + defaultSteps []byte ) func New() *cobra.Command { @@ -14,9 +26,33 @@ func New() *cobra.Command { Long: `sets up data to start ZITADEL. Requirements: - cockroachdb`, - RunE: func(cmd *cobra.Command, args []string) error { - logging.Info("hello world") - return nil + Run: func(cmd *cobra.Command, args []string) { + config := new(Config) + err := viper.Unmarshal(config) + logging.OnError(err).Fatal("unable to read config") + + v := viper.New() + v.SetConfigType("yaml") + err = v.ReadConfig(bytes.NewBuffer(defaultSteps)) + logging.OnError(err).Fatal("unable to read setup steps") + + steps := new(Steps) + err = v.Unmarshal(steps) + logging.OnError(err).Fatal("unable to read steps") + + setup(config, steps) }, } } + +func setup(config *Config, steps *Steps) { + dbClient, err := database.Connect(config.Database) + logging.OnError(err).Fatal("unable to connect to database") + + eventstoreClient, err := eventstore.Start(dbClient) + logging.OnError(err).Fatal("unable to start eventstore") + + steps.S1ProjectionTable = &ProjectionTable{dbClient: dbClient} + + migration.Migrate(context.Background(), eventstoreClient, steps.S1ProjectionTable) +} diff --git a/migrations/testfiles/V1.3__empty.sql b/cmd/admin/setup/steps.yaml similarity index 100% rename from migrations/testfiles/V1.3__empty.sql rename to cmd/admin/setup/steps.yaml diff --git a/cmd/admin/start/start.go b/cmd/admin/start/start.go index bdf20a36a1..f057f2d523 100644 --- a/cmd/admin/start/start.go +++ b/cmd/admin/start/start.go @@ -41,7 +41,6 @@ import ( "github.com/caos/zitadel/internal/crypto" cryptoDB "github.com/caos/zitadel/internal/crypto/database" "github.com/caos/zitadel/internal/database" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/notification" @@ -308,7 +307,7 @@ func shutdownServer(ctx context.Context, server *http.Server) error { //TODO:!!??!! func consoleClientID(ctx context.Context, queries *query.Queries) (string, error) { - iam, err := queries.IAMByID(ctx, domain.IAMID) + iam, err := queries.IAM(ctx) if err != nil { return "", err } diff --git a/internal/api/api.go b/internal/api/api.go index ed5978488f..1368c984b0 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -32,7 +32,7 @@ type API struct { type health interface { Health(ctx context.Context) error - IAMByID(ctx context.Context, id string) (*query.IAM, error) + IAM(ctx context.Context) (*query.IAM, error) } func New( @@ -107,7 +107,7 @@ func (a *API) healthHandler() http.Handler { return nil }, func(ctx context.Context) error { - iam, err := a.health.IAMByID(ctx, domain.IAMID) + iam, err := a.health.IAM(ctx) if err != nil && !errors.IsNotFound(err) { return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED") } diff --git a/internal/api/authz/context.go b/internal/api/authz/context.go index 2e90a39bdd..b219f49fcd 100644 --- a/internal/api/authz/context.go +++ b/internal/api/authz/context.go @@ -15,12 +15,12 @@ const ( requestPermissionsKey key = 1 dataKey key = 2 allPermissionsKey key = 3 + instanceKey key = 4 ) type CtxData struct { UserID string OrgID string - TenantID string //TODO: Set Tenant ID on some context ProjectID string AgentID string PreferredLanguage string @@ -31,6 +31,10 @@ func (ctxData CtxData) IsZero() bool { return ctxData.UserID == "" || ctxData.OrgID == "" } +type Instance struct { + ID string +} + type Grants []*Grant type Grant struct { @@ -43,7 +47,7 @@ type Memberships []*Membership type Membership struct { MemberType MemberType AggregateID string - //ObjectID differs from aggregate id if obejct is sub of an aggregate + //ObjectID differs from aggregate id if object is sub of an aggregate ObjectID string Roles []string @@ -112,6 +116,11 @@ func GetCtxData(ctx context.Context) CtxData { return ctxData } +func GetInstance(ctx context.Context) Instance { + instance, _ := ctx.Value(instanceKey).(Instance) + return instance +} + func GetRequestPermissionsFromCtx(ctx context.Context) []string { ctxPermission, _ := ctx.Value(requestPermissionsKey).([]string) return ctxPermission diff --git a/internal/api/authz/context_mock.go b/internal/api/authz/context_mock.go index 0dde79922f..e7b5c4017e 100644 --- a/internal/api/authz/context_mock.go +++ b/internal/api/authz/context_mock.go @@ -2,11 +2,13 @@ package authz import "context" -func NewMockContext(tenantID, orgID, userID string) context.Context { - return context.WithValue(context.Background(), dataKey, CtxData{UserID: userID, OrgID: orgID, TenantID: tenantID}) +func NewMockContext(instanceID, orgID, userID string) context.Context { + ctx := context.WithValue(context.Background(), dataKey, CtxData{UserID: userID, OrgID: orgID}) + return context.WithValue(ctx, instanceKey, instanceID) } -func NewMockContextWithPermissions(tenantID, orgID, userID string, permissions []string) context.Context { - ctx := context.WithValue(context.Background(), dataKey, CtxData{UserID: userID, OrgID: orgID, TenantID: tenantID}) +func NewMockContextWithPermissions(instanceID, orgID, userID string, permissions []string) context.Context { + ctx := context.WithValue(context.Background(), dataKey, CtxData{UserID: userID, OrgID: orgID}) + ctx = context.WithValue(ctx, instanceKey, instanceID) return context.WithValue(ctx, requestPermissionsKey, permissions) } diff --git a/internal/api/grpc/admin/language.go b/internal/api/grpc/admin/language.go index fff5b43381..259075fca5 100644 --- a/internal/api/grpc/admin/language.go +++ b/internal/api/grpc/admin/language.go @@ -3,12 +3,12 @@ package admin import ( "context" + "golang.org/x/text/language" + "github.com/caos/zitadel/internal/api/grpc/object" "github.com/caos/zitadel/internal/api/grpc/text" - "github.com/caos/zitadel/internal/domain" caos_errors "github.com/caos/zitadel/internal/errors" admin_pb "github.com/caos/zitadel/pkg/grpc/admin" - "golang.org/x/text/language" ) func (s *Server) GetSupportedLanguages(ctx context.Context, req *admin_pb.GetSupportedLanguagesRequest) (*admin_pb.GetSupportedLanguagesResponse, error) { @@ -34,9 +34,5 @@ func (s *Server) SetDefaultLanguage(ctx context.Context, req *admin_pb.SetDefaul } func (s *Server) GetDefaultLanguage(ctx context.Context, req *admin_pb.GetDefaultLanguageRequest) (*admin_pb.GetDefaultLanguageResponse, error) { - iam, err := s.query.IAMByID(ctx, domain.IAMID) - if err != nil { - return nil, err - } - return &admin_pb.GetDefaultLanguageResponse{Language: iam.DefaultLanguage.String()}, nil + return &admin_pb.GetDefaultLanguageResponse{Language: s.query.GetDefaultLanguage(ctx).String()}, nil } diff --git a/internal/api/grpc/auth/user.go b/internal/api/grpc/auth/user.go index 16ad3df195..067d2092fe 100644 --- a/internal/api/grpc/auth/user.go +++ b/internal/api/grpc/auth/user.go @@ -152,7 +152,7 @@ func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProje return nil, err } - iam, err := s.query.IAMByID(ctx, domain.IAMID) + iam, err := s.query.IAM(ctx) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/iam.go b/internal/api/grpc/management/iam.go index 03aa70a91a..65ddbb5899 100644 --- a/internal/api/grpc/management/iam.go +++ b/internal/api/grpc/management/iam.go @@ -3,12 +3,11 @@ package management import ( "context" - "github.com/caos/zitadel/internal/domain" mgmt_pb "github.com/caos/zitadel/pkg/grpc/management" ) -func (s *Server) GetIAM(ctx context.Context, req *mgmt_pb.GetIAMRequest) (*mgmt_pb.GetIAMResponse, error) { - iam, err := s.query.IAMByID(ctx, domain.IAMID) +func (s *Server) GetIAM(ctx context.Context, _ *mgmt_pb.GetIAMRequest) (*mgmt_pb.GetIAMResponse, error) { + iam, err := s.query.IAM(ctx) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/org.go b/internal/api/grpc/management/org.go index d540f95b1f..5e92cad5d8 100644 --- a/internal/api/grpc/management/org.go +++ b/internal/api/grpc/management/org.go @@ -206,8 +206,8 @@ func (s *Server) SetPrimaryOrgDomain(ctx context.Context, req *mgmt_pb.SetPrimar }, nil } -func (s *Server) ListOrgMemberRoles(ctx context.Context, req *mgmt_pb.ListOrgMemberRolesRequest) (*mgmt_pb.ListOrgMemberRolesResponse, error) { - iam, err := s.query.IAMByID(ctx, domain.IAMID) +func (s *Server) ListOrgMemberRoles(ctx context.Context, _ *mgmt_pb.ListOrgMemberRolesRequest) (*mgmt_pb.ListOrgMemberRolesResponse, error) { + iam, err := s.query.IAM(ctx) if err != nil { return nil, err } diff --git a/internal/api/http/middleware/user_agent_cookie.go b/internal/api/http/middleware/user_agent_cookie.go index 90caf559d9..176de252df 100644 --- a/internal/api/http/middleware/user_agent_cookie.go +++ b/internal/api/http/middleware/user_agent_cookie.go @@ -21,6 +21,10 @@ func UserAgentIDFromCtx(ctx context.Context) (string, bool) { return userAgentID, ok } +func InstanceIDFromCtx(ctx context.Context) string { + return "" //TODO: implement +} + type UserAgent struct { ID string } diff --git a/internal/api/oidc/auth_request.go b/internal/api/oidc/auth_request.go index ba98b572bb..79460f19a6 100644 --- a/internal/api/oidc/auth_request.go +++ b/internal/api/oidc/auth_request.go @@ -10,6 +10,7 @@ import ( "github.com/caos/oidc/pkg/oidc" "github.com/caos/oidc/pkg/op" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query" @@ -45,7 +46,8 @@ func (o *OPStorage) AuthRequestByID(ctx context.Context, id string) (_ op.AuthRe if !ok { return nil, errors.ThrowPreconditionFailed(nil, "OIDC-D3g21", "no user agent id") } - resp, err := o.repo.AuthRequestByIDCheckLoggedIn(ctx, id, userAgentID) + instanceID := authz.GetInstance(ctx).ID + resp, err := o.repo.AuthRequestByIDCheckLoggedIn(ctx, id, userAgentID, instanceID) if err != nil { return nil, err } @@ -55,7 +57,9 @@ func (o *OPStorage) AuthRequestByID(ctx context.Context, id string) (_ op.AuthRe func (o *OPStorage) AuthRequestByCode(ctx context.Context, code string) (_ op.AuthRequest, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - resp, err := o.repo.AuthRequestByCode(ctx, code) + + instanceID := authz.GetInstance(ctx).ID + resp, err := o.repo.AuthRequestByCode(ctx, code, instanceID) if err != nil { return nil, err } @@ -69,13 +73,16 @@ func (o *OPStorage) SaveAuthCode(ctx context.Context, id, code string) (err erro if !ok { return errors.ThrowPreconditionFailed(nil, "OIDC-Dgus2", "no user agent id") } - return o.repo.SaveAuthCode(ctx, id, code, userAgentID) + instanceID := authz.GetInstance(ctx).ID + return o.repo.SaveAuthCode(ctx, id, code, userAgentID, instanceID) } func (o *OPStorage) DeleteAuthRequest(ctx context.Context, id string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - return o.repo.DeleteAuthRequest(ctx, id) + + instanceID := authz.GetInstance(ctx).ID + return o.repo.DeleteAuthRequest(ctx, id, instanceID) } func (o *OPStorage) CreateAccessToken(ctx context.Context, req op.TokenRequest) (_ string, _ time.Time, err error) { diff --git a/internal/api/oidc/auth_request_converter.go b/internal/api/oidc/auth_request_converter.go index 71526adcb7..3af880deed 100644 --- a/internal/api/oidc/auth_request_converter.go +++ b/internal/api/oidc/auth_request_converter.go @@ -10,6 +10,7 @@ import ( "github.com/caos/oidc/pkg/op" "golang.org/x/text/language" + "github.com/caos/zitadel/internal/api/authz" http_utils "github.com/caos/zitadel/internal/api/http" model2 "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/domain" @@ -132,6 +133,7 @@ func CreateAuthRequestToBusiness(ctx context.Context, authReq *oidc.AuthRequest, SelectedIDPConfigID: GetSelectedIDPIDFromScopes(authReq.Scopes), MaxAuthAge: MaxAgeToBusiness(authReq.MaxAge), UserID: userID, + InstanceID: authz.GetInstance(ctx).ID, Request: &domain.AuthRequestOIDC{ Scopes: authReq.Scopes, ResponseType: ResponseTypeToBusiness(authReq.ResponseType), diff --git a/internal/api/ui/login/auth_request.go b/internal/api/ui/login/auth_request.go index d7a2984077..241aa958de 100644 --- a/internal/api/ui/login/auth_request.go +++ b/internal/api/ui/login/auth_request.go @@ -5,6 +5,7 @@ import ( "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" ) @@ -19,7 +20,8 @@ func (l *Login) getAuthRequest(r *http.Request) (*domain.AuthRequest, error) { return nil, nil } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - return l.authRepo.AuthRequestByID(r.Context(), authRequestID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + return l.authRepo.AuthRequestByID(r.Context(), authRequestID, userAgentID, instanceID) } func (l *Login) getAuthRequestAndParseData(r *http.Request, data interface{}) (*domain.AuthRequest, error) { diff --git a/internal/api/ui/login/custom_action.go b/internal/api/ui/login/custom_action.go index b4b8b75c3f..664d3c5674 100644 --- a/internal/api/ui/login/custom_action.go +++ b/internal/api/ui/login/custom_action.go @@ -16,7 +16,7 @@ func (l *Login) customExternalUserMapping(ctx context.Context, user *domain.Exte resourceOwner = config.AggregateID } if resourceOwner == domain.IAMID { - iam, err := l.query.IAMByID(ctx, domain.IAMID) + iam, err := l.query.IAM(ctx) if err != nil { return nil, err } diff --git a/internal/api/ui/login/external_login_handler.go b/internal/api/ui/login/external_login_handler.go index 13c5c672e9..166bc8474c 100644 --- a/internal/api/ui/login/external_login_handler.go +++ b/internal/api/ui/login/external_login_handler.go @@ -11,6 +11,8 @@ import ( "github.com/caos/oidc/pkg/oidc" "golang.org/x/oauth2" + "github.com/caos/zitadel/internal/api/authz" + http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" @@ -87,7 +89,8 @@ func (l *Login) handleIDP(w http.ResponseWriter, r *http.Request, authReq *domai return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID) if err != nil { l.renderLogin(w, r, authReq, err) return @@ -139,7 +142,8 @@ func (l *Login) handleExternalLoginCallback(w http.ResponseWriter, r *http.Reque return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -198,12 +202,13 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R return } - err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, userAgentID, externalUser, domain.BrowserInfoFromRequest(r)) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, userAgentID, instanceID, externalUser, domain.BrowserInfoFromRequest(r)) if err != nil { if errors.IsNotFound(err) { err = nil } - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return @@ -226,7 +231,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R l.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err) return } - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID, instanceID) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err) return @@ -235,7 +240,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R return } if len(externalUser.Metadatas) > 0 { - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID, instanceID) if err != nil { return } @@ -254,7 +259,7 @@ func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Requ errID, errMessage = l.getErrorMessage(r, err) } if orgIAMPolicy == nil { - iam, err = l.query.IAMByID(r.Context(), domain.IAMID) + iam, err = l.query.IAM(r.Context()) if err != nil { l.renderError(w, r, authReq, err) return @@ -324,7 +329,8 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http return } else if data.ResetLinking { userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID, instanceID) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) } @@ -335,7 +341,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http } func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest) { - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return @@ -362,6 +368,7 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) + instanceID := authz.GetInstance(r.Context()).ID if len(authReq.LinkingUsers) == 0 { l.renderError(w, r, authReq, caos_errors.ThrowPreconditionFailed(nil, "LOGIN-asfg3", "Errors.ExternalIDP.NoExternalUserData")) return @@ -373,12 +380,12 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, nil, nil, err) return } - err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, memberRoles, authReq.ID, userAgentID, resourceOwner, metadata, domain.BrowserInfoFromRequest(r)) + err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, memberRoles, authReq.ID, userAgentID, resourceOwner, instanceID, metadata, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, user, externalIDP, err) return } - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID, instanceID) if err != nil { l.renderError(w, r, authReq, err) return diff --git a/internal/api/ui/login/external_register_handler.go b/internal/api/ui/login/external_register_handler.go index 550a160e7a..ab3cd0ac45 100644 --- a/internal/api/ui/login/external_register_handler.go +++ b/internal/api/ui/login/external_register_handler.go @@ -8,6 +8,7 @@ import ( "github.com/caos/oidc/pkg/oidc" "golang.org/x/text/language" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/domain" iam_model "github.com/caos/zitadel/internal/iam/model" @@ -67,7 +68,8 @@ func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) { return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID) if err != nil { l.renderLogin(w, r, authReq, err) return @@ -87,7 +89,8 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -111,7 +114,7 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re } func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, userAgentID string, tokens *oidc.Tokens) { - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderRegisterOption(w, r, authReq, err) return @@ -204,7 +207,7 @@ func (l *Login) handleExternalRegisterCheck(w http.ResponseWriter, r *http.Reque return } - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderRegisterOption(w, r, authReq, err) return diff --git a/internal/api/ui/login/jwt_handler.go b/internal/api/ui/login/jwt_handler.go index b007a670e2..55b2471440 100644 --- a/internal/api/ui/login/jwt_handler.go +++ b/internal/api/ui/login/jwt_handler.go @@ -12,6 +12,7 @@ import ( "github.com/caos/oidc/pkg/client/rp" "github.com/caos/oidc/pkg/oidc" + "github.com/caos/zitadel/internal/api/authz" http_util "github.com/caos/zitadel/internal/api/http" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -44,7 +45,8 @@ func (l *Login) handleJWTRequest(w http.ResponseWriter, r *http.Request) { l.renderError(w, r, nil, err) return } - authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -82,13 +84,13 @@ func (l *Login) handleJWTExtraction(w http.ResponseWriter, r *http.Request, auth return } metadata := externalUser.Metadatas - err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, authReq.AgentID, externalUser, domain.BrowserInfoFromRequest(r)) + err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID, externalUser, domain.BrowserInfoFromRequest(r)) if err != nil { l.jwtExtractionUserNotFound(w, r, authReq, idpConfig, tokens, err) return } if len(metadata) > 0 { - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -115,7 +117,7 @@ func (l *Login) jwtExtractionUserNotFound(w http.ResponseWriter, r *http.Request l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return } - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -133,12 +135,12 @@ func (l *Login) jwtExtractionUserNotFound(w http.ResponseWriter, r *http.Request l.renderError(w, r, authReq, err) return } - err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, nil, authReq.ID, authReq.AgentID, resourceOwner, metadata, domain.BrowserInfoFromRequest(r)) + err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, nil, authReq.ID, authReq.AgentID, resourceOwner, authReq.InstanceID, metadata, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderError(w, r, authReq, err) return } - authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) + authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID) if err != nil { l.renderError(w, r, authReq, err) return @@ -207,7 +209,8 @@ func (l *Login) handleJWTCallback(w http.ResponseWriter, r *http.Request) { l.renderError(w, r, nil, err) return } - authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID) if err != nil { l.renderError(w, r, authReq, err) return diff --git a/internal/api/ui/login/link_users_handler.go b/internal/api/ui/login/link_users_handler.go index 9d56126360..e45a5b63c0 100644 --- a/internal/api/ui/login/link_users_handler.go +++ b/internal/api/ui/login/link_users_handler.go @@ -3,6 +3,7 @@ package login import ( "net/http" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/domain" ) @@ -13,7 +14,8 @@ const ( func (l *Login) linkUsers(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) { userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.LinkExternalUsers(setContext(r.Context(), authReq.UserOrgID), authReq.ID, userAgentID, domain.BrowserInfoFromRequest(r)) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.LinkExternalUsers(setContext(r.Context(), authReq.UserOrgID), authReq.ID, userAgentID, instanceID, domain.BrowserInfoFromRequest(r)) l.renderLinkUsersDone(w, r, authReq, err) } diff --git a/internal/api/ui/login/login_handler.go b/internal/api/ui/login/login_handler.go index c1400cadcf..4f9107fe89 100644 --- a/internal/api/ui/login/login_handler.go +++ b/internal/api/ui/login/login_handler.go @@ -3,6 +3,7 @@ package login import ( "net/http" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -59,8 +60,9 @@ func (l *Login) handleLoginNameCheck(w http.ResponseWriter, r *http.Request) { return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) + instanceID := authz.GetInstance(r.Context()).ID loginName := data.LoginName - err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, loginName, userAgentID) + err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, loginName, userAgentID, instanceID) if err != nil { l.renderLogin(w, r, authReq, err) return diff --git a/internal/api/ui/login/mfa_verify_handler.go b/internal/api/ui/login/mfa_verify_handler.go index f4c2d52e59..9b7fc1a755 100644 --- a/internal/api/ui/login/mfa_verify_handler.go +++ b/internal/api/ui/login/mfa_verify_handler.go @@ -3,6 +3,7 @@ package login import ( "net/http" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/domain" ) @@ -35,7 +36,8 @@ func (l *Login) handleMFAVerify(w http.ResponseWriter, r *http.Request) { } if data.MFAType == domain.MFATypeOTP { userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.VerifyMFAOTP(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Code, userAgentID, domain.BrowserInfoFromRequest(r)) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.VerifyMFAOTP(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Code, userAgentID, instanceID, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderMFAVerifySelected(w, r, authReq, step, domain.MFATypeOTP, err) return diff --git a/internal/api/ui/login/mfa_verify_u2f_handler.go b/internal/api/ui/login/mfa_verify_u2f_handler.go index 6b85213471..33c982f4b3 100644 --- a/internal/api/ui/login/mfa_verify_u2f_handler.go +++ b/internal/api/ui/login/mfa_verify_u2f_handler.go @@ -6,6 +6,7 @@ import ( "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" ) @@ -29,7 +30,8 @@ func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, au var webAuthNLogin *domain.WebAuthNLogin if err == nil { userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - webAuthNLogin, err = l.authRepo.BeginMFAU2FLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + webAuthNLogin, err = l.authRepo.BeginMFAU2FLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID) } if err != nil { errID, errMessage = l.getErrorMessage(r, err) @@ -70,7 +72,8 @@ func (l *Login) handleU2FVerification(w http.ResponseWriter, r *http.Request) { return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.VerifyMFAU2F(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, credData, domain.BrowserInfoFromRequest(r)) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.VerifyMFAU2F(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID, credData, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderU2FVerification(w, r, authReq, step.MFAProviders, err) return diff --git a/internal/api/ui/login/password_handler.go b/internal/api/ui/login/password_handler.go index ca724b747b..32e9ce84be 100644 --- a/internal/api/ui/login/password_handler.go +++ b/internal/api/ui/login/password_handler.go @@ -4,8 +4,6 @@ import ( "net/http" "github.com/caos/zitadel/internal/domain" - - http_mw "github.com/caos/zitadel/internal/api/http/middleware" ) const ( @@ -40,8 +38,7 @@ func (l *Login) handlePasswordCheck(w http.ResponseWriter, r *http.Request) { l.renderError(w, r, authReq, err) return } - userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.VerifyPassword(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Password, userAgentID, domain.BrowserInfoFromRequest(r)) + err = l.authRepo.VerifyPassword(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Password, authReq.AgentID, authReq.InstanceID, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderPassword(w, r, authReq, err) return diff --git a/internal/api/ui/login/passwordless_login_handler.go b/internal/api/ui/login/passwordless_login_handler.go index 76a8fc7c23..fa6ffe3191 100644 --- a/internal/api/ui/login/passwordless_login_handler.go +++ b/internal/api/ui/login/passwordless_login_handler.go @@ -5,8 +5,6 @@ import ( "net/http" "github.com/caos/zitadel/internal/domain" - - http_mw "github.com/caos/zitadel/internal/api/http/middleware" ) const ( @@ -27,8 +25,7 @@ func (l *Login) renderPasswordlessVerification(w http.ResponseWriter, r *http.Re var errID, errMessage, credentialData string var webAuthNLogin *domain.WebAuthNLogin if err == nil { - userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - webAuthNLogin, err = l.authRepo.BeginPasswordlessLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID) + webAuthNLogin, err = l.authRepo.BeginPasswordlessLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, authReq.AgentID, authReq.InstanceID) } if err != nil { errID, errMessage = l.getErrorMessage(r, err) @@ -65,8 +62,7 @@ func (l *Login) handlePasswordlessVerification(w http.ResponseWriter, r *http.Re l.renderPasswordlessVerification(w, r, authReq, formData.PasswordLogin, err) return } - userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.VerifyPasswordless(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, credData, domain.BrowserInfoFromRequest(r)) + err = l.authRepo.VerifyPasswordless(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, authReq.AgentID, authReq.InstanceID, credData, domain.BrowserInfoFromRequest(r)) if err != nil { l.renderPasswordlessVerification(w, r, authReq, formData.PasswordLogin, err) return diff --git a/internal/api/ui/login/register_handler.go b/internal/api/ui/login/register_handler.go index 7b2057e06c..aaaa881fe4 100644 --- a/internal/api/ui/login/register_handler.go +++ b/internal/api/ui/login/register_handler.go @@ -5,6 +5,7 @@ import ( "golang.org/x/text/language" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" @@ -61,7 +62,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { l.renderRegister(w, r, authRequest, data, err) return } - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderRegister(w, r, authRequest, data, err) return @@ -94,7 +95,8 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.SelectUser(r.Context(), authRequest.ID, user.AggregateID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.SelectUser(r.Context(), authRequest.ID, user.AggregateID, userAgentID, instanceID) if err != nil { l.renderRegister(w, r, authRequest, data, err) return @@ -125,7 +127,7 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque } if resourceOwner == "" { - iam, err := l.query.IAMByID(r.Context(), domain.IAMID) + iam, err := l.query.IAM(r.Context()) if err != nil { l.renderRegister(w, r, authRequest, formData, err) return diff --git a/internal/api/ui/login/renderer.go b/internal/api/ui/login/renderer.go index c79c4d2e8f..4e8901cf37 100644 --- a/internal/api/ui/login/renderer.go +++ b/internal/api/ui/login/renderer.go @@ -224,8 +224,7 @@ func (l *Login) renderNextStep(w http.ResponseWriter, r *http.Request, authReq * l.renderInternalError(w, r, nil, caos_errs.ThrowInvalidArgument(nil, "LOGIN-Df3f2", "Errors.AuthRequest.NotFound")) return } - userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - authReq, err := l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID) + authReq, err := l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID, authReq.InstanceID) if err != nil { l.renderInternalError(w, r, authReq, err) return diff --git a/internal/api/ui/login/select_user_handler.go b/internal/api/ui/login/select_user_handler.go index aad30927e8..99efecbfe2 100644 --- a/internal/api/ui/login/select_user_handler.go +++ b/internal/api/ui/login/select_user_handler.go @@ -5,6 +5,7 @@ import ( "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/api/authz" http_mw "github.com/caos/zitadel/internal/api/http/middleware" ) @@ -38,7 +39,8 @@ func (l *Login) handleSelectUser(w http.ResponseWriter, r *http.Request) { return } userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) - err = l.authRepo.SelectUser(r.Context(), authSession.ID, data.UserID, userAgentID) + instanceID := authz.GetInstance(r.Context()).ID + err = l.authRepo.SelectUser(r.Context(), authSession.ID, data.UserID, userAgentID, instanceID) if err != nil { l.renderError(w, r, authSession, err) return diff --git a/internal/auth/repository/auth_request.go b/internal/auth/repository/auth_request.go index 423d7f453e..79eb549969 100644 --- a/internal/auth/repository/auth_request.go +++ b/internal/auth/repository/auth_request.go @@ -8,30 +8,30 @@ import ( type AuthRequestRepository interface { CreateAuthRequest(ctx context.Context, request *domain.AuthRequest) (*domain.AuthRequest, error) - AuthRequestByID(ctx context.Context, id, userAgentID string) (*domain.AuthRequest, error) - AuthRequestByIDCheckLoggedIn(ctx context.Context, id, userAgentID string) (*domain.AuthRequest, error) - AuthRequestByCode(ctx context.Context, code string) (*domain.AuthRequest, error) - SaveAuthCode(ctx context.Context, id, code, userAgentID string) error - DeleteAuthRequest(ctx context.Context, id string) error + AuthRequestByID(ctx context.Context, id, userAgentID, instanceID string) (*domain.AuthRequest, error) + AuthRequestByIDCheckLoggedIn(ctx context.Context, id, userAgentID, instanceID string) (*domain.AuthRequest, error) + AuthRequestByCode(ctx context.Context, code, instanceID string) (*domain.AuthRequest, error) + SaveAuthCode(ctx context.Context, id, code, userAgentID, instanceID string) error + DeleteAuthRequest(ctx context.Context, id, instanceID string) error - CheckLoginName(ctx context.Context, id, loginName, userAgentID string) error - CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser, info *domain.BrowserInfo) error - SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser) error - SelectUser(ctx context.Context, id, userID, userAgentID string) error - SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID string) error - VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID string, info *domain.BrowserInfo) error + CheckLoginName(ctx context.Context, id, loginName, userAgentID, instanceID string) error + CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID, instanceID string, user *domain.ExternalUser, info *domain.BrowserInfo) error + SetExternalUserLogin(ctx context.Context, authReqID, userAgentID, instanceID string, user *domain.ExternalUser) error + SelectUser(ctx context.Context, id, userID, userAgentID, instanceID string) error + SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID, instanceID string) error + VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID, instanceID string, info *domain.BrowserInfo) error - VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID string, info *domain.BrowserInfo) error - BeginMFAU2FLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string) (*domain.WebAuthNLogin, error) - VerifyMFAU2F(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string, credentialData []byte, info *domain.BrowserInfo) error + VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID, instanceID string, info *domain.BrowserInfo) error + BeginMFAU2FLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string) (*domain.WebAuthNLogin, error) + VerifyMFAU2F(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string, credentialData []byte, info *domain.BrowserInfo) error BeginPasswordlessSetup(ctx context.Context, userID, resourceOwner string, preferredPlatformType domain.AuthenticatorAttachment) (login *domain.WebAuthNToken, err error) VerifyPasswordlessSetup(ctx context.Context, userID, resourceOwner, userAgentID, tokenName string, credentialData []byte) (err error) BeginPasswordlessInitCodeSetup(ctx context.Context, userID, resourceOwner, codeID, verificationCode string, preferredPlatformType domain.AuthenticatorAttachment) (login *domain.WebAuthNToken, err error) VerifyPasswordlessInitCodeSetup(ctx context.Context, userID, resourceOwner, userAgentID, tokenName, codeID, verificationCode string, credentialData []byte) (err error) - BeginPasswordlessLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string) (*domain.WebAuthNLogin, error) - VerifyPasswordless(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string, credentialData []byte, info *domain.BrowserInfo) error + BeginPasswordlessLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string) (*domain.WebAuthNLogin, error) + VerifyPasswordless(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string, credentialData []byte, info *domain.BrowserInfo) error - LinkExternalUsers(ctx context.Context, authReqID, userAgentID string, info *domain.BrowserInfo) error - AutoRegisterExternalUser(ctx context.Context, user *domain.Human, externalIDP *domain.UserIDPLink, orgMemberRoles []string, authReqID, userAgentID, resourceOwner string, metadatas []*domain.Metadata, info *domain.BrowserInfo) error - ResetLinkingUsers(ctx context.Context, authReqID, userAgentID string) error + LinkExternalUsers(ctx context.Context, authReqID, userAgentID, instanceID string, info *domain.BrowserInfo) error + AutoRegisterExternalUser(ctx context.Context, user *domain.Human, externalIDP *domain.UserIDPLink, orgMemberRoles []string, authReqID, userAgentID, resourceOwner, instanceID string, metadatas []*domain.Metadata, info *domain.BrowserInfo) error + ResetLinkingUsers(ctx context.Context, authReqID, userAgentID, instanceID string) error } diff --git a/internal/auth/repository/eventsourcing/eventstore/auth_request.go b/internal/auth/repository/eventsourcing/eventstore/auth_request.go index 71a5ad4068..f3326a4567 100644 --- a/internal/auth/repository/eventsourcing/eventstore/auth_request.go +++ b/internal/auth/repository/eventsourcing/eventstore/auth_request.go @@ -156,22 +156,22 @@ func (repo *AuthRequestRepo) CreateAuthRequest(ctx context.Context, request *dom return request, nil } -func (repo *AuthRequestRepo) AuthRequestByID(ctx context.Context, id, userAgentID string) (_ *domain.AuthRequest, err error) { +func (repo *AuthRequestRepo) AuthRequestByID(ctx context.Context, id, userAgentID, instanceID string) (_ *domain.AuthRequest, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - return repo.getAuthRequestNextSteps(ctx, id, userAgentID, false) + return repo.getAuthRequestNextSteps(ctx, id, userAgentID, instanceID, false) } -func (repo *AuthRequestRepo) AuthRequestByIDCheckLoggedIn(ctx context.Context, id, userAgentID string) (_ *domain.AuthRequest, err error) { +func (repo *AuthRequestRepo) AuthRequestByIDCheckLoggedIn(ctx context.Context, id, userAgentID, instanceID string) (_ *domain.AuthRequest, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - return repo.getAuthRequestNextSteps(ctx, id, userAgentID, true) + return repo.getAuthRequestNextSteps(ctx, id, userAgentID, instanceID, true) } -func (repo *AuthRequestRepo) SaveAuthCode(ctx context.Context, id, code, userAgentID string) (err error) { +func (repo *AuthRequestRepo) SaveAuthCode(ctx context.Context, id, code, userAgentID, instanceID string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, id, userAgentID) + request, err := repo.getAuthRequest(ctx, id, userAgentID, instanceID) if err != nil { return err } @@ -179,10 +179,10 @@ func (repo *AuthRequestRepo) SaveAuthCode(ctx context.Context, id, code, userAge return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) AuthRequestByCode(ctx context.Context, code string) (_ *domain.AuthRequest, err error) { +func (repo *AuthRequestRepo) AuthRequestByCode(ctx context.Context, code, instanceID string) (_ *domain.AuthRequest, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.AuthRequests.GetAuthRequestByCode(ctx, code) + request, err := repo.AuthRequests.GetAuthRequestByCode(ctx, code, instanceID) if err != nil { return nil, err } @@ -198,16 +198,16 @@ func (repo *AuthRequestRepo) AuthRequestByCode(ctx context.Context, code string) return request, nil } -func (repo *AuthRequestRepo) DeleteAuthRequest(ctx context.Context, id string) (err error) { +func (repo *AuthRequestRepo) DeleteAuthRequest(ctx context.Context, id, instanceID string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - return repo.AuthRequests.DeleteAuthRequest(ctx, id) + return repo.AuthRequests.DeleteAuthRequest(ctx, id, instanceID) } -func (repo *AuthRequestRepo) CheckLoginName(ctx context.Context, id, loginName, userAgentID string) (err error) { +func (repo *AuthRequestRepo) CheckLoginName(ctx context.Context, id, loginName, userAgentID, instanceID string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, id, userAgentID) + request, err := repo.getAuthRequest(ctx, id, userAgentID, instanceID) if err != nil { return err } @@ -218,10 +218,10 @@ func (repo *AuthRequestRepo) CheckLoginName(ctx context.Context, id, loginName, return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID string) (err error) { +func (repo *AuthRequestRepo) SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID, instanceID string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -232,10 +232,10 @@ func (repo *AuthRequestRepo) SelectExternalIDP(ctx context.Context, authReqID, i return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID string, externalUser *domain.ExternalUser, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID, instanceID string, externalUser *domain.ExternalUser, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -257,10 +257,10 @@ func (repo *AuthRequestRepo) CheckExternalUserLogin(ctx context.Context, authReq return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, externalUser *domain.ExternalUser) (err error) { +func (repo *AuthRequestRepo) SetExternalUserLogin(ctx context.Context, authReqID, userAgentID, instanceID string, externalUser *domain.ExternalUser) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -277,10 +277,10 @@ func (repo *AuthRequestRepo) setLinkingUser(ctx context.Context, request *domain return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID, userAgentID string) (err error) { +func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID, userAgentID, instanceID string) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, id, userAgentID) + request, err := repo.getAuthRequest(ctx, id, userAgentID, instanceID) if err != nil { return err } @@ -299,10 +299,10 @@ func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID, userAge return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID string, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID, instanceID string, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, id, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, id, userAgentID, userID, instanceID) if err != nil { return err } @@ -328,31 +328,31 @@ func lockoutPolicyToDomain(policy *query.LockoutPolicy) *domain.LockoutPolicy { } } -func (repo *AuthRequestRepo) VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID string, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) VerifyMFAOTP(ctx context.Context, authRequestID, userID, resourceOwner, code, userAgentID, instanceID string, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID, instanceID) if err != nil { return err } return repo.Command.HumanCheckMFAOTP(ctx, userID, code, resourceOwner, request.WithCurrentInfo(info)) } -func (repo *AuthRequestRepo) BeginMFAU2FLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string) (login *domain.WebAuthNLogin, err error) { +func (repo *AuthRequestRepo) BeginMFAU2FLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string) (login *domain.WebAuthNLogin, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID, instanceID) if err != nil { return nil, err } return repo.Command.HumanBeginU2FLogin(ctx, userID, resourceOwner, request, true) } -func (repo *AuthRequestRepo) VerifyMFAU2F(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string, credentialData []byte, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) VerifyMFAU2F(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string, credentialData []byte, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID, instanceID) if err != nil { return err } @@ -393,30 +393,30 @@ func (repo *AuthRequestRepo) VerifyPasswordlessInitCodeSetup(ctx context.Context return err } -func (repo *AuthRequestRepo) BeginPasswordlessLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string) (login *domain.WebAuthNLogin, err error) { +func (repo *AuthRequestRepo) BeginPasswordlessLogin(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string) (login *domain.WebAuthNLogin, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID, instanceID) if err != nil { return nil, err } return repo.Command.HumanBeginPasswordlessLogin(ctx, userID, resourceOwner, request, true) } -func (repo *AuthRequestRepo) VerifyPasswordless(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID string, credentialData []byte, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) VerifyPasswordless(ctx context.Context, userID, resourceOwner, authRequestID, userAgentID, instanceID string, credentialData []byte, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID) + request, err := repo.getAuthRequestEnsureUser(ctx, authRequestID, userAgentID, userID, instanceID) if err != nil { return err } return repo.Command.HumanFinishPasswordlessLogin(ctx, userID, resourceOwner, credentialData, request, true) } -func (repo *AuthRequestRepo) LinkExternalUsers(ctx context.Context, authReqID, userAgentID string, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) LinkExternalUsers(ctx context.Context, authReqID, userAgentID, instanceID string, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -432,8 +432,8 @@ func (repo *AuthRequestRepo) LinkExternalUsers(ctx context.Context, authReqID, u return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) ResetLinkingUsers(ctx context.Context, authReqID, userAgentID string) error { - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) +func (repo *AuthRequestRepo) ResetLinkingUsers(ctx context.Context, authReqID, userAgentID, instanceID string) error { + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -442,10 +442,10 @@ func (repo *AuthRequestRepo) ResetLinkingUsers(ctx context.Context, authReqID, u return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) AutoRegisterExternalUser(ctx context.Context, registerUser *domain.Human, externalIDP *domain.UserIDPLink, orgMemberRoles []string, authReqID, userAgentID, resourceOwner string, metadatas []*domain.Metadata, info *domain.BrowserInfo) (err error) { +func (repo *AuthRequestRepo) AutoRegisterExternalUser(ctx context.Context, registerUser *domain.Human, externalIDP *domain.UserIDPLink, orgMemberRoles []string, authReqID, userAgentID, resourceOwner, instanceID string, metadatas []*domain.Metadata, info *domain.BrowserInfo) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - request, err := repo.getAuthRequest(ctx, authReqID, userAgentID) + request, err := repo.getAuthRequest(ctx, authReqID, userAgentID, instanceID) if err != nil { return err } @@ -478,8 +478,8 @@ func (repo *AuthRequestRepo) AutoRegisterExternalUser(ctx context.Context, regis return repo.AuthRequests.UpdateAuthRequest(ctx, request) } -func (repo *AuthRequestRepo) getAuthRequestNextSteps(ctx context.Context, id, userAgentID string, checkLoggedIn bool) (*domain.AuthRequest, error) { - request, err := repo.getAuthRequest(ctx, id, userAgentID) +func (repo *AuthRequestRepo) getAuthRequestNextSteps(ctx context.Context, id, userAgentID, instanceID string, checkLoggedIn bool) (*domain.AuthRequest, error) { + request, err := repo.getAuthRequest(ctx, id, userAgentID, instanceID) if err != nil { return nil, err } @@ -491,8 +491,8 @@ func (repo *AuthRequestRepo) getAuthRequestNextSteps(ctx context.Context, id, us return request, nil } -func (repo *AuthRequestRepo) getAuthRequestEnsureUser(ctx context.Context, authRequestID, userAgentID, userID string) (*domain.AuthRequest, error) { - request, err := repo.getAuthRequest(ctx, authRequestID, userAgentID) +func (repo *AuthRequestRepo) getAuthRequestEnsureUser(ctx context.Context, authRequestID, userAgentID, userID, instanceID string) (*domain.AuthRequest, error) { + request, err := repo.getAuthRequest(ctx, authRequestID, userAgentID, instanceID) if err != nil { return nil, err } @@ -506,8 +506,8 @@ func (repo *AuthRequestRepo) getAuthRequestEnsureUser(ctx context.Context, authR return request, nil } -func (repo *AuthRequestRepo) getAuthRequest(ctx context.Context, id, userAgentID string) (*domain.AuthRequest, error) { - request, err := repo.AuthRequests.GetAuthRequestByID(ctx, id) +func (repo *AuthRequestRepo) getAuthRequest(ctx context.Context, id, userAgentID, instanceID string) (*domain.AuthRequest, error) { + request, err := repo.AuthRequests.GetAuthRequestByID(ctx, id, instanceID) if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/org_project_mapping.go b/internal/auth/repository/eventsourcing/handler/org_project_mapping.go index 8c6cb85712..040d60bfbf 100644 --- a/internal/auth/repository/eventsourcing/handler/org_project_mapping.go +++ b/internal/auth/repository/eventsourcing/handler/org_project_mapping.go @@ -3,7 +3,7 @@ package handler import ( "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore/v1" + v1 "github.com/caos/zitadel/internal/eventstore/v1" es_models "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/eventstore/v1/query" "github.com/caos/zitadel/internal/eventstore/v1/spooler" @@ -76,6 +76,7 @@ func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) { case model.ProjectAdded: mapping.OrgID = event.ResourceOwner mapping.ProjectID = event.AggregateID + mapping.InstanceID = event.InstanceID case model.ProjectRemoved: err := p.view.DeleteOrgProjectMappingsByProjectID(event.AggregateID) if err == nil { @@ -87,6 +88,7 @@ func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) { mapping.OrgID = projectGrant.GrantedOrgID mapping.ProjectID = event.AggregateID mapping.ProjectGrantID = projectGrant.GrantID + mapping.InstanceID = projectGrant.InstanceID case model.ProjectGrantRemoved: projectGrant := new(view_model.ProjectGrant) projectGrant.SetData(event) diff --git a/internal/auth/repository/eventsourcing/handler/user_session.go b/internal/auth/repository/eventsourcing/handler/user_session.go index 4b9cede173..2cd3dc0bea 100644 --- a/internal/auth/repository/eventsourcing/handler/user_session.go +++ b/internal/auth/repository/eventsourcing/handler/user_session.go @@ -2,9 +2,10 @@ package handler import ( "github.com/caos/logging" + req_model "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" + v1 "github.com/caos/zitadel/internal/eventstore/v1" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/eventstore/v1/query" "github.com/caos/zitadel/internal/eventstore/v1/spooler" @@ -104,6 +105,7 @@ func (u *UserSession) Reduce(event *models.Event) (err error) { UserAgentID: eventData.UserAgentID, UserID: event.AggregateID, State: int32(req_model.UserSessionStateActive), + InstanceID: event.InstanceID, } } return u.updateSession(session, event) diff --git a/internal/auth_request/repository/cache/cache.go b/internal/auth_request/repository/cache/cache.go index e32df8983b..83d8726e91 100644 --- a/internal/auth_request/repository/cache/cache.go +++ b/internal/auth_request/repository/cache/cache.go @@ -26,38 +26,38 @@ func (c *AuthRequestCache) Health(ctx context.Context) error { return c.client.PingContext(ctx) } -func (c *AuthRequestCache) GetAuthRequestByID(_ context.Context, id string) (*domain.AuthRequest, error) { - return c.getAuthRequest("id", id) +func (c *AuthRequestCache) GetAuthRequestByID(_ context.Context, id, instanceID string) (*domain.AuthRequest, error) { + return c.getAuthRequest("id", id, instanceID) } -func (c *AuthRequestCache) GetAuthRequestByCode(_ context.Context, code string) (*domain.AuthRequest, error) { - return c.getAuthRequest("code", code) +func (c *AuthRequestCache) GetAuthRequestByCode(_ context.Context, code, instanceID string) (*domain.AuthRequest, error) { + return c.getAuthRequest("code", code, instanceID) } func (c *AuthRequestCache) SaveAuthRequest(_ context.Context, request *domain.AuthRequest) error { - return c.saveAuthRequest(request, "INSERT INTO auth.auth_requests (id, request, creation_date, change_date, request_type) VALUES($1, $2, $3, $3, $4)", request.CreationDate, request.Request.Type()) + return c.saveAuthRequest(request, "INSERT INTO auth.auth_requests (id, request, instance_id, creation_date, change_date, request_type) VALUES($1, $2, $3, $3, $4, $5)", request.CreationDate, request.InstanceID, request.Request.Type()) } func (c *AuthRequestCache) UpdateAuthRequest(_ context.Context, request *domain.AuthRequest) error { if request.ChangeDate.IsZero() { request.ChangeDate = time.Now() } - return c.saveAuthRequest(request, "UPDATE auth.auth_requests SET request = $2, change_date = $3, code = $4 WHERE id = $1", request.ChangeDate, request.Code) + return c.saveAuthRequest(request, "UPDATE auth.auth_requests SET request = $2, instance_id = $3 change_date = $4, code = $5 WHERE id = $1", request.ChangeDate, request.InstanceID, request.Code) } -func (c *AuthRequestCache) DeleteAuthRequest(_ context.Context, id string) error { - _, err := c.client.Exec("DELETE FROM auth.auth_requests WHERE id = $1", id) +func (c *AuthRequestCache) DeleteAuthRequest(_ context.Context, id, instanceID string) error { + _, err := c.client.Exec("DELETE FROM auth.auth_requests WHERE instance = $1 and id = $2", instanceID, id) if err != nil { return caos_errs.ThrowInternal(err, "CACHE-dsHw3", "unable to delete auth request") } return nil } -func (c *AuthRequestCache) getAuthRequest(key, value string) (*domain.AuthRequest, error) { +func (c *AuthRequestCache) getAuthRequest(key, value, instanceID string) (*domain.AuthRequest, error) { var b []byte var requestType domain.AuthRequestType - query := fmt.Sprintf("SELECT request, request_type FROM auth.auth_requests WHERE %s = $1", key) - err := c.client.QueryRow(query, value).Scan(&b, &requestType) + query := fmt.Sprintf("SELECT request, request_type FROM auth.auth_requests WHERE instance = $1 and %s = $2", key) + err := c.client.QueryRow(query, instanceID, value).Scan(&b, &requestType) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, caos_errs.ThrowNotFound(err, "CACHE-d24aD", "Errors.AuthRequest.NotFound") @@ -74,7 +74,7 @@ func (c *AuthRequestCache) getAuthRequest(key, value string) (*domain.AuthReques return request, nil } -func (c *AuthRequestCache) saveAuthRequest(request *domain.AuthRequest, query string, date time.Time, param interface{}) error { +func (c *AuthRequestCache) saveAuthRequest(request *domain.AuthRequest, query string, date time.Time, instanceID string, param interface{}) error { b, err := json.Marshal(request) if err != nil { return caos_errs.ThrowInternal(err, "CACHE-os0GH", "Errors.Internal") @@ -83,7 +83,7 @@ func (c *AuthRequestCache) saveAuthRequest(request *domain.AuthRequest, query st if err != nil { return caos_errs.ThrowInternal(err, "CACHE-su3GK", "Errors.Internal") } - _, err = stmt.Exec(request.ID, b, date, param) + _, err = stmt.Exec(request.ID, b, date, instanceID, param) if err != nil { return caos_errs.ThrowInternal(err, "CACHE-sj8iS", "Errors.Internal") } diff --git a/internal/auth_request/repository/mock/repository.mock.go b/internal/auth_request/repository/mock/repository.mock.go index 54669d9f60..8f40e3d2aa 100644 --- a/internal/auth_request/repository/mock/repository.mock.go +++ b/internal/auth_request/repository/mock/repository.mock.go @@ -6,79 +6,80 @@ package mock import ( context "context" + reflect "reflect" + domain "github.com/caos/zitadel/internal/domain" gomock "github.com/golang/mock/gomock" - reflect "reflect" ) -// MockAuthRequestCache is a mock of AuthRequestCache interface +// MockAuthRequestCache is a mock of AuthRequestCache interface. type MockAuthRequestCache struct { ctrl *gomock.Controller recorder *MockAuthRequestCacheMockRecorder } -// MockAuthRequestCacheMockRecorder is the mock recorder for MockAuthRequestCache +// MockAuthRequestCacheMockRecorder is the mock recorder for MockAuthRequestCache. type MockAuthRequestCacheMockRecorder struct { mock *MockAuthRequestCache } -// NewMockAuthRequestCache creates a new mock instance +// NewMockAuthRequestCache creates a new mock instance. func NewMockAuthRequestCache(ctrl *gomock.Controller) *MockAuthRequestCache { mock := &MockAuthRequestCache{ctrl: ctrl} mock.recorder = &MockAuthRequestCacheMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockAuthRequestCache) EXPECT() *MockAuthRequestCacheMockRecorder { return m.recorder } -// DeleteAuthRequest mocks base method -func (m *MockAuthRequestCache) DeleteAuthRequest(arg0 context.Context, arg1 string) error { +// DeleteAuthRequest mocks base method. +func (m *MockAuthRequestCache) DeleteAuthRequest(arg0 context.Context, arg1, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteAuthRequest", arg0, arg1) + ret := m.ctrl.Call(m, "DeleteAuthRequest", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// DeleteAuthRequest indicates an expected call of DeleteAuthRequest -func (mr *MockAuthRequestCacheMockRecorder) DeleteAuthRequest(arg0, arg1 interface{}) *gomock.Call { +// DeleteAuthRequest indicates an expected call of DeleteAuthRequest. +func (mr *MockAuthRequestCacheMockRecorder) DeleteAuthRequest(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAuthRequest", reflect.TypeOf((*MockAuthRequestCache)(nil).DeleteAuthRequest), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAuthRequest", reflect.TypeOf((*MockAuthRequestCache)(nil).DeleteAuthRequest), arg0, arg1, arg2) } -// GetAuthRequestByCode mocks base method -func (m *MockAuthRequestCache) GetAuthRequestByCode(arg0 context.Context, arg1 string) (*domain.AuthRequest, error) { +// GetAuthRequestByCode mocks base method. +func (m *MockAuthRequestCache) GetAuthRequestByCode(arg0 context.Context, arg1, arg2 string) (*domain.AuthRequest, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAuthRequestByCode", arg0, arg1) + ret := m.ctrl.Call(m, "GetAuthRequestByCode", arg0, arg1, arg2) ret0, _ := ret[0].(*domain.AuthRequest) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAuthRequestByCode indicates an expected call of GetAuthRequestByCode -func (mr *MockAuthRequestCacheMockRecorder) GetAuthRequestByCode(arg0, arg1 interface{}) *gomock.Call { +// GetAuthRequestByCode indicates an expected call of GetAuthRequestByCode. +func (mr *MockAuthRequestCacheMockRecorder) GetAuthRequestByCode(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthRequestByCode", reflect.TypeOf((*MockAuthRequestCache)(nil).GetAuthRequestByCode), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthRequestByCode", reflect.TypeOf((*MockAuthRequestCache)(nil).GetAuthRequestByCode), arg0, arg1, arg2) } -// GetAuthRequestByID mocks base method -func (m *MockAuthRequestCache) GetAuthRequestByID(arg0 context.Context, arg1 string) (*domain.AuthRequest, error) { +// GetAuthRequestByID mocks base method. +func (m *MockAuthRequestCache) GetAuthRequestByID(arg0 context.Context, arg1, arg2 string) (*domain.AuthRequest, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAuthRequestByID", arg0, arg1) + ret := m.ctrl.Call(m, "GetAuthRequestByID", arg0, arg1, arg2) ret0, _ := ret[0].(*domain.AuthRequest) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAuthRequestByID indicates an expected call of GetAuthRequestByID -func (mr *MockAuthRequestCacheMockRecorder) GetAuthRequestByID(arg0, arg1 interface{}) *gomock.Call { +// GetAuthRequestByID indicates an expected call of GetAuthRequestByID. +func (mr *MockAuthRequestCacheMockRecorder) GetAuthRequestByID(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthRequestByID", reflect.TypeOf((*MockAuthRequestCache)(nil).GetAuthRequestByID), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthRequestByID", reflect.TypeOf((*MockAuthRequestCache)(nil).GetAuthRequestByID), arg0, arg1, arg2) } -// Health mocks base method +// Health mocks base method. func (m *MockAuthRequestCache) Health(arg0 context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Health", arg0) @@ -86,13 +87,13 @@ func (m *MockAuthRequestCache) Health(arg0 context.Context) error { return ret0 } -// Health indicates an expected call of Health +// Health indicates an expected call of Health. func (mr *MockAuthRequestCacheMockRecorder) Health(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Health", reflect.TypeOf((*MockAuthRequestCache)(nil).Health), arg0) } -// SaveAuthRequest mocks base method +// SaveAuthRequest mocks base method. func (m *MockAuthRequestCache) SaveAuthRequest(arg0 context.Context, arg1 *domain.AuthRequest) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SaveAuthRequest", arg0, arg1) @@ -100,13 +101,13 @@ func (m *MockAuthRequestCache) SaveAuthRequest(arg0 context.Context, arg1 *domai return ret0 } -// SaveAuthRequest indicates an expected call of SaveAuthRequest +// SaveAuthRequest indicates an expected call of SaveAuthRequest. func (mr *MockAuthRequestCacheMockRecorder) SaveAuthRequest(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveAuthRequest", reflect.TypeOf((*MockAuthRequestCache)(nil).SaveAuthRequest), arg0, arg1) } -// UpdateAuthRequest mocks base method +// UpdateAuthRequest mocks base method. func (m *MockAuthRequestCache) UpdateAuthRequest(arg0 context.Context, arg1 *domain.AuthRequest) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpdateAuthRequest", arg0, arg1) @@ -114,7 +115,7 @@ func (m *MockAuthRequestCache) UpdateAuthRequest(arg0 context.Context, arg1 *dom return ret0 } -// UpdateAuthRequest indicates an expected call of UpdateAuthRequest +// UpdateAuthRequest indicates an expected call of UpdateAuthRequest. func (mr *MockAuthRequestCacheMockRecorder) UpdateAuthRequest(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAuthRequest", reflect.TypeOf((*MockAuthRequestCache)(nil).UpdateAuthRequest), arg0, arg1) diff --git a/internal/auth_request/repository/repository.go b/internal/auth_request/repository/repository.go index 32c3cf86e6..b86fb74ab6 100644 --- a/internal/auth_request/repository/repository.go +++ b/internal/auth_request/repository/repository.go @@ -2,15 +2,16 @@ package repository import ( "context" + "github.com/caos/zitadel/internal/domain" ) type AuthRequestCache interface { Health(ctx context.Context) error - GetAuthRequestByID(ctx context.Context, id string) (*domain.AuthRequest, error) - GetAuthRequestByCode(ctx context.Context, code string) (*domain.AuthRequest, error) + GetAuthRequestByID(ctx context.Context, id, instanceID string) (*domain.AuthRequest, error) + GetAuthRequestByCode(ctx context.Context, code, instanceID string) (*domain.AuthRequest, error) SaveAuthRequest(ctx context.Context, request *domain.AuthRequest) error UpdateAuthRequest(ctx context.Context, request *domain.AuthRequest) error - DeleteAuthRequest(ctx context.Context, id string) error + DeleteAuthRequest(ctx context.Context, id, instanceID string) error } diff --git a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go index 6e7d873db7..4e2427e54b 100644 --- a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go +++ b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go @@ -236,7 +236,7 @@ func (repo *TokenVerifierRepo) VerifierClientID(ctx context.Context, appName str ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - iam, err := repo.Query.IAMByID(ctx, domain.IAMID) + iam, err := repo.Query.IAM(ctx) if err != nil { return "", "", err } diff --git a/internal/authz/repository/eventsourcing/eventstore/user_membership.go b/internal/authz/repository/eventsourcing/eventstore/user_membership.go index 2da622af61..411787ab2c 100644 --- a/internal/authz/repository/eventsourcing/eventstore/user_membership.go +++ b/internal/authz/repository/eventsourcing/eventstore/user_membership.go @@ -28,6 +28,7 @@ func (repo *UserMembershipRepo) SearchMyMemberships(ctx context.Context) ([]*aut func (repo *UserMembershipRepo) searchUserMemberships(ctx context.Context) ([]*user_view_model.UserMembershipView, error) { ctxData := authz.GetCtxData(ctx) + instance := authz.GetInstance(ctx) orgMemberships, orgCount, err := repo.View.SearchUserMemberships(&user_model.UserMembershipSearchRequest{ Queries: []*user_model.UserMembershipSearchQuery{ { @@ -40,6 +41,11 @@ func (repo *UserMembershipRepo) searchUserMemberships(ctx context.Context) ([]*u Method: domain.SearchMethodEquals, Value: ctxData.OrgID, }, + { + Key: user_model.UserMembershipSearchKeyInstanceID, + Method: domain.SearchMethodEquals, + Value: instance.ID, + }, }, }) if err != nil { @@ -57,6 +63,11 @@ func (repo *UserMembershipRepo) searchUserMemberships(ctx context.Context) ([]*u Method: domain.SearchMethodEquals, Value: domain.IAMID, }, + { + Key: user_model.UserMembershipSearchKeyInstanceID, + Method: domain.SearchMethodEquals, + Value: instance.ID, + }, }, }) if err != nil { diff --git a/internal/authz/repository/eventsourcing/handler/handler.go b/internal/authz/repository/eventsourcing/handler/handler.go index 8fd9014e25..ec97ad8806 100644 --- a/internal/authz/repository/eventsourcing/handler/handler.go +++ b/internal/authz/repository/eventsourcing/handler/handler.go @@ -30,8 +30,6 @@ func (h *handler) Eventstore() v1.Eventstore { func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, systemDefaults sd.SystemDefaults) []query.Handler { return []query.Handler{ - newUserGrant( - handler{view, bulkLimit, configs.cycleDuration("UserGrants"), errorCount, es}), newUserMembership( handler{view, bulkLimit, configs.cycleDuration("UserMemberships"), errorCount, es}), } diff --git a/internal/authz/repository/eventsourcing/handler/user_grant.go b/internal/authz/repository/eventsourcing/handler/user_grant.go deleted file mode 100644 index e0dd933739..0000000000 --- a/internal/authz/repository/eventsourcing/handler/user_grant.go +++ /dev/null @@ -1,313 +0,0 @@ -package handler - -import ( - "context" - "strings" - - v1 "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - - "github.com/caos/logging" - - "github.com/caos/zitadel/internal/domain" - "github.com/caos/zitadel/internal/errors" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model" -) - -const ( - userGrantTable = "authz.user_grants" -) - -type UserGrant struct { - handler - iamProjectID string - subscription *v1.Subscription -} - -func newUserGrant( - handler handler, -) *UserGrant { - h := &UserGrant{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (k *UserGrant) subscribe() { - k.subscription = k.es.Subscribe(k.AggregateTypes()...) - go func() { - for event := range k.subscription.Events { - query.ReduceEvent(k, event) - } - }() -} - -func (u *UserGrant) ViewModel() string { - return userGrantTable -} - -func (u *UserGrant) Subscription() *v1.Subscription { - return u.subscription -} - -func (_ *UserGrant) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate} -} - -func (u *UserGrant) CurrentSequence() (uint64, error) { - sequence, err := u.view.GetLatestUserGrantSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (u *UserGrant) EventQuery() (*es_models.SearchQuery, error) { - if u.iamProjectID == "" { - err := u.setIamProjectID() - if err != nil { - return nil, err - } - } - sequence, err := u.view.GetLatestUserGrantSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (u *UserGrant) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case proj_es_model.ProjectAggregate: - err = u.processProject(event) - case iam_es_model.IAMAggregate: - err = u.processIAMMember(event, "IAM", false) - case org_es_model.OrgAggregate: - return u.processOrg(event) - } - return err -} - -func (u *UserGrant) processProject(event *es_models.Event) (err error) { - switch event.Type { - case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectMemberChanged, - proj_es_model.ProjectMemberRemoved, proj_es_model.ProjectMemberCascadeRemoved: - member := new(proj_es_model.ProjectMember) - err := member.SetData(event) - if err != nil { - return err - } - return u.processMember(event, "PROJECT", event.AggregateID, member.UserID, member.Roles) - case proj_es_model.ProjectGrantMemberAdded, proj_es_model.ProjectGrantMemberChanged, - proj_es_model.ProjectGrantMemberRemoved, - proj_es_model.ProjectGrantMemberCascadeRemoved: - member := new(proj_es_model.ProjectGrantMember) - err := member.SetData(event) - if err != nil { - return err - } - return u.processMember(event, "PROJECT_GRANT", member.GrantID, member.UserID, member.Roles) - default: - return u.view.ProcessedUserGrantSequence(event) - } -} - -func (u *UserGrant) processOrg(event *es_models.Event) (err error) { - switch event.Type { - case org_es_model.OrgMemberAdded, org_es_model.OrgMemberChanged, - org_es_model.OrgMemberRemoved, org_es_model.OrgMemberCascadeRemoved: - member := new(org_es_model.OrgMember) - err := member.SetData(event) - if err != nil { - return err - } - return u.processMember(event, "ORG", "", member.UserID, member.Roles) - default: - return u.view.ProcessedUserGrantSequence(event) - } -} - -func (u *UserGrant) processIAMMember(event *es_models.Event, rolePrefix string, suffix bool) error { - member := new(iam_es_model.IAMMember) - - switch event.Type { - case iam_es_model.IAMMemberAdded, iam_es_model.IAMMemberChanged: - member.SetData(event) - - grant, err := u.view.UserGrantByIDs(domain.IAMID, u.iamProjectID, member.UserID) - if err != nil && !errors.IsNotFound(err) { - return err - } - if errors.IsNotFound(err) { - grant = &view_model.UserGrantView{ - ID: u.iamProjectID + member.UserID, - ResourceOwner: domain.IAMID, - OrgName: domain.IAMID, - ProjectID: u.iamProjectID, - UserID: member.UserID, - RoleKeys: member.Roles, - CreationDate: event.CreationDate, - } - if suffix { - grant.RoleKeys = suffixRoles(event.AggregateID, grant.RoleKeys) - } - } else { - newRoles := member.Roles - if grant.RoleKeys != nil { - grant.RoleKeys = mergeExistingRoles(rolePrefix, "", grant.RoleKeys, newRoles) - } else { - grant.RoleKeys = newRoles - } - } - grant.Sequence = event.Sequence - grant.ChangeDate = event.CreationDate - return u.view.PutUserGrant(grant, event) - case iam_es_model.IAMMemberRemoved, - iam_es_model.IAMMemberCascadeRemoved: - member.SetData(event) - grant, err := u.view.UserGrantByIDs(domain.IAMID, u.iamProjectID, member.UserID) - if err != nil { - return err - } - return u.view.DeleteUserGrant(grant.ID, event) - default: - return u.view.ProcessedUserGrantSequence(event) - } -} - -func (u *UserGrant) processMember(event *es_models.Event, rolePrefix, roleSuffix string, userID string, roleKeys []string) error { - switch event.Type { - case org_es_model.OrgMemberAdded, proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded, - org_es_model.OrgMemberChanged, proj_es_model.ProjectMemberChanged, proj_es_model.ProjectGrantMemberChanged: - - grant, err := u.view.UserGrantByIDs(event.ResourceOwner, u.iamProjectID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - if roleSuffix != "" { - roleKeys = suffixRoles(roleSuffix, roleKeys) - } - if errors.IsNotFound(err) { - grant = &view_model.UserGrantView{ - ID: u.iamProjectID + event.ResourceOwner + userID, - ResourceOwner: event.ResourceOwner, - ProjectID: u.iamProjectID, - UserID: userID, - RoleKeys: roleKeys, - CreationDate: event.CreationDate, - } - - } else { - newRoles := roleKeys - if grant.RoleKeys != nil { - grant.RoleKeys = mergeExistingRoles(rolePrefix, roleSuffix, grant.RoleKeys, newRoles) - } else { - grant.RoleKeys = newRoles - } - } - grant.Sequence = event.Sequence - grant.ChangeDate = event.CreationDate - return u.view.PutUserGrant(grant, event) - case org_es_model.OrgMemberRemoved, - org_es_model.OrgMemberCascadeRemoved, - proj_es_model.ProjectMemberRemoved, - proj_es_model.ProjectMemberCascadeRemoved, - proj_es_model.ProjectGrantMemberRemoved, - proj_es_model.ProjectGrantMemberCascadeRemoved: - - grant, err := u.view.UserGrantByIDs(event.ResourceOwner, u.iamProjectID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - if errors.IsNotFound(err) { - return u.view.ProcessedUserGrantSequence(event) - } - if roleSuffix != "" { - roleKeys = suffixRoles(roleSuffix, roleKeys) - } - if grant.RoleKeys == nil { - return u.view.ProcessedUserGrantSequence(event) - } - grant.RoleKeys = mergeExistingRoles(rolePrefix, roleSuffix, grant.RoleKeys, nil) - return u.view.PutUserGrant(grant, event) - default: - return u.view.ProcessedUserGrantSequence(event) - } -} - -func suffixRoles(suffix string, roles []string) []string { - suffixedRoles := make([]string, len(roles)) - for i := 0; i < len(roles); i++ { - suffixedRoles[i] = roles[i] + ":" + suffix - } - return suffixedRoles -} - -func mergeExistingRoles(rolePrefix, suffix string, existingRoles, newRoles []string) []string { - mergedRoles := make([]string, 0) - for _, existingRole := range existingRoles { - if !strings.HasPrefix(existingRole, rolePrefix) { - mergedRoles = append(mergedRoles, existingRole) - continue - } - if suffix != "" && !strings.HasSuffix(existingRole, suffix) { - mergedRoles = append(mergedRoles, existingRole) - } - } - return append(mergedRoles, newRoles...) -} - -func (u *UserGrant) setIamProjectID() error { - if u.iamProjectID != "" { - return nil - } - iam, err := u.getIAMByID(context.Background()) - if err != nil { - return err - } - if iam.SetUpDone < domain.StepCount-1 { - return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done") - } - u.iamProjectID = iam.IAMProjectID - return nil -} - -func (u *UserGrant) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-VcVoJ", "id", event.AggregateID).WithError(err).Warn("something went wrong in user grant handler") - return spooler.HandleError(event, err, u.view.GetLatestUserGrantFailedEvent, u.view.ProcessedUserGrantFailedEvent, u.view.ProcessedUserGrantSequence, u.errorCountUntilSkip) -} - -func (u *UserGrant) OnSuccess() error { - return spooler.HandleSuccess(u.view.UpdateUserGrantSpoolerRunTimestamp) -} - -func (u *UserGrant) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/authz/repository/eventsourcing/view/user_grant.go b/internal/authz/repository/eventsourcing/view/user_grant.go deleted file mode 100644 index 6886dcf8e8..0000000000 --- a/internal/authz/repository/eventsourcing/view/user_grant.go +++ /dev/null @@ -1,70 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - grant_model "github.com/caos/zitadel/internal/usergrant/model" - "github.com/caos/zitadel/internal/usergrant/repository/view" - "github.com/caos/zitadel/internal/usergrant/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - userGrantTable = "authz.user_grants" -) - -func (v *View) UserGrantByID(grantID string) (*model.UserGrantView, error) { - return view.UserGrantByID(v.Db, userGrantTable, grantID) -} - -func (v *View) UserGrantByIDs(resourceOwnerID, projectID, userID string) (*model.UserGrantView, error) { - return view.UserGrantByIDs(v.Db, userGrantTable, resourceOwnerID, projectID, userID) -} - -func (v *View) UserGrantsByUserID(userID string) ([]*model.UserGrantView, error) { - return view.UserGrantsByUserID(v.Db, userGrantTable, userID) -} - -func (v *View) UserGrantsByProjectID(projectID string) ([]*model.UserGrantView, error) { - return view.UserGrantsByProjectID(v.Db, userGrantTable, projectID) -} - -func (v *View) SearchUserGrants(request *grant_model.UserGrantSearchRequest) ([]*model.UserGrantView, uint64, error) { - return view.SearchUserGrants(v.Db, userGrantTable, request) -} - -func (v *View) PutUserGrant(grant *model.UserGrantView, event *models.Event) error { - err := view.PutUserGrant(v.Db, userGrantTable, grant) - if err != nil { - return err - } - return v.ProcessedUserGrantSequence(event) -} - -func (v *View) DeleteUserGrant(grantID string, event *models.Event) error { - err := view.DeleteUserGrant(v.Db, userGrantTable, grantID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserGrantSequence(event) -} - -func (v *View) GetLatestUserGrantSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(userGrantTable) -} - -func (v *View) ProcessedUserGrantSequence(event *models.Event) error { - return v.saveCurrentSequence(userGrantTable, event) -} - -func (v *View) UpdateUserGrantSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(userGrantTable) -} - -func (v *View) GetLatestUserGrantFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(userGrantTable, sequence) -} - -func (v *View) ProcessedUserGrantFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/domain/auth_request.go b/internal/domain/auth_request.go index 5d8fc6cdbb..c1bf565570 100644 --- a/internal/domain/auth_request.go +++ b/internal/domain/auth_request.go @@ -23,6 +23,7 @@ type AuthRequest struct { UiLocales []string LoginHint string MaxAuthAge *time.Duration + InstanceID string Request Request levelOfAssurance LevelOfAssurance diff --git a/internal/eventstore/aggregate.go b/internal/eventstore/aggregate.go index 98f3b05e50..60793fd361 100644 --- a/internal/eventstore/aggregate.go +++ b/internal/eventstore/aggregate.go @@ -21,7 +21,7 @@ func NewAggregate( ID: id, Type: typ, ResourceOwner: authz.GetCtxData(ctx).OrgID, - Tenant: authz.GetCtxData(ctx).TenantID, + InstanceID: authz.GetInstance(ctx).ID, Version: version, } @@ -50,7 +50,7 @@ func AggregateFromWriteModel( ID: wm.AggregateID, Type: typ, ResourceOwner: wm.ResourceOwner, - Tenant: wm.Tenant, + InstanceID: wm.InstanceID, Version: version, } } @@ -63,8 +63,8 @@ type Aggregate struct { Type AggregateType `json:"-"` //ResourceOwner is the org this aggregates belongs to ResourceOwner string `json:"-"` - //Tenant is the system this aggregate belongs to - Tenant string `json:"-"` + //InstanceID is the instance this aggregate belongs to + InstanceID string `json:"-"` //Version is the semver this aggregate represents Version Version `json:"-"` } diff --git a/internal/eventstore/event_base.go b/internal/eventstore/event_base.go index 46f3a9304e..fb0bf0750a 100644 --- a/internal/eventstore/event_base.go +++ b/internal/eventstore/event_base.go @@ -79,7 +79,7 @@ func BaseEventFromRepo(event *repository.Event) *BaseEvent { ID: event.AggregateID, Type: AggregateType(event.AggregateType), ResourceOwner: event.ResourceOwner.String, - Tenant: event.Tenant.String, + InstanceID: event.InstanceID.String, Version: Version(event.Version), }, EventType: EventType(event.Type), diff --git a/internal/eventstore/eventstore.go b/internal/eventstore/eventstore.go index b6f80741ba..d812a5f96b 100644 --- a/internal/eventstore/eventstore.go +++ b/internal/eventstore/eventstore.go @@ -41,7 +41,7 @@ func (es *Eventstore) Health(ctx context.Context) error { //Push pushes the events in a single transaction // an event needs at least an aggregate func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) { - events, constraints, err := commandsToRepository(authz.GetCtxData(ctx).TenantID, cmds) + events, constraints, err := commandsToRepository(authz.GetInstance(ctx).ID, cmds) if err != nil { return nil, err } @@ -59,7 +59,7 @@ func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error return eventReaders, nil } -func commandsToRepository(tenantID string, cmds []Command) (events []*repository.Event, constraints []*repository.UniqueConstraint, err error) { +func commandsToRepository(instanceID string, cmds []Command) (events []*repository.Event, constraints []*repository.UniqueConstraint, err error) { events = make([]*repository.Event, len(cmds)) for i, cmd := range cmds { data, err := EventData(cmd) @@ -82,7 +82,7 @@ func commandsToRepository(tenantID string, cmds []Command) (events []*repository AggregateID: cmd.Aggregate().ID, AggregateType: repository.AggregateType(cmd.Aggregate().Type), ResourceOwner: sql.NullString{String: cmd.Aggregate().ResourceOwner, Valid: cmd.Aggregate().ResourceOwner != ""}, - Tenant: sql.NullString{String: tenantID, Valid: tenantID != ""}, + InstanceID: sql.NullString{String: instanceID, Valid: instanceID != ""}, EditorService: cmd.EditorService(), EditorUser: cmd.EditorUser(), Type: repository.EventType(cmd.Type()), @@ -113,7 +113,7 @@ func uniqueConstraintsToRepository(constraints []*EventUniqueConstraint) (unique //Filter filters the stored events based on the searchQuery // and maps the events to the defined event structs func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) { - query, err := queryFactory.build(authz.GetCtxData(ctx).TenantID) + query, err := queryFactory.build(authz.GetInstance(ctx).ID) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu //LatestSequence filters the latest sequence for the given search query func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) { - query, err := queryFactory.build(authz.GetCtxData(ctx).TenantID) + query, err := queryFactory.build(authz.GetInstance(ctx).ID) if err != nil { return 0, err } diff --git a/internal/eventstore/eventstore_test.go b/internal/eventstore/eventstore_test.go index 48c9310673..f7a252c12d 100644 --- a/internal/eventstore/eventstore_test.go +++ b/internal/eventstore/eventstore_test.go @@ -29,7 +29,7 @@ func newTestEvent(id, description string, data func() interface{}, checkPrevious data: data, shouldCheckPrevious: checkPrevious, BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "resourceOwner", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "resourceOwner", "editorUser"), "editorService"), NewAggregate(authz.NewMockContext("zitadel", "caos", "adlerhurst"), id, "test.aggregate", "v1"), "test.event", ), @@ -344,8 +344,8 @@ func Test_eventData(t *testing.T) { func TestEventstore_aggregatesToEvents(t *testing.T) { type args struct { - tenantID string - events []Command + instanceID string + events []Command } type res struct { wantErr bool @@ -359,7 +359,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "one aggregate one event", args: args{ - tenantID: "tenant", + instanceID: "instanceID", events: []Command{ newTestEvent( "1", @@ -380,7 +380,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "tenant", Valid: true}, + InstanceID: sql.NullString{String: "instanceID", Valid: true}, Type: "test.event", Version: "v1", }, @@ -390,7 +390,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "one aggregate multiple events", args: args{ - tenantID: "tenant", + instanceID: "instanceID", events: []Command{ newTestEvent( "1", @@ -418,7 +418,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "tenant", Valid: true}, + InstanceID: sql.NullString{String: "instanceID", Valid: true}, Type: "test.event", Version: "v1", }, @@ -429,7 +429,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "tenant", Valid: true}, + InstanceID: sql.NullString{String: "instanceID", Valid: true}, Type: "test.event", Version: "v1", }, @@ -439,7 +439,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "invalid data", args: args{ - tenantID: "tenant", + instanceID: "instanceID", events: []Command{ newTestEvent( "1", @@ -460,7 +460,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { events: []Command{ &testEvent{ BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "resourceOwner", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "resourceOwner", "editorUser"), "editorService"), NewAggregate( authz.NewMockContext("zitadel", "caos", "adlerhurst"), "", @@ -485,7 +485,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { events: []Command{ &testEvent{ BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "resourceOwner", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "resourceOwner", "editorUser"), "editorService"), NewAggregate( authz.NewMockContext("zitadel", "caos", "adlerhurst"), "id", @@ -510,7 +510,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { events: []Command{ &testEvent{ BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "resourceOwner", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "resourceOwner", "editorUser"), "editorService"), NewAggregate( authz.NewMockContext("zitadel", "caos", "adlerhurst"), "id", @@ -535,7 +535,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { events: []Command{ &testEvent{ BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "resourceOwner", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "resourceOwner", "editorUser"), "editorService"), NewAggregate( authz.NewMockContext("zitadel", "caos", "adlerhurst"), "id", @@ -560,7 +560,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { events: []Command{ &testEvent{ BaseEvent: *NewBaseEventForPush( - service.WithService(authz.NewMockContext("tenant", "", "editorUser"), "editorService"), + service.WithService(authz.NewMockContext("instanceID", "", "editorUser"), "editorService"), NewAggregate( authz.NewMockContext("zitadel", "", "adlerhurst"), "id", @@ -585,7 +585,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "", Valid: false}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -630,7 +630,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -641,7 +641,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -654,7 +654,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -665,7 +665,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - events, _, err := commandsToRepository(tt.args.tenantID, tt.args.events) + events, _, err := commandsToRepository(tt.args.instanceID, tt.args.events) if (err != nil) != tt.res.wantErr { t.Errorf("Eventstore.aggregatesToEvents() error = %v, wantErr %v", err, tt.res.wantErr) return @@ -772,7 +772,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -816,7 +816,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -827,7 +827,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -882,7 +882,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -893,7 +893,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, @@ -906,7 +906,7 @@ func TestEventstore_Push(t *testing.T) { EditorService: "editorService", EditorUser: "editorUser", ResourceOwner: sql.NullString{String: "caos", Valid: true}, - Tenant: sql.NullString{String: "zitadel"}, + InstanceID: sql.NullString{String: "zitadel"}, Type: "test.event", Version: "v1", }, diff --git a/internal/eventstore/handler/crdb/db_mock_test.go b/internal/eventstore/handler/crdb/db_mock_test.go index 17667798d1..dbd83ca01b 100644 --- a/internal/eventstore/handler/crdb/db_mock_test.go +++ b/internal/eventstore/handler/crdb/db_mock_test.go @@ -8,15 +8,16 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/caos/zitadel/internal/eventstore" ) type mockExpectation func(sqlmock.Sqlmock) -func expectFailureCount(tableName string, projectionName string, failedSeq, failureCount uint64) func(sqlmock.Sqlmock) { +func expectFailureCount(tableName string, projectionName, instanceID string, failedSeq, failureCount uint64) func(sqlmock.Sqlmock) { return func(m sqlmock.Sqlmock) { - m.ExpectQuery(`WITH failures AS \(SELECT failure_count FROM `+tableName+` WHERE projection_name = \$1 AND failed_sequence = \$2\) SELECT IF\(EXISTS\(SELECT failure_count FROM failures\), \(SELECT failure_count FROM failures\), 0\) AS failure_count`). - WithArgs(projectionName, failedSeq). + m.ExpectQuery(`WITH failures AS \(SELECT failure_count FROM `+tableName+` WHERE projection_name = \$1 AND failed_sequence = \$2\ AND instance_id = \$3\) SELECT IF\(EXISTS\(SELECT failure_count FROM failures\), \(SELECT failure_count FROM failures\), 0\) AS failure_count`). + WithArgs(projectionName, failedSeq, instanceID). WillReturnRows( sqlmock.NewRows([]string{"failure_count"}). AddRow(failureCount), @@ -24,10 +25,10 @@ func expectFailureCount(tableName string, projectionName string, failedSeq, fail } } -func expectUpdateFailureCount(tableName string, projectionName string, seq, failureCount uint64) func(sqlmock.Sqlmock) { +func expectUpdateFailureCount(tableName string, projectionName, instanceID string, seq, failureCount uint64) func(sqlmock.Sqlmock) { return func(m sqlmock.Sqlmock) { - m.ExpectExec(`UPSERT INTO `+tableName+` \(projection_name, failed_sequence, failure_count, error\) VALUES \(\$1, \$2, \$3, \$4\)`). - WithArgs(projectionName, seq, failureCount, sqlmock.AnyArg()).WillReturnResult(sqlmock.NewResult(1, 1)) + m.ExpectExec(`UPSERT INTO `+tableName+` \(projection_name, failed_sequence, failure_count, error, instance_id\) VALUES \(\$1, \$2, \$3, \$4\, \$5\)`). + WithArgs(projectionName, seq, failureCount, sqlmock.AnyArg(), instanceID).WillReturnResult(sqlmock.NewResult(1, 1)) } } diff --git a/internal/eventstore/handler/crdb/failed_stmt.go b/internal/eventstore/handler/crdb/failed_stmt.go index 15040672c9..b7a9e8bdaf 100644 --- a/internal/eventstore/handler/crdb/failed_stmt.go +++ b/internal/eventstore/handler/crdb/failed_stmt.go @@ -4,15 +4,16 @@ import ( "database/sql" "github.com/caos/logging" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/handler" ) const ( setFailureCountStmtFormat = "UPSERT INTO %s" + - " (projection_name, failed_sequence, failure_count, error)" + - " VALUES ($1, $2, $3, $4)" - failureCountStmtFormat = "WITH failures AS (SELECT failure_count FROM %s WHERE projection_name = $1 AND failed_sequence = $2)" + + " (projection_name, failed_sequence, failure_count, error, instance_id)" + + " VALUES ($1, $2, $3, $4, $5)" + failureCountStmtFormat = "WITH failures AS (SELECT failure_count FROM %s WHERE projection_name = $1 AND failed_sequence = $2 AND instance_id = $3)" + " SELECT IF(" + "EXISTS(SELECT failure_count FROM failures)," + " (SELECT failure_count FROM failures)," + @@ -21,31 +22,31 @@ const ( ) func (h *StatementHandler) handleFailedStmt(tx *sql.Tx, stmt *handler.Statement, execErr error) (shouldContinue bool) { - failureCount, err := h.failureCount(tx, stmt.Sequence) + failureCount, err := h.failureCount(tx, stmt.Sequence, stmt.InstanceID) if err != nil { - logging.WithFields("projection", h.ProjectionName, "seq", stmt.Sequence).WithError(err).Warn("unable to get failure count") + logging.WithFields("projection", h.ProjectionName, "sequence", stmt.Sequence).WithError(err).Warn("unable to get failure count") return false } failureCount += 1 - err = h.setFailureCount(tx, stmt.Sequence, failureCount, execErr) - logging.WithFields("projection", h.ProjectionName, "seq", stmt.Sequence).OnError(err).Warn("unable to update failure count") + err = h.setFailureCount(tx, stmt.Sequence, failureCount, execErr, stmt.InstanceID) + logging.WithFields("projection", h.ProjectionName, "sequence", stmt.Sequence).OnError(err).Warn("unable to update failure count") return failureCount >= h.maxFailureCount } -func (h *StatementHandler) failureCount(tx *sql.Tx, seq uint64) (count uint, err error) { - row := tx.QueryRow(h.failureCountStmt, h.ProjectionName, seq) +func (h *StatementHandler) failureCount(tx *sql.Tx, seq uint64, instanceID string) (count uint, err error) { + row := tx.QueryRow(h.failureCountStmt, h.ProjectionName, seq, instanceID) if err = row.Err(); err != nil { return 0, errors.ThrowInternal(err, "CRDB-Unnex", "unable to update failure count") } if err = row.Scan(&count); err != nil { - return 0, errors.ThrowInternal(err, "CRDB-RwSMV", "unable to scann count") + return 0, errors.ThrowInternal(err, "CRDB-RwSMV", "unable to scan count") } return count, nil } -func (h *StatementHandler) setFailureCount(tx *sql.Tx, seq uint64, count uint, err error) error { - _, dbErr := tx.Exec(h.setFailureCountStmt, h.ProjectionName, seq, count, err.Error()) +func (h *StatementHandler) setFailureCount(tx *sql.Tx, seq uint64, count uint, err error, instanceID string) error { + _, dbErr := tx.Exec(h.setFailureCountStmt, h.ProjectionName, seq, count, err.Error(), instanceID) if dbErr != nil { return errors.ThrowInternal(dbErr, "CRDB-4Ht4x", "set failure count failed") } diff --git a/internal/eventstore/handler/crdb/handler_stmt.go b/internal/eventstore/handler/crdb/handler_stmt.go index dceba869d7..4bcf1e1f1b 100644 --- a/internal/eventstore/handler/crdb/handler_stmt.go +++ b/internal/eventstore/handler/crdb/handler_stmt.go @@ -26,7 +26,8 @@ type StatementHandlerConfig struct { MaxFailureCount uint BulkLimit uint64 - Reducers []handler.AggregateReducer + Reducers []handler.AggregateReducer + InitCheck *handler.Check } type StatementHandler struct { @@ -75,6 +76,9 @@ func NewStatementHandler( Locker: NewLocker(config.Client, config.LockTable, config.ProjectionHandlerConfig.ProjectionName), } + err := h.Init(ctx, config.InitCheck) + logging.OnError(err).Fatal("unable to initialize projections") + go h.ProjectionHandler.Process( ctx, h.reduce, @@ -214,7 +218,7 @@ func (h *StatementHandler) executeStmts( continue } if stmt.PreviousSequence > 0 && stmt.PreviousSequence != sequences[stmt.AggregateType] { - logging.WithFields("projection", h.ProjectionName, "aggregateType", stmt.AggregateType, "seq", stmt.Sequence, "prevSeq", stmt.PreviousSequence, "currentSeq", sequences[stmt.AggregateType]).Warn("sequences do not match") + logging.WithFields("projection", h.ProjectionName, "aggregateType", stmt.AggregateType, "sequence", stmt.Sequence, "prevSeq", stmt.PreviousSequence, "currentSeq", sequences[stmt.AggregateType]).Warn("sequences do not match") break } err := h.executeStmt(tx, stmt) diff --git a/internal/eventstore/handler/crdb/handler_stmt_test.go b/internal/eventstore/handler/crdb/handler_stmt_test.go index 08bf91ad31..e6e1936651 100644 --- a/internal/eventstore/handler/crdb/handler_stmt_test.go +++ b/internal/eventstore/handler/crdb/handler_stmt_test.go @@ -28,6 +28,7 @@ type testEvent struct { sequence uint64 previousSequence uint64 aggregateType eventstore.AggregateType + instanceID string } func (e *testEvent) Sequence() uint64 { @@ -36,7 +37,8 @@ func (e *testEvent) Sequence() uint64 { func (e *testEvent) Aggregate() eventstore.Aggregate { return eventstore.Aggregate{ - Type: e.aggregateType, + Type: e.aggregateType, + InstanceID: e.instanceID, } } @@ -786,6 +788,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 5, previousSequence: 0, + instanceID: "instanceID", }, []handler.Column{ { @@ -798,6 +801,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 6, previousSequence: 5, + instanceID: "instanceID", }, []handler.Column{ { @@ -810,6 +814,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 7, previousSequence: 6, + instanceID: "instanceID", }, []handler.Column{ { @@ -830,8 +835,8 @@ func TestStatementHandler_executeStmts(t *testing.T) { expectSavePoint(), expectCreateErr("my_projection", []string{"col"}, []string{"$1"}, sql.ErrConnDone), expectSavePointRollback(), - expectFailureCount("failed_events", "my_projection", 6, 3), - expectUpdateFailureCount("failed_events", "my_projection", 6, 4), + expectFailureCount("failed_events", "my_projection", "instanceID", 6, 3), + expectUpdateFailureCount("failed_events", "my_projection", "instanceID", 6, 4), }, idx: 0, }, @@ -850,6 +855,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 5, previousSequence: 0, + instanceID: "instanceID", }, []handler.Column{ { @@ -862,6 +868,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 6, previousSequence: 5, + instanceID: "instanceID", }, []handler.Column{ { @@ -874,6 +881,7 @@ func TestStatementHandler_executeStmts(t *testing.T) { aggregateType: "agg", sequence: 7, previousSequence: 6, + instanceID: "instanceID", }, []handler.Column{ { @@ -894,8 +902,8 @@ func TestStatementHandler_executeStmts(t *testing.T) { expectSavePoint(), expectCreateErr("my_projection", []string{"col2"}, []string{"$1"}, sql.ErrConnDone), expectSavePointRollback(), - expectFailureCount("failed_events", "my_projection", 6, 4), - expectUpdateFailureCount("failed_events", "my_projection", 6, 5), + expectFailureCount("failed_events", "my_projection", "instanceID", 6, 4), + expectUpdateFailureCount("failed_events", "my_projection", "instanceID", 6, 5), expectSavePoint(), expectCreate("my_projection", []string{"col3"}, []string{"$1"}), expectSavePointRelease(), diff --git a/internal/eventstore/handler/crdb/init.go b/internal/eventstore/handler/crdb/init.go new file mode 100644 index 0000000000..9ee33311a8 --- /dev/null +++ b/internal/eventstore/handler/crdb/init.go @@ -0,0 +1,320 @@ +package crdb + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/caos/logging" + "github.com/lib/pq" + + caos_errs "github.com/caos/zitadel/internal/errors" + + "github.com/caos/zitadel/internal/eventstore/handler" +) + +type Table struct { + columns []*Column + primaryKey PrimaryKey + indices []*Index +} + +func NewTable(columns []*Column, key PrimaryKey, indices ...*Index) *Table { + return &Table{ + columns: columns, + primaryKey: key, + indices: indices, + } +} + +type SuffixedTable struct { + Table + suffix string +} + +func NewSuffixedTable(columns []*Column, key PrimaryKey, suffix string, indices ...*Index) *SuffixedTable { + return &SuffixedTable{ + Table: Table{ + columns: columns, + primaryKey: key, + indices: indices, + }, + suffix: suffix, + } +} + +type Column struct { + Name string + Type ColumnType + nullable bool + defaultValue interface{} + deleteCascade string +} + +type ColumnOption func(*Column) + +func NewColumn(name string, columnType ColumnType, opts ...ColumnOption) *Column { + column := &Column{ + Name: name, + Type: columnType, + nullable: false, + defaultValue: nil, + } + for _, opt := range opts { + opt(column) + } + return column +} + +func Nullable() ColumnOption { + return func(c *Column) { + c.nullable = true + } +} + +func Default(value interface{}) ColumnOption { + return func(c *Column) { + c.defaultValue = value + } +} + +func DeleteCascade(column string) ColumnOption { + return func(c *Column) { + c.deleteCascade = column + } +} + +type PrimaryKey []string + +func NewPrimaryKey(columnNames ...string) PrimaryKey { + return columnNames +} + +type ColumnType int32 + +const ( + ColumnTypeText ColumnType = iota + ColumnTypeTextArray + ColumnTypeJSONB + ColumnTypeBytes + ColumnTypeTimestamp + ColumnTypeEnum + ColumnTypeEnumArray + ColumnTypeInt64 + ColumnTypeBool +) + +func NewIndex(name string, columns []string, opts ...indexOpts) *Index { + i := &Index{ + Name: name, + Columns: columns, + bucketCount: 0, + } + for _, opt := range opts { + opt(i) + } + return i +} + +type Index struct { + Name string + Columns []string + bucketCount uint16 +} + +type indexOpts func(*Index) + +func Hash(bucketsCount uint16) indexOpts { + return func(i *Index) { + i.bucketCount = bucketsCount + } +} + +//Init implements handler.Init +func (h *StatementHandler) Init(ctx context.Context, checks ...*handler.Check) error { + for _, check := range checks { + if check == nil || check.IsNoop() { + return nil + } + tx, err := h.client.BeginTx(ctx, nil) + if err != nil { + return caos_errs.ThrowInternal(err, "CRDB-SAdf2", "begin failed") + } + for i, execute := range check.Executes { + logging.WithFields("projection", h.ProjectionName, "execute", i).Debug("executing check") + next, err := execute(h.client, h.ProjectionName) + if err != nil { + tx.Rollback() + return err + } + if !next { + logging.WithFields("projection", h.ProjectionName, "execute", i).Debug("skipping next check") + break + } + } + if err := tx.Commit(); err != nil { + return err + } + } + return nil +} + +func NewTableCheck(table *Table, opts ...execOption) *handler.Check { + config := execConfig{} + create := func(config execConfig) string { + return createTableStatement(table, config.tableName, "") + } + executes := make([]func(handler.Executer, string) (bool, error), len(table.indices)+1) + executes[0] = execNextIfExists(config, create, opts, true) + for i, index := range table.indices { + executes[i+1] = execNextIfExists(config, createIndexStatement(index), opts, true) + } + return &handler.Check{ + Executes: executes, + } +} + +func NewMultiTableCheck(primaryTable *Table, secondaryTables ...*SuffixedTable) *handler.Check { + config := execConfig{} + create := func(config execConfig) string { + stmt := createTableStatement(primaryTable, config.tableName, "") + for _, table := range secondaryTables { + stmt += createTableStatement(&table.Table, config.tableName, "_"+table.suffix) + } + return stmt + } + + return &handler.Check{ + Executes: []func(handler.Executer, string) (bool, error){ + execNextIfExists(config, create, nil, true), + }, + } +} + +func NewViewCheck(selectStmt string, secondaryTables ...*SuffixedTable) *handler.Check { + config := execConfig{} + create := func(config execConfig) string { + var stmt string + for _, table := range secondaryTables { + stmt += createTableStatement(&table.Table, config.tableName, "_"+table.suffix) + } + stmt += createViewStatement(config.tableName, selectStmt) + return stmt + } + + return &handler.Check{ + Executes: []func(handler.Executer, string) (bool, error){ + execNextIfExists(config, create, nil, false), + }, + } +} + +func execNextIfExists(config execConfig, q query, opts []execOption, executeNext bool) func(handler.Executer, string) (bool, error) { + return func(handler handler.Executer, name string) (bool, error) { + err := exec(config, q, opts)(handler, name) + if isErrAlreadyExists(err) { + return executeNext, nil + } + return false, err + } +} + +func isErrAlreadyExists(err error) bool { + caosErr := &caos_errs.CaosError{} + if !errors.As(err, &caosErr) { + return false + } + sqlErr, ok := caosErr.GetParent().(*pq.Error) + if !ok { + return false + } + return sqlErr.Routine == "NewRelationAlreadyExistsError" +} + +func createTableStatement(table *Table, tableName string, suffix string) string { + stmt := fmt.Sprintf("CREATE TABLE %s (%s, PRIMARY KEY (%s)", + tableName+suffix, + createColumnsStatement(table.columns, tableName), + strings.Join(table.primaryKey, ", "), + ) + for _, index := range table.indices { + stmt += fmt.Sprintf(", INDEX %s (%s)", index.Name, strings.Join(index.Columns, ",")) + } + return stmt + ");" +} + +func createViewStatement(viewName string, selectStmt string) string { + return fmt.Sprintf("CREATE VIEW %s AS %s", + viewName, + selectStmt, + ) +} + +func createIndexStatement(index *Index) func(config execConfig) string { + return func(config execConfig) string { + stmt := fmt.Sprintf("CREATE INDEX %s ON %s (%s)", + index.Name, + config.tableName, + strings.Join(index.Columns, ","), + ) + if index.bucketCount == 0 { + return stmt + ";" + } + return fmt.Sprintf("SET experimental_enable_hash_sharded_indexes=on; %s USING HASH WITH BUCKET_COUNT = %d;", + stmt, index.bucketCount) + } +} + +func createColumnsStatement(cols []*Column, tableName string) string { + columns := make([]string, len(cols)) + for i, col := range cols { + column := col.Name + " " + columnType(col.Type) + if !col.nullable { + column += " NOT NULL" + } + if col.defaultValue != nil { + column += " DEFAULT " + defaultValue(col.defaultValue) + } + if col.deleteCascade != "" { + column += fmt.Sprintf(" REFERENCES %s (%s) ON DELETE CASCADE", tableName, col.deleteCascade) + } + columns[i] = column + } + return strings.Join(columns, ",") +} + +func defaultValue(value interface{}) string { + switch v := value.(type) { + case string: + return "'" + v + "'" + default: + return fmt.Sprintf("%v", v) + } +} + +func columnType(columnType ColumnType) string { + switch columnType { + case ColumnTypeText: + return "TEXT" + case ColumnTypeTextArray: + return "TEXT[]" + case ColumnTypeTimestamp: + return "TIMESTAMPTZ" + case ColumnTypeEnum: + return "SMALLINT" + case ColumnTypeEnumArray: + return "SMALLINT[]" + case ColumnTypeInt64: + return "BIGINT" + case ColumnTypeBool: + return "BOOLEAN" + case ColumnTypeJSONB: + return "JSONB" + case ColumnTypeBytes: + return "BYTES" + default: + panic("") //TODO: remove? + return "" + } +} diff --git a/internal/eventstore/handler/crdb/lock.go b/internal/eventstore/handler/crdb/lock.go index 668b764989..a344cc1099 100644 --- a/internal/eventstore/handler/crdb/lock.go +++ b/internal/eventstore/handler/crdb/lock.go @@ -37,7 +37,7 @@ func NewLocker(client *sql.DB, lockTable, projectionName string) Locker { workerName, err := os.Hostname() if err != nil || workerName == "" { workerName, err = id.SonyFlakeGenerator.Next() - logging.Log("CRDB-bdO56").OnError(err).Panic("unable to generate lockID") + logging.OnError(err).Panic("unable to generate lockID") } return &locker{ client: client, diff --git a/internal/eventstore/handler/crdb/statement.go b/internal/eventstore/handler/crdb/statement.go index 6c981f903e..c8538ee512 100644 --- a/internal/eventstore/handler/crdb/statement.go +++ b/internal/eventstore/handler/crdb/statement.go @@ -6,7 +6,7 @@ import ( "github.com/lib/pq" - "github.com/caos/zitadel/internal/errors" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" ) @@ -46,6 +46,7 @@ func NewCreateStatement(event eventstore.Event, values []handler.Column, opts .. AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: exec(config, q, opts), } } @@ -71,6 +72,7 @@ func NewUpsertStatement(event eventstore.Event, values []handler.Column, opts .. AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: exec(config, q, opts), } } @@ -104,6 +106,7 @@ func NewUpdateStatement(event eventstore.Event, values []handler.Column, conditi AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: exec(config, q, opts), } } @@ -129,6 +132,7 @@ func NewDeleteStatement(event eventstore.Event, conditions []handler.Condition, AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: exec(config, q, opts), } } @@ -138,6 +142,7 @@ func NewNoOpStatement(event eventstore.Event) *handler.Statement { AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, } } @@ -153,6 +158,7 @@ func NewMultiStatement(event eventstore.Event, opts ...func(eventstore.Event) Ex AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: multiExec(execs), } } @@ -278,6 +284,7 @@ func NewCopyStatement(event eventstore.Event, cols []handler.Column, conds []han AggregateType: event.Aggregate().Type, Sequence: event.Sequence(), PreviousSequence: event.PreviousAggregateTypeSequence(), + InstanceID: event.Aggregate().InstanceID, Execute: exec(config, q, opts), } } @@ -327,7 +334,7 @@ func exec(config execConfig, q query, opts []execOption) Exec { } if _, err := ex.Exec(q(config), config.args...); err != nil { - return errors.ThrowInternal(err, "CRDB-pKtsr", "exec failed") + return caos_errs.ThrowInternal(err, "CRDB-pKtsr", "exec failed") } return nil diff --git a/internal/eventstore/handler/crdb/statement_test.go b/internal/eventstore/handler/crdb/statement_test.go index b956e6fea4..aed750ff35 100644 --- a/internal/eventstore/handler/crdb/statement_test.go +++ b/internal/eventstore/handler/crdb/statement_test.go @@ -608,6 +608,7 @@ func TestNewNoOpStatement(t *testing.T) { aggregateType: "agg", sequence: 5, previousSequence: 3, + instanceID: "instanceID", }, }, want: &handler.Statement{ @@ -615,6 +616,7 @@ func TestNewNoOpStatement(t *testing.T) { Execute: nil, Sequence: 5, PreviousSequence: 3, + InstanceID: "instanceID", }, }, } diff --git a/internal/eventstore/handler/handler_projection.go b/internal/eventstore/handler/handler_projection.go index ea243ed552..3127f8cab3 100644 --- a/internal/eventstore/handler/handler_projection.go +++ b/internal/eventstore/handler/handler_projection.go @@ -8,6 +8,7 @@ import ( "time" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" ) @@ -270,7 +271,7 @@ func (h *ProjectionHandler) fetchBulkStmts( for _, event := range events { if err = h.processEvent(ctx, event, reduce); err != nil { - logging.WithFields("projection", h.ProjectionName, "seq", event.Sequence()).WithError(err).Warn("unable to process event in bulk") + logging.WithFields("projection", h.ProjectionName, "sequence", event.Sequence(), "instanceID", event.Aggregate().InstanceID).WithError(err).Warn("unable to process event in bulk") return false, err } } diff --git a/internal/eventstore/handler/init.go b/internal/eventstore/handler/init.go new file mode 100644 index 0000000000..150196216c --- /dev/null +++ b/internal/eventstore/handler/init.go @@ -0,0 +1,14 @@ +package handler + +import "context" + +//Init initializes the projection with the given check +type Init func(context.Context, *Check) error + +type Check struct { + Executes []func(ex Executer, projectionName string) (bool, error) +} + +func (c *Check) IsNoop() bool { + return len(c.Executes) == 0 +} diff --git a/internal/eventstore/handler/statement.go b/internal/eventstore/handler/statement.go index ff7e2b41af..a565ef3edc 100644 --- a/internal/eventstore/handler/statement.go +++ b/internal/eventstore/handler/statement.go @@ -27,6 +27,7 @@ type Statement struct { AggregateType eventstore.AggregateType Sequence uint64 PreviousSequence uint64 + InstanceID string Execute func(ex Executer, projectionName string) error } diff --git a/internal/eventstore/read_model.go b/internal/eventstore/read_model.go index 7af27f3259..066e119fef 100644 --- a/internal/eventstore/read_model.go +++ b/internal/eventstore/read_model.go @@ -12,7 +12,7 @@ type ReadModel struct { ChangeDate time.Time `json:"-"` Events []Event `json:"-"` ResourceOwner string `json:"-"` - Tenant string `json:"-"` + InstanceID string `json:"-"` } //AppendEvents adds all the events to the read model. @@ -35,8 +35,8 @@ func (rm *ReadModel) Reduce() error { if rm.ResourceOwner == "" { rm.ResourceOwner = rm.Events[0].Aggregate().ResourceOwner } - if rm.Tenant == "" { - rm.Tenant = rm.Events[0].Aggregate().Tenant + if rm.InstanceID == "" { + rm.InstanceID = rm.Events[0].Aggregate().InstanceID } if rm.CreationDate.IsZero() { diff --git a/internal/eventstore/repository/event.go b/internal/eventstore/repository/event.go index 3d613fe8b7..7a6132f0bc 100644 --- a/internal/eventstore/repository/event.go +++ b/internal/eventstore/repository/event.go @@ -56,9 +56,9 @@ type Event struct { // an aggregate can only be managed by one organisation // use the ID of the org ResourceOwner sql.NullString - //Tenant is the system where this event belongs to - // use the ID of the tenant - Tenant sql.NullString + //InstanceID is the instance where this event belongs to + // use the ID of the instance + InstanceID sql.NullString } //EventType is the description of the change diff --git a/internal/eventstore/repository/search_query.go b/internal/eventstore/repository/search_query.go index 0190036daf..18531eb2cc 100644 --- a/internal/eventstore/repository/search_query.go +++ b/internal/eventstore/repository/search_query.go @@ -66,8 +66,8 @@ const ( FieldSequence //FieldResourceOwner represents the resource owner field FieldResourceOwner - //FieldTenant represents the tenant field - FieldTenant + //FieldInstanceID represents the instance id field + FieldInstanceID //FieldEditorService represents the editor service field FieldEditorService //FieldEditorUser represents the editor user field diff --git a/internal/eventstore/repository/sql/crdb.go b/internal/eventstore/repository/sql/crdb.go index ef3ea2935c..1cdd6e3d2c 100644 --- a/internal/eventstore/repository/sql/crdb.go +++ b/internal/eventstore/repository/sql/crdb.go @@ -30,7 +30,7 @@ const ( " SELECT MAX(event_sequence) seq, 1 join_me" + " FROM eventstore.events" + " WHERE aggregate_type = $2" + - " AND (CASE WHEN $9::STRING IS NULL THEN tenant is null else tenant = $9::STRING END)" + + " AND (CASE WHEN $9::STRING IS NULL THEN instance_id is null else instance_id = $9::STRING END)" + ") AS agg_type " + // combined with "LEFT JOIN " + @@ -39,7 +39,7 @@ const ( " SELECT event_sequence seq, resource_owner ro, 1 join_me" + " FROM eventstore.events" + " WHERE aggregate_type = $2 AND aggregate_id = $3" + - " AND (CASE WHEN $9::STRING IS NULL THEN tenant is null else tenant = $9::STRING END)" + + " AND (CASE WHEN $9::STRING IS NULL THEN instance_id is null else instance_id = $9::STRING END)" + " ORDER BY event_sequence DESC" + " LIMIT 1" + ") AS agg USING(join_me)" + @@ -54,7 +54,7 @@ const ( " editor_user," + " editor_service," + " resource_owner," + - " tenant," + + " instance_id," + " event_sequence," + " previous_aggregate_sequence," + " previous_aggregate_type_sequence" + @@ -70,12 +70,12 @@ const ( " $6::VARCHAR AS editor_user," + " $7::VARCHAR AS editor_service," + " IFNULL((resource_owner), $8::VARCHAR) AS resource_owner," + - " $9::VARCHAR AS tenant," + + " $9::VARCHAR AS instance_id," + " NEXTVAL(CONCAT('eventstore.', IFNULL($9, 'system'), '_seq'))," + " aggregate_sequence AS previous_aggregate_sequence," + " aggregate_type_sequence AS previous_aggregate_type_sequence " + "FROM previous_data " + - "RETURNING id, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, creation_date, resource_owner, tenant" + "RETURNING id, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, creation_date, resource_owner, instance_id" uniqueInsert = `INSERT INTO eventstore.unique_constraints ( @@ -120,8 +120,8 @@ func (db *CRDB) Push(ctx context.Context, events []*repository.Event, uniqueCons event.EditorUser, event.EditorService, event.ResourceOwner, - event.Tenant, - ).Scan(&event.ID, &event.Sequence, &previousAggregateSequence, &previousAggregateTypeSequence, &event.CreationDate, &event.ResourceOwner, &event.Tenant) + event.InstanceID, + ).Scan(&event.ID, &event.Sequence, &previousAggregateSequence, &previousAggregateTypeSequence, &event.CreationDate, &event.ResourceOwner, &event.InstanceID) event.PreviousAggregateSequence = uint64(previousAggregateSequence) event.PreviousAggregateTypeSequence = uint64(previousAggregateTypeSequence) @@ -132,7 +132,7 @@ func (db *CRDB) Push(ctx context.Context, events []*repository.Event, uniqueCons "aggregateId", event.AggregateID, "aggregateType", event.AggregateType, "eventType", event.Type, - "tenant", event.Tenant, + "instanceID", event.InstanceID, ).WithError(err).Info("query failed") return caos_errs.ThrowInternal(err, "SQL-SBP37", "unable to create event") } @@ -229,7 +229,7 @@ func (db *CRDB) eventQuery() string { ", editor_service" + ", editor_user" + ", resource_owner" + - ", tenant" + + ", instance_id" + ", aggregate_type" + ", aggregate_id" + ", aggregate_version" + @@ -250,8 +250,8 @@ func (db *CRDB) columnName(col repository.Field) string { return "event_sequence" case repository.FieldResourceOwner: return "resource_owner" - case repository.FieldTenant: - return "tenant" + case repository.FieldInstanceID: + return "instance_id" case repository.FieldEditorService: return "editor_service" case repository.FieldEditorUser: diff --git a/internal/eventstore/repository/sql/query.go b/internal/eventstore/repository/sql/query.go index be6672de14..eef4ec8a92 100644 --- a/internal/eventstore/repository/sql/query.go +++ b/internal/eventstore/repository/sql/query.go @@ -109,7 +109,7 @@ func eventsScanner(scanner scan, dest interface{}) (err error) { &event.EditorService, &event.EditorUser, &event.ResourceOwner, - &event.Tenant, + &event.InstanceID, &event.AggregateType, &event.AggregateID, &event.Version, diff --git a/internal/eventstore/repository/sql/query_test.go b/internal/eventstore/repository/sql/query_test.go index 8f0e7dd6c1..4e26eda709 100644 --- a/internal/eventstore/repository/sql/query_test.go +++ b/internal/eventstore/repository/sql/query_test.go @@ -130,7 +130,7 @@ func Test_prepareColumns(t *testing.T) { dest: &[]*repository.Event{}, }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", expected: []*repository.Event{ {AggregateID: "hodor", AggregateType: "user", Sequence: 5, Data: make(Data, 0)}, }, @@ -146,7 +146,7 @@ func Test_prepareColumns(t *testing.T) { dest: []*repository.Event{}, }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", dbErr: errors.IsErrorInvalidArgument, }, }, @@ -158,7 +158,7 @@ func Test_prepareColumns(t *testing.T) { dbErr: sql.ErrConnDone, }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", dbErr: errors.IsInternal, }, }, @@ -592,7 +592,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQuery(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, []driver.Value{repository.AggregateType("user")}, ), }, @@ -621,7 +621,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQuery(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence LIMIT \$2`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence LIMIT \$2`, []driver.Value{repository.AggregateType("user"), uint64(5)}, ), }, @@ -650,7 +650,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQuery(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC LIMIT \$2`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC LIMIT \$2`, []driver.Value{repository.AggregateType("user"), uint64(5)}, ), }, @@ -679,7 +679,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQueryErr(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, []driver.Value{repository.AggregateType("user")}, sql.ErrConnDone), }, @@ -708,7 +708,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQuery(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) ORDER BY event_sequence DESC`, []driver.Value{repository.AggregateType("user")}, &repository.Event{Sequence: 100}), }, @@ -776,7 +776,7 @@ func Test_query_events_mocked(t *testing.T) { }, fields: fields{ mock: newMockClient(t).expectQuery(t, - `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) OR \( aggregate_type = \$2 AND aggregate_id = \$3 \) ORDER BY event_sequence DESC LIMIT \$4`, + `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, previous_aggregate_type_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE \( aggregate_type = \$1 \) OR \( aggregate_type = \$2 AND aggregate_id = \$3 \) ORDER BY event_sequence DESC LIMIT \$4`, []driver.Value{repository.AggregateType("user"), repository.AggregateType("org"), "asdf42", uint64(5)}, ), }, diff --git a/internal/eventstore/search_query.go b/internal/eventstore/search_query.go index 927f1099b3..fbf199fd72 100644 --- a/internal/eventstore/search_query.go +++ b/internal/eventstore/search_query.go @@ -12,7 +12,7 @@ type SearchQueryBuilder struct { limit uint64 desc bool resourceOwner string - tenant string + instanceID string queries []*SearchQuery } @@ -68,9 +68,9 @@ func (factory *SearchQueryBuilder) ResourceOwner(resourceOwner string) *SearchQu return factory } -//Tenant defines the tenant (system) of the events -func (factory *SearchQueryBuilder) Tenant(tenant string) *SearchQueryBuilder { - factory.tenant = tenant +//InstanceID defines the instanceID (system) of the events +func (factory *SearchQueryBuilder) InstanceID(instanceID string) *SearchQueryBuilder { + factory.instanceID = instanceID return factory } @@ -145,13 +145,13 @@ func (query *SearchQuery) Builder() *SearchQueryBuilder { return query.builder } -func (builder *SearchQueryBuilder) build(tenantID string) (*repository.SearchQuery, error) { +func (builder *SearchQueryBuilder) build(instanceID string) (*repository.SearchQuery, error) { if builder == nil || len(builder.queries) < 1 || builder.columns.Validate() != nil { return nil, errors.ThrowPreconditionFailed(nil, "MODEL-4m9gs", "builder invalid") } - builder.tenant = tenantID + builder.instanceID = instanceID filters := make([][]*repository.Filter, len(builder.queries)) for i, query := range builder.queries { @@ -163,7 +163,7 @@ func (builder *SearchQueryBuilder) build(tenantID string) (*repository.SearchQue query.eventSequenceGreaterFilter, query.eventSequenceLessFilter, query.builder.resourceOwnerFilter, - query.builder.tenantFilter, + query.builder.instanceIDFilter, } { if filter := f(); filter != nil { if err := filter.Validate(); err != nil { @@ -247,11 +247,11 @@ func (builder *SearchQueryBuilder) resourceOwnerFilter() *repository.Filter { return repository.NewFilter(repository.FieldResourceOwner, builder.resourceOwner, repository.OperationEquals) } -func (builder *SearchQueryBuilder) tenantFilter() *repository.Filter { - if builder.tenant == "" { +func (builder *SearchQueryBuilder) instanceIDFilter() *repository.Filter { + if builder.instanceID == "" { return nil } - return repository.NewFilter(repository.FieldTenant, builder.tenant, repository.OperationEquals) + return repository.NewFilter(repository.FieldInstanceID, builder.instanceID, repository.OperationEquals) } func (query *SearchQuery) eventDataFilter() *repository.Filter { diff --git a/internal/eventstore/search_query_test.go b/internal/eventstore/search_query_test.go index ac137a12e6..0076a2469a 100644 --- a/internal/eventstore/search_query_test.go +++ b/internal/eventstore/search_query_test.go @@ -224,9 +224,9 @@ func TestSearchQuerybuilderSetters(t *testing.T) { func TestSearchQuerybuilderBuild(t *testing.T) { type args struct { - columns Columns - setters []func(*SearchQueryBuilder) *SearchQueryBuilder - tenant string + columns Columns + setters []func(*SearchQueryBuilder) *SearchQueryBuilder + instanceID string } type res struct { isErr func(err error) bool @@ -622,7 +622,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) { }, }, { - name: "filter aggregate type and tenant", + name: "filter aggregate type and instanceID", args: args{ columns: ColumnsEvent, setters: []func(*SearchQueryBuilder) *SearchQueryBuilder{ @@ -630,7 +630,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) { testSetAggregateTypes("user"), ), }, - tenant: "tenant", + instanceID: "instanceID", }, res: res{ isErr: nil, @@ -641,7 +641,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) { Filters: [][]*repository.Filter{ { repository.NewFilter(repository.FieldAggregateType, repository.AggregateType("user"), repository.OperationEquals), - repository.NewFilter(repository.FieldTenant, "tenant", repository.OperationEquals), + repository.NewFilter(repository.FieldInstanceID, "instanceID", repository.OperationEquals), }, }, }, @@ -668,7 +668,7 @@ func TestSearchQuerybuilderBuild(t *testing.T) { for _, f := range tt.args.setters { builder = f(builder) } - query, err := builder.build(tt.args.tenant) + query, err := builder.build(tt.args.instanceID) if tt.res.isErr != nil && !tt.res.isErr(err) { t.Errorf("wrong error(%T): %v", err, err) return diff --git a/internal/eventstore/subscription.go b/internal/eventstore/subscription.go index 6204116f60..57c99607b0 100644 --- a/internal/eventstore/subscription.go +++ b/internal/eventstore/subscription.go @@ -122,7 +122,7 @@ func mapEventToV1Event(event Event) *models.Event { AggregateType: models.AggregateType(event.Aggregate().Type), AggregateID: event.Aggregate().ID, ResourceOwner: event.Aggregate().ResourceOwner, - Tenant: event.Aggregate().Tenant, + InstanceID: event.Aggregate().InstanceID, EditorService: event.EditorService(), EditorUser: event.EditorUser(), Data: event.DataAsBytes(), diff --git a/internal/eventstore/v1/internal/repository/sql/db_mock_test.go b/internal/eventstore/v1/internal/repository/sql/db_mock_test.go index 9254a1f7f4..749e5b06c7 100644 --- a/internal/eventstore/v1/internal/repository/sql/db_mock_test.go +++ b/internal/eventstore/v1/internal/repository/sql/db_mock_test.go @@ -7,15 +7,16 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/caos/zitadel/internal/eventstore/v1/models" ) const ( - selectEscaped = `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore\.events WHERE aggregate_type = \$1` + selectEscaped = `SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore\.events WHERE aggregate_type = \$1` ) var ( - eventColumns = []string{"creation_date", "event_type", "event_sequence", "previous_aggregate_sequence", "event_data", "editor_service", "editor_user", "resource_owner", "tenant", "aggregate_type", "aggregate_id", "aggregate_version"} + eventColumns = []string{"creation_date", "event_type", "event_sequence", "previous_aggregate_sequence", "event_data", "editor_service", "editor_user", "resource_owner", "instance_id", "aggregate_type", "aggregate_id", "aggregate_version"} expectedFilterEventsLimitFormat = regexp.MustCompile(selectEscaped + ` ORDER BY event_sequence LIMIT \$2`).String() expectedFilterEventsDescFormat = regexp.MustCompile(selectEscaped + ` ORDER BY event_sequence DESC`).String() expectedFilterEventsAggregateIDLimit = regexp.MustCompile(selectEscaped + ` AND aggregate_id = \$2 ORDER BY event_sequence LIMIT \$3`).String() @@ -23,7 +24,7 @@ var ( expectedGetAllEvents = regexp.MustCompile(selectEscaped + ` ORDER BY event_sequence`).String() expectedInsertStatement = regexp.MustCompile(`INSERT INTO eventstore\.events ` + - `\(event_type, aggregate_type, aggregate_id, aggregate_version, creation_date, event_data, editor_user, editor_service, resource_owner, tenant, previous_aggregate_sequence, previous_aggregate_type_sequence\) ` + + `\(event_type, aggregate_type, aggregate_id, aggregate_version, creation_date, event_data, editor_user, editor_service, resource_owner, instance_id, previous_aggregate_sequence, previous_aggregate_type_sequence\) ` + `SELECT \$1, \$2, \$3, \$4, COALESCE\(\$5, now\(\)\), \$6, \$7, \$8, \$9, \$10, \$11 ` + `WHERE EXISTS \(` + `SELECT 1 FROM eventstore\.events WHERE aggregate_type = \$12 AND aggregate_id = \$13 HAVING MAX\(event_sequence\) = \$14 OR \(\$14::BIGINT IS NULL AND COUNT\(\*\) = 0\)\) ` + @@ -99,7 +100,7 @@ func (db *dbMock) expectRollback(err error) *dbMock { func (db *dbMock) expectInsertEvent(e *models.Event, returnedSequence uint64) *dbMock { db.mock.ExpectQuery(expectedInsertStatement). WithArgs( - e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, e.Tenant, Sequence(e.PreviousSequence), + e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, e.InstanceID, Sequence(e.PreviousSequence), e.AggregateType, e.AggregateID, Sequence(e.PreviousSequence), Sequence(e.PreviousSequence), ). WillReturnRows( @@ -113,7 +114,7 @@ func (db *dbMock) expectInsertEvent(e *models.Event, returnedSequence uint64) *d func (db *dbMock) expectInsertEventError(e *models.Event) *dbMock { db.mock.ExpectQuery(expectedInsertStatement). WithArgs( - e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, e.Tenant, Sequence(e.PreviousSequence), + e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, e.InstanceID, Sequence(e.PreviousSequence), e.AggregateType, e.AggregateID, Sequence(e.PreviousSequence), Sequence(e.PreviousSequence), ). WillReturnError(sql.ErrTxDone) @@ -124,7 +125,7 @@ func (db *dbMock) expectInsertEventError(e *models.Event) *dbMock { func (db *dbMock) expectFilterEventsLimit(aggregateType string, limit uint64, eventCount int) *dbMock { rows := sqlmock.NewRows(eventColumns) for i := 0; i < eventCount; i++ { - rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "tenant", "aggType", "aggID", "v1.0.0") + rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "instanceID", "aggType", "aggID", "v1.0.0") } db.mock.ExpectQuery(expectedFilterEventsLimitFormat). WithArgs(aggregateType, limit). @@ -135,7 +136,7 @@ func (db *dbMock) expectFilterEventsLimit(aggregateType string, limit uint64, ev func (db *dbMock) expectFilterEventsDesc(aggregateType string, eventCount int) *dbMock { rows := sqlmock.NewRows(eventColumns) for i := eventCount; i > 0; i-- { - rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "tenant", "aggType", "aggID", "v1.0.0") + rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "instanceID", "aggType", "aggID", "v1.0.0") } db.mock.ExpectQuery(expectedFilterEventsDescFormat). WillReturnRows(rows) @@ -145,7 +146,7 @@ func (db *dbMock) expectFilterEventsDesc(aggregateType string, eventCount int) * func (db *dbMock) expectFilterEventsAggregateIDLimit(aggregateType, aggregateID string, limit uint64) *dbMock { rows := sqlmock.NewRows(eventColumns) for i := limit; i > 0; i-- { - rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "tenant", "aggType", "aggID", "v1.0.0") + rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "instanceID", "aggType", "aggID", "v1.0.0") } db.mock.ExpectQuery(expectedFilterEventsAggregateIDLimit). WithArgs(aggregateType, aggregateID, limit). @@ -156,7 +157,7 @@ func (db *dbMock) expectFilterEventsAggregateIDLimit(aggregateType, aggregateID func (db *dbMock) expectFilterEventsAggregateIDTypeLimit(aggregateType, aggregateID string, limit uint64) *dbMock { rows := sqlmock.NewRows(eventColumns) for i := limit; i > 0; i-- { - rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "tenant", "aggType", "aggID", "v1.0.0") + rows.AddRow(time.Now(), "eventType", Sequence(i+1), Sequence(i), nil, "svc", "hodor", "org", "instanceID", "aggType", "aggID", "v1.0.0") } db.mock.ExpectQuery(expectedFilterEventsAggregateIDTypeLimit). WithArgs(aggregateType, aggregateID, limit). diff --git a/internal/eventstore/v1/internal/repository/sql/query.go b/internal/eventstore/v1/internal/repository/sql/query.go index ef4f38c1eb..f49db454c9 100644 --- a/internal/eventstore/v1/internal/repository/sql/query.go +++ b/internal/eventstore/v1/internal/repository/sql/query.go @@ -8,9 +8,10 @@ import ( "strings" "github.com/caos/logging" + "github.com/lib/pq" + z_errors "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/lib/pq" ) const ( @@ -23,7 +24,7 @@ const ( ", editor_service" + ", editor_user" + ", resource_owner" + - ", tenant" + + ", instance_id" + ", aggregate_type" + ", aggregate_id" + ", aggregate_version" + @@ -117,7 +118,7 @@ func prepareColumns(columns es_models.Columns) (string, func(s scan, dest interf &event.EditorService, &event.EditorUser, &event.ResourceOwner, - &event.Tenant, + &event.InstanceID, &event.AggregateType, &event.AggregateID, &event.AggregateVersion, @@ -177,8 +178,8 @@ func getField(field es_models.Field) string { return "event_sequence" case es_models.Field_ResourceOwner: return "resource_owner" - case es_models.Field_Tenant: - return "tenant" + case es_models.Field_InstanceID: + return "instance_id" case es_models.Field_EditorService: return "editor_service" case es_models.Field_EditorUser: diff --git a/internal/eventstore/v1/internal/repository/sql/query_test.go b/internal/eventstore/v1/internal/repository/sql/query_test.go index 4a7cae5ec6..c5d4c561dd 100644 --- a/internal/eventstore/v1/internal/repository/sql/query_test.go +++ b/internal/eventstore/v1/internal/repository/sql/query_test.go @@ -6,9 +6,10 @@ import ( "testing" "time" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/lib/pq" ) func Test_numberPlaceholder(t *testing.T) { @@ -80,7 +81,7 @@ func Test_getField(t *testing.T) { es_models.Field_AggregateID: "aggregate_id", es_models.Field_LatestSequence: "event_sequence", es_models.Field_ResourceOwner: "resource_owner", - es_models.Field_Tenant: "tenant", + es_models.Field_InstanceID: "instance_id", es_models.Field_EditorService: "editor_service", es_models.Field_EditorUser: "editor_user", es_models.Field_EventType: "event_type", @@ -235,7 +236,7 @@ func Test_prepareColumns(t *testing.T) { dest: new(es_models.Event), }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", dbRow: []interface{}{time.Time{}, es_models.EventType(""), uint64(5), Sequence(0), Data(nil), "", "", "", "", es_models.AggregateType("user"), "hodor", es_models.Version("")}, expected: es_models.Event{AggregateID: "hodor", AggregateType: "user", Sequence: 5, Data: make(Data, 0)}, }, @@ -247,7 +248,7 @@ func Test_prepareColumns(t *testing.T) { dest: new(uint64), }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", dbErr: errors.IsErrorInvalidArgument, }, }, @@ -259,7 +260,7 @@ func Test_prepareColumns(t *testing.T) { dbErr: sql.ErrConnDone, }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events", dbErr: errors.IsInternal, }, }, @@ -430,7 +431,7 @@ func Test_buildQuery(t *testing.T) { queryFactory: es_models.NewSearchQueryFactory("user").OrderDesc(), }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC", rowScanner: true, values: []interface{}{es_models.AggregateType("user")}, }, @@ -441,7 +442,7 @@ func Test_buildQuery(t *testing.T) { queryFactory: es_models.NewSearchQueryFactory("user").Limit(5), }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence LIMIT $2", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence LIMIT $2", rowScanner: true, values: []interface{}{es_models.AggregateType("user"), uint64(5)}, limit: 5, @@ -453,7 +454,7 @@ func Test_buildQuery(t *testing.T) { queryFactory: es_models.NewSearchQueryFactory("user").Limit(5).OrderDesc(), }, res: res{ - query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, tenant, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC LIMIT $2", + query: "SELECT creation_date, event_type, event_sequence, previous_aggregate_sequence, event_data, editor_service, editor_user, resource_owner, instance_id, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC LIMIT $2", rowScanner: true, values: []interface{}{es_models.AggregateType("user"), uint64(5)}, limit: 5, diff --git a/internal/eventstore/v1/models/aggregate.go b/internal/eventstore/v1/models/aggregate.go index c6e0849068..7da47a3d1a 100644 --- a/internal/eventstore/v1/models/aggregate.go +++ b/internal/eventstore/v1/models/aggregate.go @@ -23,7 +23,7 @@ type Aggregate struct { editorService string editorUser string resourceOwner string - tenant string + instanceID string Events []*Event Precondition *precondition } @@ -56,7 +56,7 @@ func (a *Aggregate) AppendEvent(typ EventType, payload interface{}) (*Aggregate, EditorService: a.editorService, EditorUser: a.editorUser, ResourceOwner: a.resourceOwner, - Tenant: a.tenant, + InstanceID: a.instanceID, } a.Events = append(a.Events, e) diff --git a/internal/eventstore/v1/models/aggregate_creator.go b/internal/eventstore/v1/models/aggregate_creator.go index 31942a9275..a2e112bdea 100644 --- a/internal/eventstore/v1/models/aggregate_creator.go +++ b/internal/eventstore/v1/models/aggregate_creator.go @@ -18,9 +18,10 @@ type option func(*Aggregate) func (c *AggregateCreator) NewAggregate(ctx context.Context, id string, typ AggregateType, version Version, previousSequence uint64, opts ...option) (*Aggregate, error) { ctxData := authz.GetCtxData(ctx) + instance := authz.GetInstance(ctx) editorUser := ctxData.UserID resourceOwner := ctxData.OrgID - tenant := ctxData.TenantID + instanceID := instance.ID aggregate := &Aggregate{ ID: id, @@ -31,7 +32,7 @@ func (c *AggregateCreator) NewAggregate(ctx context.Context, id string, typ Aggr editorService: c.serviceName, editorUser: editorUser, resourceOwner: resourceOwner, - tenant: tenant, + instanceID: instanceID, } for _, opt := range opts { diff --git a/internal/eventstore/v1/models/event.go b/internal/eventstore/v1/models/event.go index a497d5c090..de7b15c907 100644 --- a/internal/eventstore/v1/models/event.go +++ b/internal/eventstore/v1/models/event.go @@ -28,7 +28,7 @@ type Event struct { EditorService string EditorUser string ResourceOwner string - Tenant string + InstanceID string } func eventData(i interface{}) ([]byte, error) { diff --git a/internal/eventstore/v1/models/field.go b/internal/eventstore/v1/models/field.go index d4df34c3ea..39435ed5f5 100644 --- a/internal/eventstore/v1/models/field.go +++ b/internal/eventstore/v1/models/field.go @@ -11,5 +11,5 @@ const ( Field_EditorUser Field_EventType Field_CreationDate - Field_Tenant + Field_InstanceID ) diff --git a/internal/eventstore/v1/models/object.go b/internal/eventstore/v1/models/object.go index fb5a06e7eb..3fcb050473 100644 --- a/internal/eventstore/v1/models/object.go +++ b/internal/eventstore/v1/models/object.go @@ -8,7 +8,7 @@ type ObjectRoot struct { AggregateID string `json:"-"` Sequence uint64 `json:"-"` ResourceOwner string `json:"-"` - Tenant string `json:"-"` + InstanceID string `json:"-"` CreationDate time.Time `json:"-"` ChangeDate time.Time `json:"-"` } @@ -22,8 +22,8 @@ func (o *ObjectRoot) AppendEvent(event *Event) { if o.ResourceOwner == "" { o.ResourceOwner = event.ResourceOwner } - if o.Tenant == "" { - o.Tenant = event.Tenant + if o.InstanceID == "" { + o.InstanceID = event.InstanceID } o.ChangeDate = event.CreationDate diff --git a/internal/eventstore/v1/models/search_query.go b/internal/eventstore/v1/models/search_query.go index e07e510a9e..a4370c5918 100644 --- a/internal/eventstore/v1/models/search_query.go +++ b/internal/eventstore/v1/models/search_query.go @@ -4,6 +4,7 @@ import ( "time" "github.com/caos/logging" + "github.com/caos/zitadel/internal/errors" ) @@ -17,7 +18,7 @@ type SearchQueryFactory struct { sequenceTo uint64 eventTypes []EventType resourceOwner string - tenant string + instanceID string creationDate time.Time } @@ -63,8 +64,8 @@ func FactoryFromSearchQuery(query *SearchQuery) *SearchQueryFactory { } case Field_ResourceOwner: factory = factory.ResourceOwner(filter.value.(string)) - case Field_Tenant: - factory = factory.Tenant(filter.value.(string)) + case Field_InstanceID: + factory = factory.InstanceID(filter.value.(string)) case Field_EventType: factory = factory.EventTypes(filter.value.([]EventType)...) case Field_EditorService, Field_EditorUser: @@ -123,8 +124,8 @@ func (factory *SearchQueryFactory) ResourceOwner(resourceOwner string) *SearchQu return factory } -func (factory *SearchQueryFactory) Tenant(tenant string) *SearchQueryFactory { - factory.tenant = tenant +func (factory *SearchQueryFactory) InstanceID(instanceID string) *SearchQueryFactory { + factory.instanceID = instanceID return factory } @@ -159,7 +160,7 @@ func (factory *SearchQueryFactory) Build() (*searchQuery, error) { factory.sequenceToFilter, factory.eventTypeFilter, factory.resourceOwnerFilter, - factory.tenantFilter, + factory.instanceIDFilter, factory.creationDateNewerFilter, } { if filter := f(); filter != nil { @@ -231,11 +232,11 @@ func (factory *SearchQueryFactory) resourceOwnerFilter() *Filter { return NewFilter(Field_ResourceOwner, factory.resourceOwner, Operation_Equals) } -func (factory *SearchQueryFactory) tenantFilter() *Filter { - if factory.tenant == "" { +func (factory *SearchQueryFactory) instanceIDFilter() *Filter { + if factory.instanceID == "" { return nil } - return NewFilter(Field_Tenant, factory.tenant, Operation_Equals) + return NewFilter(Field_InstanceID, factory.instanceID, Operation_Equals) } func (factory *SearchQueryFactory) creationDateNewerFilter() *Filter { diff --git a/internal/eventstore/v1/models/search_query_old.go b/internal/eventstore/v1/models/search_query_old.go index ade859813a..75f4021a07 100644 --- a/internal/eventstore/v1/models/search_query_old.go +++ b/internal/eventstore/v1/models/search_query_old.go @@ -69,8 +69,8 @@ func (q *SearchQuery) ResourceOwnerFilter(resourceOwner string) *SearchQuery { return q.setFilter(NewFilter(Field_ResourceOwner, resourceOwner, Operation_Equals)) } -func (q *SearchQuery) TenantFilter(tenant string) *SearchQuery { - return q.setFilter(NewFilter(Field_Tenant, tenant, Operation_Equals)) +func (q *SearchQuery) InstanceIDFilter(instanceID string) *SearchQuery { + return q.setFilter(NewFilter(Field_InstanceID, instanceID, Operation_Equals)) } func (q *SearchQuery) CreationDateNewerFilter(time time.Time) *SearchQuery { diff --git a/internal/eventstore/v1/query/handler.go b/internal/eventstore/v1/query/handler.go index dc745aea60..00bc5e4829 100755 --- a/internal/eventstore/v1/query/handler.go +++ b/internal/eventstore/v1/query/handler.go @@ -54,7 +54,7 @@ func ReduceEvent(handler Handler, event *models.Event) { unprocessedEvents, err := handler.Eventstore().FilterEvents(context.Background(), searchQuery) if err != nil { - logging.LogWithFields("HANDL-L6YH1", "seq", event.Sequence).Warn("filter failed") + logging.WithFields("HANDL-L6YH1", "sequence", event.Sequence).Warn("filter failed") return } @@ -74,12 +74,12 @@ func ReduceEvent(handler Handler, event *models.Event) { } err = handler.Reduce(unprocessedEvent) - logging.LogWithFields("HANDL-V42TI", "seq", unprocessedEvent.Sequence).OnError(err).Warn("reduce failed") + logging.WithFields("HANDL-V42TI", "sequence", unprocessedEvent.Sequence).OnError(err).Warn("reduce failed") } if len(unprocessedEvents) == eventLimit { - logging.LogWithFields("QUERY-BSqe9", "seq", event.Sequence).Warn("didnt process event") + logging.WithFields("QUERY-BSqe9", "sequence", event.Sequence).Warn("didnt process event") return } err = handler.Reduce(event) - logging.LogWithFields("HANDL-wQDL2", "seq", event.Sequence).OnError(err).Warn("reduce failed") + logging.WithFields("HANDL-wQDL2", "sequence", event.Sequence).OnError(err).Warn("reduce failed") } diff --git a/internal/eventstore/write_model.go b/internal/eventstore/write_model.go index f99df62bf9..0ac28eb888 100644 --- a/internal/eventstore/write_model.go +++ b/internal/eventstore/write_model.go @@ -10,7 +10,7 @@ type WriteModel struct { ProcessedSequence uint64 `json:"-"` Events []Event `json:"-"` ResourceOwner string `json:"-"` - Tenant string `json:"-"` + InstanceID string `json:"-"` ChangeDate time.Time `json:"-"` } @@ -33,8 +33,8 @@ func (wm *WriteModel) Reduce() error { if wm.ResourceOwner == "" { wm.ResourceOwner = wm.Events[0].Aggregate().ResourceOwner } - if wm.Tenant == "" { - wm.Tenant = wm.Events[0].Aggregate().Tenant + if wm.InstanceID == "" { + wm.InstanceID = wm.Events[0].Aggregate().InstanceID } wm.ProcessedSequence = wm.Events[len(wm.Events)-1].Sequence() diff --git a/internal/iam/model/idp_config_view.go b/internal/iam/model/idp_config_view.go index a681be3b1e..42227317ce 100644 --- a/internal/iam/model/idp_config_view.go +++ b/internal/iam/model/idp_config_view.go @@ -51,6 +51,7 @@ const ( IDPConfigSearchKeyAggregateID IDPConfigSearchKeyIdpConfigID IDPConfigSearchKeyIdpProviderType + IDPConfigSearchKeyInstanceID ) type IDPConfigSearchQuery struct { diff --git a/internal/iam/model/label_policy_view.go b/internal/iam/model/label_policy_view.go index 4555d660b8..1a8d26e5ae 100644 --- a/internal/iam/model/label_policy_view.go +++ b/internal/iam/model/label_policy_view.go @@ -48,6 +48,7 @@ const ( LabelPolicySearchKeyUnspecified LabelPolicySearchKey = iota LabelPolicySearchKeyAggregateID LabelPolicySearchKeyState + LabelPolicySearchKeyInstanceID ) type LabelPolicySearchQuery struct { diff --git a/internal/iam/repository/view/model/idp_config.go b/internal/iam/repository/view/model/idp_config.go index 49c44ae717..c2bf98e75f 100644 --- a/internal/iam/repository/view/model/idp_config.go +++ b/internal/iam/repository/view/model/idp_config.go @@ -24,6 +24,7 @@ const ( IDPConfigKeyAggregateID = "aggregate_id" IDPConfigKeyName = "name" IDPConfigKeyProviderType = "idp_provider_type" + IDPConfigKeyInstanceID = "instance_id" ) type IDPConfigView struct { @@ -50,7 +51,8 @@ type IDPConfigView struct { JWTKeysEndpoint string `json:"keysEndpoint" gorm:"jwt_keys_endpoint"` JWTHeaderName string `json:"headerName" gorm:"jwt_header_name"` - Sequence uint64 `json:"-" gorm:"column:sequence"` + Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func IDPConfigViewToModel(idp *IDPConfigView) *model.IDPConfigView { @@ -120,6 +122,7 @@ func (i *IDPConfigView) AppendEvent(providerType model.IDPProviderType, event *m func (r *IDPConfigView) setRootData(event *models.Event) { r.AggregateID = event.AggregateID + r.InstanceID = event.InstanceID } func (r *IDPConfigView) SetData(event *models.Event) error { diff --git a/internal/iam/repository/view/model/idp_config_query.go b/internal/iam/repository/view/model/idp_config_query.go index e00680aef8..202b8048ce 100644 --- a/internal/iam/repository/view/model/idp_config_query.go +++ b/internal/iam/repository/view/model/idp_config_query.go @@ -59,6 +59,8 @@ func (key IDPConfigSearchKey) ToColumnName() string { return IDPConfigKeyName case iam_model.IDPConfigSearchKeyIdpProviderType: return IDPConfigKeyProviderType + case iam_model.IDPConfigSearchKeyInstanceID: + return IDPConfigKeyInstanceID default: return "" } diff --git a/internal/iam/repository/view/model/idp_provider.go b/internal/iam/repository/view/model/idp_provider.go index b6050c77ca..963837358f 100644 --- a/internal/iam/repository/view/model/idp_provider.go +++ b/internal/iam/repository/view/model/idp_provider.go @@ -2,12 +2,14 @@ package model import ( "encoding/json" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" "time" + org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" + es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/iam/model" @@ -32,7 +34,8 @@ type IDPProviderView struct { IDPProviderType int32 `json:"idpProviderType" gorm:"column:idp_provider_type"` IDPState int32 `json:"-" gorm:"column:idp_state"` - Sequence uint64 `json:"-" gorm:"column:sequence"` + Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func IDPProviderViewFromModel(provider *model.IDPProviderView) *IDPProviderView { @@ -87,6 +90,7 @@ func (i *IDPProviderView) AppendEvent(event *models.Event) (err error) { func (r *IDPProviderView) setRootData(event *models.Event) { r.AggregateID = event.AggregateID + r.InstanceID = event.InstanceID } func (r *IDPProviderView) SetData(event *models.Event) error { diff --git a/internal/iam/repository/view/model/label_policy.go b/internal/iam/repository/view/model/label_policy.go index 568e21da4a..5fb3e545a3 100644 --- a/internal/iam/repository/view/model/label_policy.go +++ b/internal/iam/repository/view/model/label_policy.go @@ -19,6 +19,7 @@ import ( const ( LabelPolicyKeyAggregateID = "aggregate_id" LabelPolicyKeyState = "label_policy_state" + LabelPolicyKeyInstanceID = "instance_id" ) type LabelPolicyView struct { @@ -45,7 +46,8 @@ type LabelPolicyView struct { DisableWatermark bool `json:"disableWatermark" gorm:"column:disable_watermark"` Default bool `json:"-" gorm:"-"` - Sequence uint64 `json:"-" gorm:"column:sequence"` + Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } type AssetView struct { @@ -189,6 +191,7 @@ func (i *LabelPolicyView) AppendEvent(event *models.Event) (err error) { func (r *LabelPolicyView) setRootData(event *models.Event) { r.AggregateID = event.AggregateID + r.InstanceID = event.InstanceID } func (r *LabelPolicyView) SetData(event *models.Event) error { diff --git a/internal/iam/repository/view/model/label_policy_query.go b/internal/iam/repository/view/model/label_policy_query.go index a4ee2914f7..f55101d15e 100644 --- a/internal/iam/repository/view/model/label_policy_query.go +++ b/internal/iam/repository/view/model/label_policy_query.go @@ -55,6 +55,9 @@ func (key LabelPolicySearchKey) ToColumnName() string { return LabelPolicyKeyAggregateID case iam_model.LabelPolicySearchKeyState: return LabelPolicyKeyState + case iam_model.LabelPolicySearchKeyInstanceID: + return LabelPolicyKeyInstanceID + default: return "" } diff --git a/internal/migration/command.go b/internal/migration/command.go new file mode 100644 index 0000000000..84f73ca94a --- /dev/null +++ b/internal/migration/command.go @@ -0,0 +1,77 @@ +package migration + +import "github.com/caos/zitadel/internal/eventstore" + +//SetupStep is the command pushed on the eventstore +type SetupStep struct { + typ eventstore.EventType + migration Migration + Name string `json:"name"` + Error error `json:"error,omitempty"` + done bool +} + +func setupStartedCmd(migration Migration) eventstore.Command { + return &SetupStep{ + migration: migration, + typ: startedType, + Name: migration.String(), + } +} + +func setupDoneCmd(migration Migration, err error) eventstore.Command { + s := &SetupStep{ + typ: doneType, + migration: migration, + Name: migration.String(), + } + + if err != nil { + s.typ = failedType + s.Error = err + } + + return s +} + +func (s *SetupStep) Aggregate() eventstore.Aggregate { + return eventstore.Aggregate{ + ID: aggregateID, + Type: aggregateType, + ResourceOwner: "SYSTEM", + Version: "v1", + } +} + +func (s *SetupStep) EditorService() string { + return "system" +} + +func (s *SetupStep) EditorUser() string { + return "system" +} + +func (s *SetupStep) Type() eventstore.EventType { + return s.typ +} + +func (s *SetupStep) Data() interface{} { + return s +} + +func (s *SetupStep) UniqueConstraints() []*eventstore.EventUniqueConstraint { + switch s.typ { + case startedType: + return []*eventstore.EventUniqueConstraint{ + eventstore.NewAddEventUniqueConstraint("migration_started", s.migration.String(), "Errors.Step.Started.AlreadyExists"), + } + case failedType: + return []*eventstore.EventUniqueConstraint{ + eventstore.NewRemoveEventUniqueConstraint("migration_started", s.migration.String()), + } + default: + return []*eventstore.EventUniqueConstraint{ + eventstore.NewAddEventUniqueConstraint("migration_done", s.migration.String(), "Errors.Step.Done.AlreadyExists"), + } + } +} diff --git a/internal/migration/migration.go b/internal/migration/migration.go new file mode 100644 index 0000000000..34c75965bb --- /dev/null +++ b/internal/migration/migration.go @@ -0,0 +1,84 @@ +package migration + +import ( + "context" + "encoding/json" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore" +) + +const ( + startedType = eventstore.EventType("system.migration.started") + doneType = eventstore.EventType("system.migration.done") + failedType = eventstore.EventType("system.migration.failed") + aggregateType = eventstore.AggregateType("system") + aggregateID = "SYSTEM" +) + +type Migration interface { + String() string + Execute(context.Context) error +} + +func Migrate(ctx context.Context, es *eventstore.Eventstore, migration Migration) (err error) { + if should, err := shouldExec(ctx, es, migration); !should || err != nil { + return err + } + + if _, err = es.Push(ctx, setupStartedCmd(migration)); err != nil { + return err + } + + err = migration.Execute(ctx) + logging.OnError(err).Error("migration failed") + + _, err = es.Push(ctx, setupDoneCmd(migration, err)) + return err +} + +func shouldExec(ctx context.Context, es *eventstore.Eventstore, migration Migration) (should bool, err error) { + events, err := es.Filter(ctx, eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). + OrderDesc(). + AddQuery(). + AggregateTypes(aggregateType). + AggregateIDs(aggregateID). + EventTypes(startedType, doneType, failedType). + Builder()) + if err != nil { + return false, err + } + + if len(events) == 0 { + return true, nil + } + if events[len(events)-1].Type() == startedType { + return false, nil + } + + for _, e := range events { + step := new(SetupStep) + + err = json.Unmarshal(e.DataAsBytes(), step) + if err != nil { + return false, err + } + + if step.Name != migration.String() { + continue + } + + switch e.Type() { + case startedType, doneType: + //TODO: if started should we wait until done/failed? + return false, nil + case failedType: + //TODO: how to allow retries? + logging.WithFields("migration", migration.String()).Error("failed before") + return false, errors.ThrowInternal(nil, "MIGRA-mjI2E", "migration failed before") + } + } + return true, nil +} diff --git a/internal/project/model/org_project_mapping_view.go b/internal/project/model/org_project_mapping_view.go index 3b71510666..1b45f2c17a 100644 --- a/internal/project/model/org_project_mapping_view.go +++ b/internal/project/model/org_project_mapping_view.go @@ -26,6 +26,7 @@ const ( OrgProjectMappingSearchKeyProjectID OrgProjectMappingSearchKeyOrgID OrgProjectMappingSearchKeyProjectGrantID + OrgProjectMappingSearchKeyInstanceID ) type OrgProjectMappingViewSearchQuery struct { diff --git a/internal/project/repository/view/model/org_project_mapping.go b/internal/project/repository/view/model/org_project_mapping.go index e2f5705d38..e4de47725e 100644 --- a/internal/project/repository/view/model/org_project_mapping.go +++ b/internal/project/repository/view/model/org_project_mapping.go @@ -4,10 +4,12 @@ const ( OrgProjectMappingKeyProjectID = "project_id" OrgProjectMappingKeyOrgID = "org_id" OrgProjectMappingKeyProjectGrantID = "project_grant_id" + OrgProjectMappingKeyInstanceID = "instance_id" ) type OrgProjectMapping struct { ProjectID string `json:"-" gorm:"column:project_id;primary_key"` OrgID string `json:"-" gorm:"column:org_id;primary_key"` - ProjectGrantID string `json:"-" gorm:"column:project_grant_id;"` + ProjectGrantID string `json:"-" gorm:"column:project_grant_id"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } diff --git a/internal/project/repository/view/model/org_project_mapping_query.go b/internal/project/repository/view/model/org_project_mapping_query.go index cc638fcb5c..94e0cbc80c 100644 --- a/internal/project/repository/view/model/org_project_mapping_query.go +++ b/internal/project/repository/view/model/org_project_mapping_query.go @@ -57,6 +57,8 @@ func (key OrgProjectMappingSearchKey) ToColumnName() string { return OrgProjectMappingKeyProjectID case proj_model.OrgProjectMappingSearchKeyProjectGrantID: return OrgProjectMappingKeyProjectGrantID + case proj_model.OrgProjectMappingSearchKeyInstanceID: + return OrgProjectMappingKeyInstanceID default: return "" } diff --git a/internal/project/repository/view/model/project_grant.go b/internal/project/repository/view/model/project_grant.go index 31a0261516..ffa27386a9 100644 --- a/internal/project/repository/view/model/project_grant.go +++ b/internal/project/repository/view/model/project_grant.go @@ -2,13 +2,15 @@ package model import ( "encoding/json" + "time" + "github.com/caos/logging" + "github.com/lib/pq" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/project/model" es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - "github.com/lib/pq" - "time" ) const ( @@ -39,6 +41,7 @@ type ProjectGrant struct { GrantID string `json:"grantId"` GrantedOrgID string `json:"grantedOrgId"` RoleKeys []string `json:"roleKeys"` + InstanceID string `json:"instanceID"` } func ProjectGrantFromModel(project *model.ProjectGrantView) *ProjectGrantView { diff --git a/internal/query/action.go b/internal/query/action.go index 099d519590..e493086088 100644 --- a/internal/query/action.go +++ b/internal/query/action.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -33,6 +35,10 @@ var ( name: projection.ActionResourceOwnerCol, table: actionTable, } + ActionColumnInstanceID = Column{ + name: projection.ActionInstanceIDCol, + table: actionTable, + } ActionColumnSequence = Column{ name: projection.ActionSequenceCol, table: actionTable, @@ -93,7 +99,11 @@ func (q *ActionSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder { func (q *Queries) SearchActions(ctx context.Context, queries *ActionSearchQueries) (actions *Actions, err error) { query, scan := prepareActionsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }). + ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-SDgwg", "Errors.Query.InvalidRequest") } @@ -116,6 +126,7 @@ func (q *Queries) GetActionByID(ctx context.Context, id string, orgID string) (* sq.Eq{ ActionColumnID.identifier(): id, ActionColumnResourceOwner.identifier(): orgID, + ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dgff3", "Errors.Query.SQLStatement") diff --git a/internal/query/action_flow.go b/internal/query/action_flow.go index c2285659bf..b6a663fe37 100644 --- a/internal/query/action_flow.go +++ b/internal/query/action_flow.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -21,6 +23,14 @@ var ( name: projection.FlowTypeCol, table: flowsTriggersTable, } + FlowsTriggersColumnChangeDate = Column{ + name: projection.FlowChangeDateCol, + table: flowsTriggersTable, + } + FlowsTriggersColumnSequence = Column{ + name: projection.FlowSequenceCol, + table: flowsTriggersTable, + } FlowsTriggersColumnTriggerType = Column{ name: projection.FlowTriggerTypeCol, table: flowsTriggersTable, @@ -29,6 +39,10 @@ var ( name: projection.FlowResourceOwnerCol, table: flowsTriggersTable, } + FlowsTriggersColumnInstanceID = Column{ + name: projection.FlowInstanceIDCol, + table: flowsTriggersTable, + } FlowsTriggersColumnTriggerSequence = Column{ name: projection.FlowActionTriggerSequenceCol, table: flowsTriggersTable, @@ -40,10 +54,9 @@ var ( ) type Flow struct { - CreationDate time.Time //TODO: add in projection - ChangeDate time.Time //TODO: add in projection - ResourceOwner string //TODO: add in projection - Sequence uint64 //TODO: add in projection + ChangeDate time.Time + ResourceOwner string + Sequence uint64 Type domain.FlowType TriggerActions map[domain.TriggerType][]*Action @@ -55,6 +68,7 @@ func (q *Queries) GetFlow(ctx context.Context, flowType domain.FlowType, orgID s sq.Eq{ FlowsTriggersColumnFlowType.identifier(): flowType, FlowsTriggersColumnResourceOwner.identifier(): orgID, + FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-HBRh3", "Errors.Query.InvalidRequest") @@ -74,6 +88,7 @@ func (q *Queries) GetActiveActionsByFlowAndTriggerType(ctx context.Context, flow FlowsTriggersColumnFlowType.identifier(): flowType, FlowsTriggersColumnTriggerType.identifier(): triggerType, FlowsTriggersColumnResourceOwner.identifier(): orgID, + FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, ActionColumnState.identifier(): domain.ActionStateActive, }, ).ToSql() @@ -92,7 +107,8 @@ func (q *Queries) GetFlowTypesOfActionID(ctx context.Context, actionID string) ( stmt, scan := prepareFlowTypesQuery() query, args, err := stmt.Where( sq.Eq{ - FlowsTriggersColumnActionID.identifier(): actionID, + FlowsTriggersColumnActionID.identifier(): actionID, + FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -185,6 +201,9 @@ func prepareFlowQuery() (sq.SelectBuilder, func(*sql.Rows) (*Flow, error)) { FlowsTriggersColumnTriggerType.identifier(), FlowsTriggersColumnTriggerSequence.identifier(), FlowsTriggersColumnFlowType.identifier(), + FlowsTriggersColumnChangeDate.identifier(), + FlowsTriggersColumnSequence.identifier(), + FlowsTriggersColumnResourceOwner.identifier(), ). From(flowsTriggersTable.name). LeftJoin(join(ActionColumnID, FlowsTriggersColumnActionID)). @@ -194,7 +213,6 @@ func prepareFlowQuery() (sq.SelectBuilder, func(*sql.Rows) (*Flow, error)) { TriggerActions: make(map[domain.TriggerType][]*Action), } for rows.Next() { - // action := new(Action) var ( actionID sql.NullString actionCreationDate pq.NullTime @@ -207,7 +225,6 @@ func prepareFlowQuery() (sq.SelectBuilder, func(*sql.Rows) (*Flow, error)) { triggerType domain.TriggerType triggerSequence int - flowType domain.FlowType ) err := rows.Scan( &actionID, @@ -220,12 +237,14 @@ func prepareFlowQuery() (sq.SelectBuilder, func(*sql.Rows) (*Flow, error)) { &actionScript, &triggerType, &triggerSequence, - &flowType, + &flow.Type, + &flow.ChangeDate, + &flow.Sequence, + &flow.ResourceOwner, ) if err != nil { return nil, err } - flow.Type = flowType if !actionID.Valid { continue } diff --git a/internal/query/action_flow_test.go b/internal/query/action_flow_test.go index 924678fdb9..fcc42d699d 100644 --- a/internal/query/action_flow_test.go +++ b/internal/query/action_flow_test.go @@ -27,19 +27,22 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.flows_triggers.trigger_type,`+ - ` zitadel.projections.flows_triggers.trigger_sequence,`+ - ` zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.flows_triggers.trigger_type,`+ + ` projections.flows_triggers.trigger_sequence,`+ + ` projections.flows_triggers.flow_type,`+ + ` projections.flows_triggers.change_date,`+ + ` projections.flows_triggers.sequence,`+ + ` projections.flows_triggers.resource_owner`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), nil, nil, ), @@ -51,19 +54,22 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.flows_triggers.trigger_type,`+ - ` zitadel.projections.flows_triggers.trigger_sequence,`+ - ` zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.flows_triggers.trigger_type,`+ + ` projections.flows_triggers.trigger_sequence,`+ + ` projections.flows_triggers.flow_type,`+ + ` projections.flows_triggers.change_date,`+ + ` projections.flows_triggers.sequence,`+ + ` projections.flows_triggers.resource_owner`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), []string{ "id", "creation_date", @@ -73,9 +79,13 @@ func Test_FlowPrepares(t *testing.T) { "sequence", "name", "script", + //flow "trigger_type", "trigger_sequence", "flow_type", + "change_date", + "sequence", + "resource_owner", }, [][]driver.Value{ { @@ -90,12 +100,18 @@ func Test_FlowPrepares(t *testing.T) { domain.TriggerTypePreCreation, uint64(20211109), domain.FlowTypeExternalAuthentication, + testNow, + uint64(20211115), + "owner", }, }, ), }, object: &Flow{ - Type: domain.FlowTypeExternalAuthentication, + ChangeDate: testNow, + ResourceOwner: "owner", + Sequence: 20211115, + Type: domain.FlowTypeExternalAuthentication, TriggerActions: map[domain.TriggerType][]*Action{ domain.TriggerTypePreCreation: { { @@ -117,19 +133,22 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.flows_triggers.trigger_type,`+ - ` zitadel.projections.flows_triggers.trigger_sequence,`+ - ` zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.flows_triggers.trigger_type,`+ + ` projections.flows_triggers.trigger_sequence,`+ + ` projections.flows_triggers.flow_type,`+ + ` projections.flows_triggers.change_date,`+ + ` projections.flows_triggers.sequence,`+ + ` projections.flows_triggers.resource_owner`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), []string{ "id", "creation_date", @@ -139,9 +158,13 @@ func Test_FlowPrepares(t *testing.T) { "sequence", "name", "script", + //flow "trigger_type", "trigger_sequence", "flow_type", + "change_date", + "sequence", + "resource_owner", }, [][]driver.Value{ { @@ -156,6 +179,9 @@ func Test_FlowPrepares(t *testing.T) { domain.TriggerTypePreCreation, uint64(20211109), domain.FlowTypeExternalAuthentication, + testNow, + uint64(20211115), + "owner", }, { "action-id-post", @@ -169,12 +195,18 @@ func Test_FlowPrepares(t *testing.T) { domain.TriggerTypePostCreation, uint64(20211109), domain.FlowTypeExternalAuthentication, + testNow, + uint64(20211115), + "owner", }, }, ), }, object: &Flow{ - Type: domain.FlowTypeExternalAuthentication, + ChangeDate: testNow, + ResourceOwner: "owner", + Sequence: 20211115, + Type: domain.FlowTypeExternalAuthentication, TriggerActions: map[domain.TriggerType][]*Action{ domain.TriggerTypePreCreation: { { @@ -208,19 +240,22 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.flows_triggers.trigger_type,`+ - ` zitadel.projections.flows_triggers.trigger_sequence,`+ - ` zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.flows_triggers.trigger_type,`+ + ` projections.flows_triggers.trigger_sequence,`+ + ` projections.flows_triggers.flow_type,`+ + ` projections.flows_triggers.change_date,`+ + ` projections.flows_triggers.sequence,`+ + ` projections.flows_triggers.resource_owner`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), []string{ "id", "creation_date", @@ -230,9 +265,13 @@ func Test_FlowPrepares(t *testing.T) { "sequence", "name", "script", + //flow "trigger_type", "trigger_sequence", "flow_type", + "change_date", + "sequence", + "resource_owner", }, [][]driver.Value{ { @@ -247,11 +286,17 @@ func Test_FlowPrepares(t *testing.T) { domain.TriggerTypePostCreation, uint64(20211109), domain.FlowTypeExternalAuthentication, + testNow, + uint64(20211115), + "owner", }, }, ), }, object: &Flow{ + ChangeDate: testNow, + ResourceOwner: "owner", + Sequence: 20211115, Type: domain.FlowTypeExternalAuthentication, TriggerActions: map[domain.TriggerType][]*Action{}, }, @@ -261,19 +306,22 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.flows_triggers.trigger_type,`+ - ` zitadel.projections.flows_triggers.trigger_sequence,`+ - ` zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.flows_triggers.trigger_type,`+ + ` projections.flows_triggers.trigger_sequence,`+ + ` projections.flows_triggers.flow_type,`+ + ` projections.flows_triggers.change_date,`+ + ` projections.flows_triggers.sequence,`+ + ` projections.flows_triggers.resource_owner`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -290,16 +338,16 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareTriggerActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), nil, nil, ), @@ -311,16 +359,16 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareTriggerActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), []string{ "id", "creation_date", @@ -363,16 +411,16 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareTriggerActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), []string{ "id", "creation_date", @@ -435,16 +483,16 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareTriggerActionsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script`+ - ` FROM zitadel.projections.flows_triggers`+ - ` LEFT JOIN zitadel.projections.actions ON zitadel.projections.flows_triggers.action_id = zitadel.projections.actions.id`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.action_state,`+ + ` projections.actions.sequence,`+ + ` projections.actions.name,`+ + ` projections.actions.script`+ + ` FROM projections.flows_triggers`+ + ` LEFT JOIN projections.actions ON projections.flows_triggers.action_id = projections.actions.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -461,8 +509,8 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowTypesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`), + regexp.QuoteMeta(`SELECT projections.flows_triggers.flow_type`+ + ` FROM projections.flows_triggers`), nil, nil, ), @@ -474,8 +522,8 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowTypesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`), + regexp.QuoteMeta(`SELECT projections.flows_triggers.flow_type`+ + ` FROM projections.flows_triggers`), []string{ "flow_type", }, @@ -495,8 +543,8 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowTypesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`), + regexp.QuoteMeta(`SELECT projections.flows_triggers.flow_type`+ + ` FROM projections.flows_triggers`), []string{ "flow_type", }, @@ -520,8 +568,8 @@ func Test_FlowPrepares(t *testing.T) { prepare: prepareFlowTypesQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.flows_triggers.flow_type`+ - ` FROM zitadel.projections.flows_triggers`), + regexp.QuoteMeta(`SELECT projections.flows_triggers.flow_type`+ + ` FROM projections.flows_triggers`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/action_test.go b/internal/query/action_test.go index dfda629a97..fe036b21e9 100644 --- a/internal/query/action_test.go +++ b/internal/query/action_test.go @@ -29,18 +29,18 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail,`+ + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.actions`), + ` FROM projections.actions`), nil, nil, ), @@ -52,18 +52,18 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail,`+ + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.actions`), + ` FROM projections.actions`), []string{ "id", "creation_date", @@ -118,18 +118,18 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail,`+ + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.actions`), + ` FROM projections.actions`), []string{ "id", "creation_date", @@ -208,18 +208,18 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail,`+ + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.actions`), + ` FROM projections.actions`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -236,17 +236,17 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail`+ - ` FROM zitadel.projections.actions`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail`+ + ` FROM projections.actions`), nil, nil, ), @@ -264,17 +264,17 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail`+ - ` FROM zitadel.projections.actions`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail`+ + ` FROM projections.actions`), []string{ "id", "creation_date", @@ -319,17 +319,17 @@ func Test_ActionPrepares(t *testing.T) { prepare: prepareActionQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.actions.id,`+ - ` zitadel.projections.actions.creation_date,`+ - ` zitadel.projections.actions.change_date,`+ - ` zitadel.projections.actions.resource_owner,`+ - ` zitadel.projections.actions.sequence,`+ - ` zitadel.projections.actions.action_state,`+ - ` zitadel.projections.actions.name,`+ - ` zitadel.projections.actions.script,`+ - ` zitadel.projections.actions.timeout,`+ - ` zitadel.projections.actions.allowed_to_fail`+ - ` FROM zitadel.projections.actions`), + regexp.QuoteMeta(`SELECT projections.actions.id,`+ + ` projections.actions.creation_date,`+ + ` projections.actions.change_date,`+ + ` projections.actions.resource_owner,`+ + ` projections.actions.sequence,`+ + ` projections.actions.action_state,`+ + ` projections.actions.name,`+ + ` projections.actions.script,`+ + ` projections.actions.timeout,`+ + ` projections.actions.allowed_to_fail`+ + ` FROM projections.actions`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/app.go b/internal/query/app.go index 0b716410af..3ad0a96e93 100644 --- a/internal/query/app.go +++ b/internal/query/app.go @@ -9,6 +9,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" @@ -102,6 +104,10 @@ var ( name: projection.AppColumnResourceOwner, table: appsTable, } + AppColumnInstanceID = Column{ + name: projection.AppColumnInstanceID, + table: appsTable, + } AppColumnState = Column{ name: projection.AppColumnState, table: appsTable, @@ -204,8 +210,9 @@ func (q *Queries) AppByProjectAndAppID(ctx context.Context, projectID, appID str stmt, scan := prepareAppQuery() query, args, err := stmt.Where( sq.Eq{ - AppColumnID.identifier(): appID, - AppColumnProjectID.identifier(): projectID, + AppColumnID.identifier(): appID, + AppColumnProjectID.identifier(): projectID, + AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -219,7 +226,10 @@ func (q *Queries) AppByProjectAndAppID(ctx context.Context, projectID, appID str func (q *Queries) AppByID(ctx context.Context, appID string) (*App, error) { stmt, scan := prepareAppQuery() query, args, err := stmt.Where( - sq.Eq{AppColumnID.identifier(): appID}, + sq.Eq{ + AppColumnID.identifier(): appID, + AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }, ).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-immt9", "Errors.Query.SQLStatement") @@ -232,7 +242,10 @@ func (q *Queries) AppByID(ctx context.Context, appID string) (*App, error) { func (q *Queries) ProjectIDFromOIDCClientID(ctx context.Context, appID string) (string, error) { stmt, scan := prepareProjectIDByAppQuery() query, args, err := stmt.Where( - sq.Eq{AppOIDCConfigColumnClientID.identifier(): appID}, + sq.Eq{ + AppOIDCConfigColumnClientID.identifier(): appID, + AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }, ).ToSql() if err != nil { return "", errors.ThrowInternal(err, "QUERY-7d92U", "Errors.Query.SQLStatement") @@ -245,9 +258,12 @@ func (q *Queries) ProjectIDFromOIDCClientID(ctx context.Context, appID string) ( func (q *Queries) ProjectIDFromClientID(ctx context.Context, appID string) (string, error) { stmt, scan := prepareProjectIDByAppQuery() query, args, err := stmt.Where( - sq.Or{ - sq.Eq{AppOIDCConfigColumnClientID.identifier(): appID}, - sq.Eq{AppAPIConfigColumnClientID.identifier(): appID}, + sq.And{ + sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID}, + sq.Or{ + sq.Eq{AppOIDCConfigColumnClientID.identifier(): appID}, + sq.Eq{AppAPIConfigColumnClientID.identifier(): appID}, + }, }, ).ToSql() if err != nil { @@ -261,7 +277,10 @@ func (q *Queries) ProjectIDFromClientID(ctx context.Context, appID string) (stri func (q *Queries) ProjectByOIDCClientID(ctx context.Context, id string) (*Project, error) { stmt, scan := prepareProjectByAppQuery() query, args, err := stmt.Where( - sq.Eq{AppOIDCConfigColumnClientID.identifier(): id}, + sq.Eq{ + AppOIDCConfigColumnClientID.identifier(): id, + AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }, ).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-XhJi4", "Errors.Query.SQLStatement") @@ -276,6 +295,7 @@ func (q *Queries) AppByOIDCClientID(ctx context.Context, clientID string) (*App, query, args, err := stmt.Where( sq.Eq{ AppOIDCConfigColumnClientID.identifier(): clientID, + AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -289,9 +309,12 @@ func (q *Queries) AppByOIDCClientID(ctx context.Context, clientID string) (*App, func (q *Queries) AppByClientID(ctx context.Context, clientID string) (*App, error) { stmt, scan := prepareAppQuery() query, args, err := stmt.Where( - sq.Or{ - sq.Eq{AppOIDCConfigColumnClientID.identifier(): clientID}, - sq.Eq{AppAPIConfigColumnClientID.identifier(): clientID}, + sq.And{ + sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID}, + sq.Or{ + sq.Eq{AppOIDCConfigColumnClientID.identifier(): clientID}, + sq.Eq{AppAPIConfigColumnClientID.identifier(): clientID}, + }, }, ).ToSql() if err != nil { @@ -304,7 +327,10 @@ func (q *Queries) AppByClientID(ctx context.Context, clientID string) (*App, err func (q *Queries) SearchApps(ctx context.Context, queries *AppSearchQueries) (*Apps, error) { query, scan := prepareAppsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where( + sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID}, + ).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-fajp8", "Errors.Query.InvalidRequest") } @@ -323,7 +349,10 @@ func (q *Queries) SearchApps(ctx context.Context, queries *AppSearchQueries) (*A func (q *Queries) SearchClientIDs(ctx context.Context, queries *AppSearchQueries) ([]string, error) { query, scan := prepareClientIDsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where( + sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID}, + ).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-fajp8", "Errors.Query.InvalidRequest") } diff --git a/internal/query/app_test.go b/internal/query/app_test.go index ec482b734d..4f78500da8 100644 --- a/internal/query/app_test.go +++ b/internal/query/app_test.go @@ -16,95 +16,95 @@ import ( ) var ( - expectedAppQuery = regexp.QuoteMeta(`SELECT zitadel.projections.apps.id,` + - ` zitadel.projections.apps.name,` + - ` zitadel.projections.apps.project_id,` + - ` zitadel.projections.apps.creation_date,` + - ` zitadel.projections.apps.change_date,` + - ` zitadel.projections.apps.resource_owner,` + - ` zitadel.projections.apps.state,` + - ` zitadel.projections.apps.sequence,` + + expectedAppQuery = regexp.QuoteMeta(`SELECT projections.apps.id,` + + ` projections.apps.name,` + + ` projections.apps.project_id,` + + ` projections.apps.creation_date,` + + ` projections.apps.change_date,` + + ` projections.apps.resource_owner,` + + ` projections.apps.state,` + + ` projections.apps.sequence,` + // api config - ` zitadel.projections.apps_api_configs.app_id,` + - ` zitadel.projections.apps_api_configs.client_id,` + - ` zitadel.projections.apps_api_configs.auth_method,` + + ` projections.apps_api_configs.app_id,` + + ` projections.apps_api_configs.client_id,` + + ` projections.apps_api_configs.auth_method,` + // oidc config - ` zitadel.projections.apps_oidc_configs.app_id,` + - ` zitadel.projections.apps_oidc_configs.version,` + - ` zitadel.projections.apps_oidc_configs.client_id,` + - ` zitadel.projections.apps_oidc_configs.redirect_uris,` + - ` zitadel.projections.apps_oidc_configs.response_types,` + - ` zitadel.projections.apps_oidc_configs.grant_types,` + - ` zitadel.projections.apps_oidc_configs.application_type,` + - ` zitadel.projections.apps_oidc_configs.auth_method_type,` + - ` zitadel.projections.apps_oidc_configs.post_logout_redirect_uris,` + - ` zitadel.projections.apps_oidc_configs.is_dev_mode,` + - ` zitadel.projections.apps_oidc_configs.access_token_type,` + - ` zitadel.projections.apps_oidc_configs.access_token_role_assertion,` + - ` zitadel.projections.apps_oidc_configs.id_token_role_assertion,` + - ` zitadel.projections.apps_oidc_configs.id_token_userinfo_assertion,` + - ` zitadel.projections.apps_oidc_configs.clock_skew,` + - ` zitadel.projections.apps_oidc_configs.additional_origins` + - ` FROM zitadel.projections.apps` + - ` LEFT JOIN zitadel.projections.apps_api_configs ON zitadel.projections.apps.id = zitadel.projections.apps_api_configs.app_id` + - ` LEFT JOIN zitadel.projections.apps_oidc_configs ON zitadel.projections.apps.id = zitadel.projections.apps_oidc_configs.app_id`) - expectedAppsQuery = regexp.QuoteMeta(`SELECT zitadel.projections.apps.id,` + - ` zitadel.projections.apps.name,` + - ` zitadel.projections.apps.project_id,` + - ` zitadel.projections.apps.creation_date,` + - ` zitadel.projections.apps.change_date,` + - ` zitadel.projections.apps.resource_owner,` + - ` zitadel.projections.apps.state,` + - ` zitadel.projections.apps.sequence,` + + ` projections.apps_oidc_configs.app_id,` + + ` projections.apps_oidc_configs.version,` + + ` projections.apps_oidc_configs.client_id,` + + ` projections.apps_oidc_configs.redirect_uris,` + + ` projections.apps_oidc_configs.response_types,` + + ` projections.apps_oidc_configs.grant_types,` + + ` projections.apps_oidc_configs.application_type,` + + ` projections.apps_oidc_configs.auth_method_type,` + + ` projections.apps_oidc_configs.post_logout_redirect_uris,` + + ` projections.apps_oidc_configs.is_dev_mode,` + + ` projections.apps_oidc_configs.access_token_type,` + + ` projections.apps_oidc_configs.access_token_role_assertion,` + + ` projections.apps_oidc_configs.id_token_role_assertion,` + + ` projections.apps_oidc_configs.id_token_userinfo_assertion,` + + ` projections.apps_oidc_configs.clock_skew,` + + ` projections.apps_oidc_configs.additional_origins` + + ` FROM projections.apps` + + ` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` + + ` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`) + expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps.id,` + + ` projections.apps.name,` + + ` projections.apps.project_id,` + + ` projections.apps.creation_date,` + + ` projections.apps.change_date,` + + ` projections.apps.resource_owner,` + + ` projections.apps.state,` + + ` projections.apps.sequence,` + // api config - ` zitadel.projections.apps_api_configs.app_id,` + - ` zitadel.projections.apps_api_configs.client_id,` + - ` zitadel.projections.apps_api_configs.auth_method,` + + ` projections.apps_api_configs.app_id,` + + ` projections.apps_api_configs.client_id,` + + ` projections.apps_api_configs.auth_method,` + // oidc config - ` zitadel.projections.apps_oidc_configs.app_id,` + - ` zitadel.projections.apps_oidc_configs.version,` + - ` zitadel.projections.apps_oidc_configs.client_id,` + - ` zitadel.projections.apps_oidc_configs.redirect_uris,` + - ` zitadel.projections.apps_oidc_configs.response_types,` + - ` zitadel.projections.apps_oidc_configs.grant_types,` + - ` zitadel.projections.apps_oidc_configs.application_type,` + - ` zitadel.projections.apps_oidc_configs.auth_method_type,` + - ` zitadel.projections.apps_oidc_configs.post_logout_redirect_uris,` + - ` zitadel.projections.apps_oidc_configs.is_dev_mode,` + - ` zitadel.projections.apps_oidc_configs.access_token_type,` + - ` zitadel.projections.apps_oidc_configs.access_token_role_assertion,` + - ` zitadel.projections.apps_oidc_configs.id_token_role_assertion,` + - ` zitadel.projections.apps_oidc_configs.id_token_userinfo_assertion,` + - ` zitadel.projections.apps_oidc_configs.clock_skew,` + - ` zitadel.projections.apps_oidc_configs.additional_origins,` + + ` projections.apps_oidc_configs.app_id,` + + ` projections.apps_oidc_configs.version,` + + ` projections.apps_oidc_configs.client_id,` + + ` projections.apps_oidc_configs.redirect_uris,` + + ` projections.apps_oidc_configs.response_types,` + + ` projections.apps_oidc_configs.grant_types,` + + ` projections.apps_oidc_configs.application_type,` + + ` projections.apps_oidc_configs.auth_method_type,` + + ` projections.apps_oidc_configs.post_logout_redirect_uris,` + + ` projections.apps_oidc_configs.is_dev_mode,` + + ` projections.apps_oidc_configs.access_token_type,` + + ` projections.apps_oidc_configs.access_token_role_assertion,` + + ` projections.apps_oidc_configs.id_token_role_assertion,` + + ` projections.apps_oidc_configs.id_token_userinfo_assertion,` + + ` projections.apps_oidc_configs.clock_skew,` + + ` projections.apps_oidc_configs.additional_origins,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.apps` + - ` LEFT JOIN zitadel.projections.apps_api_configs ON zitadel.projections.apps.id = zitadel.projections.apps_api_configs.app_id` + - ` LEFT JOIN zitadel.projections.apps_oidc_configs ON zitadel.projections.apps.id = zitadel.projections.apps_oidc_configs.app_id`) - expectedAppIDsQuery = regexp.QuoteMeta(`SELECT zitadel.projections.apps_api_configs.client_id,` + - ` zitadel.projections.apps_oidc_configs.client_id` + - ` FROM zitadel.projections.apps` + - ` LEFT JOIN zitadel.projections.apps_api_configs ON zitadel.projections.apps.id = zitadel.projections.apps_api_configs.app_id` + - ` LEFT JOIN zitadel.projections.apps_oidc_configs ON zitadel.projections.apps.id = zitadel.projections.apps_oidc_configs.app_id`) - expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT zitadel.projections.apps.project_id` + - ` FROM zitadel.projections.apps` + - ` LEFT JOIN zitadel.projections.apps_api_configs ON zitadel.projections.apps.id = zitadel.projections.apps_api_configs.app_id` + - ` LEFT JOIN zitadel.projections.apps_oidc_configs ON zitadel.projections.apps.id = zitadel.projections.apps_oidc_configs.app_id`) - expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,` + - ` zitadel.projections.projects.creation_date,` + - ` zitadel.projections.projects.change_date,` + - ` zitadel.projections.projects.resource_owner,` + - ` zitadel.projections.projects.state,` + - ` zitadel.projections.projects.sequence,` + - ` zitadel.projections.projects.name,` + - ` zitadel.projections.projects.project_role_assertion,` + - ` zitadel.projections.projects.project_role_check,` + - ` zitadel.projections.projects.has_project_check,` + - ` zitadel.projections.projects.private_labeling_setting` + - ` FROM zitadel.projections.projects` + - ` JOIN zitadel.projections.apps ON zitadel.projections.projects.id = zitadel.projections.apps.project_id` + - ` LEFT JOIN zitadel.projections.apps_api_configs ON zitadel.projections.apps.id = zitadel.projections.apps_api_configs.app_id` + - ` LEFT JOIN zitadel.projections.apps_oidc_configs ON zitadel.projections.apps.id = zitadel.projections.apps_oidc_configs.app_id`) + ` FROM projections.apps` + + ` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` + + ` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`) + expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps_api_configs.client_id,` + + ` projections.apps_oidc_configs.client_id` + + ` FROM projections.apps` + + ` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` + + ` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`) + expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps.project_id` + + ` FROM projections.apps` + + ` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` + + ` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`) + expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT projections.projects.id,` + + ` projections.projects.creation_date,` + + ` projections.projects.change_date,` + + ` projections.projects.resource_owner,` + + ` projections.projects.state,` + + ` projections.projects.sequence,` + + ` projections.projects.name,` + + ` projections.projects.project_role_assertion,` + + ` projections.projects.project_role_check,` + + ` projections.projects.has_project_check,` + + ` projections.projects.private_labeling_setting` + + ` FROM projections.projects` + + ` JOIN projections.apps ON projections.projects.id = projections.apps.project_id` + + ` LEFT JOIN projections.apps_api_configs ON projections.apps.id = projections.apps_api_configs.app_id` + + ` LEFT JOIN projections.apps_oidc_configs ON projections.apps.id = projections.apps_oidc_configs.app_id`) appCols = []string{ "id", diff --git a/internal/query/authn_key.go b/internal/query/authn_key.go index af6f3229ea..e5c5050671 100644 --- a/internal/query/authn_key.go +++ b/internal/query/authn_key.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -29,6 +31,10 @@ var ( name: projection.AuthNKeyResourceOwnerCol, table: authNKeyTable, } + AuthNKeyColumnInstanceID = Column{ + name: projection.AuthNKeyInstanceIDCol, + table: authNKeyTable, + } AuthNKeyColumnAggregateID = Column{ name: projection.AuthNKeyAggregateIDCol, table: authNKeyTable, @@ -96,7 +102,8 @@ func (q *Queries) SearchAuthNKeys(ctx context.Context, queries *AuthNKeySearchQu query = queries.toQuery(query) stmt, args, err := query.Where( sq.Eq{ - AuthNKeyColumnEnabled.identifier(): true, + AuthNKeyColumnEnabled.identifier(): true, + AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -122,8 +129,9 @@ func (q *Queries) GetAuthNKeyByID(ctx context.Context, id string, queries ...Sea } stmt, args, err := query.Where( sq.Eq{ - AuthNKeyColumnID.identifier(): id, - AuthNKeyColumnEnabled.identifier(): true, + AuthNKeyColumnID.identifier(): id, + AuthNKeyColumnEnabled.identifier(): true, + AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-AGhg4", "Errors.Query.SQLStatement") @@ -141,6 +149,7 @@ func (q *Queries) GetAuthNKeyPublicKeyByIDAndIdentifier(ctx context.Context, id AuthNKeyColumnID.identifier(): id, AuthNKeyColumnIdentifier.identifier(): identifier, AuthNKeyColumnEnabled.identifier(): true, + AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, sq.Gt{ AuthNKeyColumnExpiration.identifier(): time.Now(), diff --git a/internal/query/authn_key_test.go b/internal/query/authn_key_test.go index 31a59a881f..ca46fc5f65 100644 --- a/internal/query/authn_key_test.go +++ b/internal/query/authn_key_test.go @@ -28,14 +28,14 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type,`+ + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.authn_keys`), + ` FROM projections.authn_keys`), nil, nil, ), @@ -47,14 +47,14 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type,`+ + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.authn_keys`), + ` FROM projections.authn_keys`), []string{ "id", "creation_date", @@ -97,14 +97,14 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type,`+ + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.authn_keys`), + ` FROM projections.authn_keys`), []string{ "id", "creation_date", @@ -163,14 +163,14 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeysQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type,`+ + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.authn_keys`), + ` FROM projections.authn_keys`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -187,13 +187,13 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type`+ + ` FROM projections.authn_keys`), nil, nil, ), @@ -211,13 +211,13 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type`+ + ` FROM projections.authn_keys`), []string{ "id", "creation_date", @@ -250,13 +250,13 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.id,`+ - ` zitadel.projections.authn_keys.creation_date,`+ - ` zitadel.projections.authn_keys.resource_owner,`+ - ` zitadel.projections.authn_keys.sequence,`+ - ` zitadel.projections.authn_keys.expiration,`+ - ` zitadel.projections.authn_keys.type`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.id,`+ + ` projections.authn_keys.creation_date,`+ + ` projections.authn_keys.resource_owner,`+ + ` projections.authn_keys.sequence,`+ + ` projections.authn_keys.expiration,`+ + ` projections.authn_keys.type`+ + ` FROM projections.authn_keys`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -273,8 +273,8 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyPublicKeyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.public_key`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.public_key`+ + ` FROM projections.authn_keys`), nil, nil, ), @@ -292,8 +292,8 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyPublicKeyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.public_key`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.public_key`+ + ` FROM projections.authn_keys`), []string{ "public_key", }, @@ -309,8 +309,8 @@ func Test_AuthNKeyPrepares(t *testing.T) { prepare: prepareAuthNKeyPublicKeyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.authn_keys.public_key`+ - ` FROM zitadel.projections.authn_keys`), + regexp.QuoteMeta(`SELECT projections.authn_keys.public_key`+ + ` FROM projections.authn_keys`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/current_sequence.go b/internal/query/current_sequence.go index b79cdd59b9..ee585b7c19 100644 --- a/internal/query/current_sequence.go +++ b/internal/query/current_sequence.go @@ -105,11 +105,11 @@ func (q *Queries) ClearCurrentSequence(ctx context.Context, projectionName strin func (q *Queries) checkAndLock(ctx context.Context, projectionName string) error { projectionQuery, args, err := sq.Select("count(*)"). - From("[show tables from zitadel.projections]"). + From("[show tables from projections]"). Where( sq.And{ sq.NotEq{"table_name": []string{"locks", "current_sequences", "failed_events"}}, - sq.Eq{"concat('zitadel.projections.', table_name)": projectionName}, + sq.Eq{"concat('projections.', table_name)": projectionName}, }). PlaceholderFormat(sq.Dollar). ToSql() @@ -139,13 +139,13 @@ func (q *Queries) checkAndLock(ctx context.Context, projectionName string) error } func tablesForReset(ctx context.Context, tx *sql.Tx, projectionName string) ([]string, error) { - tablesQuery, args, err := sq.Select("concat('zitadel.projections.', table_name)"). - From("[show tables from zitadel.projections]"). + tablesQuery, args, err := sq.Select("concat('projections.', table_name)"). + From("[show tables from projections]"). Where( sq.And{ sq.Eq{"type": "table"}, sq.NotEq{"table_name": []string{"locks", "current_sequences", "failed_events"}}, - sq.Like{"concat('zitadel.projections.', table_name)": projectionName + "%"}, + sq.Like{"concat('projections.', table_name)": projectionName + "%"}, }). PlaceholderFormat(sq.Dollar). ToSql() diff --git a/internal/query/custom_text.go b/internal/query/custom_text.go index e809afd236..676ea8a084 100644 --- a/internal/query/custom_text.go +++ b/internal/query/custom_text.go @@ -12,6 +12,8 @@ import ( "golang.org/x/text/language" "sigs.k8s.io/yaml" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v1/models" @@ -43,6 +45,10 @@ var ( name: projection.CustomTextAggregateIDCol, table: customTextTable, } + CustomTextColInstanceID = Column{ + name: projection.CustomTextInstanceIDCol, + table: customTextTable, + } CustomTextColSequence = Column{ name: projection.CustomTextSequenceCol, table: customTextTable, @@ -80,6 +86,7 @@ func (q *Queries) CustomTextList(ctx context.Context, aggregateID, template, lan CustomTextColAggregateID.identifier(): aggregateID, CustomTextColTemplate.identifier(): template, CustomTextColLanguage.identifier(): language, + CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -104,6 +111,7 @@ func (q *Queries) CustomTextListByTemplate(ctx context.Context, aggregateID, tem sq.Eq{ CustomTextColAggregateID.identifier(): aggregateID, CustomTextColTemplate.identifier(): template, + CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { diff --git a/internal/query/custom_text_test.go b/internal/query/custom_text_test.go index a66e4f0839..7ec2a36efc 100644 --- a/internal/query/custom_text_test.go +++ b/internal/query/custom_text_test.go @@ -8,8 +8,9 @@ import ( "regexp" "testing" - errs "github.com/caos/zitadel/internal/errors" "golang.org/x/text/language" + + errs "github.com/caos/zitadel/internal/errors" ) func Test_CustomTextPrepares(t *testing.T) { @@ -28,16 +29,16 @@ func Test_CustomTextPrepares(t *testing.T) { prepare: prepareCustomTextsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+ - ` zitadel.projections.custom_texts.sequence,`+ - ` zitadel.projections.custom_texts.creation_date,`+ - ` zitadel.projections.custom_texts.change_date,`+ - ` zitadel.projections.custom_texts.language,`+ - ` zitadel.projections.custom_texts.template,`+ - ` zitadel.projections.custom_texts.key,`+ - ` zitadel.projections.custom_texts.text,`+ + regexp.QuoteMeta(`SELECT projections.custom_texts.aggregate_id,`+ + ` projections.custom_texts.sequence,`+ + ` projections.custom_texts.creation_date,`+ + ` projections.custom_texts.change_date,`+ + ` projections.custom_texts.language,`+ + ` projections.custom_texts.template,`+ + ` projections.custom_texts.key,`+ + ` projections.custom_texts.text,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.custom_texts`), + ` FROM projections.custom_texts`), nil, nil, ), @@ -55,16 +56,16 @@ func Test_CustomTextPrepares(t *testing.T) { prepare: prepareCustomTextsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+ - ` zitadel.projections.custom_texts.sequence,`+ - ` zitadel.projections.custom_texts.creation_date,`+ - ` zitadel.projections.custom_texts.change_date,`+ - ` zitadel.projections.custom_texts.language,`+ - ` zitadel.projections.custom_texts.template,`+ - ` zitadel.projections.custom_texts.key,`+ - ` zitadel.projections.custom_texts.text,`+ + regexp.QuoteMeta(`SELECT projections.custom_texts.aggregate_id,`+ + ` projections.custom_texts.sequence,`+ + ` projections.custom_texts.creation_date,`+ + ` projections.custom_texts.change_date,`+ + ` projections.custom_texts.language,`+ + ` projections.custom_texts.template,`+ + ` projections.custom_texts.key,`+ + ` projections.custom_texts.text,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.custom_texts`), + ` FROM projections.custom_texts`), []string{ "aggregate_id", "sequence", @@ -113,16 +114,16 @@ func Test_CustomTextPrepares(t *testing.T) { prepare: prepareCustomTextsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+ - ` zitadel.projections.custom_texts.sequence,`+ - ` zitadel.projections.custom_texts.creation_date,`+ - ` zitadel.projections.custom_texts.change_date,`+ - ` zitadel.projections.custom_texts.language,`+ - ` zitadel.projections.custom_texts.template,`+ - ` zitadel.projections.custom_texts.key,`+ - ` zitadel.projections.custom_texts.text,`+ + regexp.QuoteMeta(`SELECT projections.custom_texts.aggregate_id,`+ + ` projections.custom_texts.sequence,`+ + ` projections.custom_texts.creation_date,`+ + ` projections.custom_texts.change_date,`+ + ` projections.custom_texts.language,`+ + ` projections.custom_texts.template,`+ + ` projections.custom_texts.key,`+ + ` projections.custom_texts.text,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.custom_texts`), + ` FROM projections.custom_texts`), []string{ "aggregate_id", "sequence", @@ -191,16 +192,16 @@ func Test_CustomTextPrepares(t *testing.T) { prepare: prepareCustomTextsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.custom_texts.aggregate_id,`+ - ` zitadel.projections.custom_texts.sequence,`+ - ` zitadel.projections.custom_texts.creation_date,`+ - ` zitadel.projections.custom_texts.change_date,`+ - ` zitadel.projections.custom_texts.language,`+ - ` zitadel.projections.custom_texts.template,`+ - ` zitadel.projections.custom_texts.key,`+ - ` zitadel.projections.custom_texts.text,`+ + regexp.QuoteMeta(`SELECT projections.custom_texts.aggregate_id,`+ + ` projections.custom_texts.sequence,`+ + ` projections.custom_texts.creation_date,`+ + ` projections.custom_texts.change_date,`+ + ` projections.custom_texts.language,`+ + ` projections.custom_texts.template,`+ + ` projections.custom_texts.key,`+ + ` projections.custom_texts.text,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.custom_texts`), + ` FROM projections.custom_texts`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/failed_events.go b/internal/query/failed_events.go index c78ec81f63..056a845879 100644 --- a/internal/query/failed_events.go +++ b/internal/query/failed_events.go @@ -16,6 +16,7 @@ const ( failedEventsColumnFailedSequence = "failed_sequence" failedEventsColumnFailureCount = "failure_count" failedEventsColumnError = "error" + failedEventsColumnInstanceID = "instance_id" ) var ( @@ -38,6 +39,10 @@ var ( name: failedEventsColumnError, table: failedEventsTable, } + FailedEventsColumnInstanceID = Column{ + name: failedEventsColumnInstanceID, + table: failedEventsTable, + } ) type FailedEvents struct { diff --git a/internal/query/features.go b/internal/query/features.go index 6d74cd98cf..6cc4cd2002 100644 --- a/internal/query/features.go +++ b/internal/query/features.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -50,6 +52,10 @@ var ( name: projection.FeatureAggregateIDCol, table: featureTable, } + FeatureColumnInstanceID = Column{ + name: projection.FeatureInstanceIDCol, + table: featureTable, + } FeatureColumnChangeDate = Column{ name: projection.FeatureChangeDateCol, table: featureTable, @@ -155,12 +161,17 @@ var ( func (q *Queries) FeaturesByOrgID(ctx context.Context, orgID string) (*Features, error) { query, scan := prepareFeaturesQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - FeatureColumnAggregateID.identifier(): orgID, + FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - FeatureColumnAggregateID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + FeatureColumnAggregateID.identifier(): orgID, + }, + sq.Eq{ + FeatureColumnAggregateID.identifier(): domain.IAMID, + }, }, }). OrderBy(FeatureColumnIsDefault.identifier()). @@ -177,6 +188,7 @@ func (q *Queries) DefaultFeatures(ctx context.Context) (*Features, error) { query, scan := prepareFeaturesQuery() stmt, args, err := query.Where(sq.Eq{ FeatureColumnAggregateID.identifier(): domain.IAMID, + FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-1Ndlg", "Errors.Query.SQLStatement") diff --git a/internal/query/features_test.go b/internal/query/features_test.go index 4709f6f501..fabd2d20ca 100644 --- a/internal/query/features_test.go +++ b/internal/query/features_test.go @@ -29,33 +29,33 @@ func Test_FeaturesPrepares(t *testing.T) { prepare: prepareFeaturesQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.features.aggregate_id,`+ - ` zitadel.projections.features.change_date,`+ - ` zitadel.projections.features.sequence,`+ - ` zitadel.projections.features.is_default,`+ - ` zitadel.projections.features.tier_name,`+ - ` zitadel.projections.features.tier_description,`+ - ` zitadel.projections.features.state,`+ - ` zitadel.projections.features.state_description,`+ - ` zitadel.projections.features.audit_log_retention,`+ - ` zitadel.projections.features.login_policy_factors,`+ - ` zitadel.projections.features.login_policy_idp,`+ - ` zitadel.projections.features.login_policy_passwordless,`+ - ` zitadel.projections.features.login_policy_registration,`+ - ` zitadel.projections.features.login_policy_username_login,`+ - ` zitadel.projections.features.login_policy_password_reset,`+ - ` zitadel.projections.features.password_complexity_policy,`+ - ` zitadel.projections.features.label_policy_private_label,`+ - ` zitadel.projections.features.label_policy_watermark,`+ - ` zitadel.projections.features.custom_domain,`+ - ` zitadel.projections.features.privacy_policy,`+ - ` zitadel.projections.features.metadata_user,`+ - ` zitadel.projections.features.custom_text_message,`+ - ` zitadel.projections.features.custom_text_login,`+ - ` zitadel.projections.features.lockout_policy,`+ - ` zitadel.projections.features.actions_allowed,`+ - ` zitadel.projections.features.max_actions`+ - ` FROM zitadel.projections.features`), + regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+ + ` projections.features.change_date,`+ + ` projections.features.sequence,`+ + ` projections.features.is_default,`+ + ` projections.features.tier_name,`+ + ` projections.features.tier_description,`+ + ` projections.features.state,`+ + ` projections.features.state_description,`+ + ` projections.features.audit_log_retention,`+ + ` projections.features.login_policy_factors,`+ + ` projections.features.login_policy_idp,`+ + ` projections.features.login_policy_passwordless,`+ + ` projections.features.login_policy_registration,`+ + ` projections.features.login_policy_username_login,`+ + ` projections.features.login_policy_password_reset,`+ + ` projections.features.password_complexity_policy,`+ + ` projections.features.label_policy_private_label,`+ + ` projections.features.label_policy_watermark,`+ + ` projections.features.custom_domain,`+ + ` projections.features.privacy_policy,`+ + ` projections.features.metadata_user,`+ + ` projections.features.custom_text_message,`+ + ` projections.features.custom_text_login,`+ + ` projections.features.lockout_policy,`+ + ` projections.features.actions_allowed,`+ + ` projections.features.max_actions`+ + ` FROM projections.features`), nil, nil, ), @@ -73,33 +73,33 @@ func Test_FeaturesPrepares(t *testing.T) { prepare: prepareFeaturesQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.features.aggregate_id,`+ - ` zitadel.projections.features.change_date,`+ - ` zitadel.projections.features.sequence,`+ - ` zitadel.projections.features.is_default,`+ - ` zitadel.projections.features.tier_name,`+ - ` zitadel.projections.features.tier_description,`+ - ` zitadel.projections.features.state,`+ - ` zitadel.projections.features.state_description,`+ - ` zitadel.projections.features.audit_log_retention,`+ - ` zitadel.projections.features.login_policy_factors,`+ - ` zitadel.projections.features.login_policy_idp,`+ - ` zitadel.projections.features.login_policy_passwordless,`+ - ` zitadel.projections.features.login_policy_registration,`+ - ` zitadel.projections.features.login_policy_username_login,`+ - ` zitadel.projections.features.login_policy_password_reset,`+ - ` zitadel.projections.features.password_complexity_policy,`+ - ` zitadel.projections.features.label_policy_private_label,`+ - ` zitadel.projections.features.label_policy_watermark,`+ - ` zitadel.projections.features.custom_domain,`+ - ` zitadel.projections.features.privacy_policy,`+ - ` zitadel.projections.features.metadata_user,`+ - ` zitadel.projections.features.custom_text_message,`+ - ` zitadel.projections.features.custom_text_login,`+ - ` zitadel.projections.features.lockout_policy,`+ - ` zitadel.projections.features.actions_allowed,`+ - ` zitadel.projections.features.max_actions`+ - ` FROM zitadel.projections.features`), + regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+ + ` projections.features.change_date,`+ + ` projections.features.sequence,`+ + ` projections.features.is_default,`+ + ` projections.features.tier_name,`+ + ` projections.features.tier_description,`+ + ` projections.features.state,`+ + ` projections.features.state_description,`+ + ` projections.features.audit_log_retention,`+ + ` projections.features.login_policy_factors,`+ + ` projections.features.login_policy_idp,`+ + ` projections.features.login_policy_passwordless,`+ + ` projections.features.login_policy_registration,`+ + ` projections.features.login_policy_username_login,`+ + ` projections.features.login_policy_password_reset,`+ + ` projections.features.password_complexity_policy,`+ + ` projections.features.label_policy_private_label,`+ + ` projections.features.label_policy_watermark,`+ + ` projections.features.custom_domain,`+ + ` projections.features.privacy_policy,`+ + ` projections.features.metadata_user,`+ + ` projections.features.custom_text_message,`+ + ` projections.features.custom_text_login,`+ + ` projections.features.lockout_policy,`+ + ` projections.features.actions_allowed,`+ + ` projections.features.max_actions`+ + ` FROM projections.features`), []string{ "aggregate_id", "change_date", @@ -192,33 +192,33 @@ func Test_FeaturesPrepares(t *testing.T) { prepare: prepareFeaturesQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.features.aggregate_id,`+ - ` zitadel.projections.features.change_date,`+ - ` zitadel.projections.features.sequence,`+ - ` zitadel.projections.features.is_default,`+ - ` zitadel.projections.features.tier_name,`+ - ` zitadel.projections.features.tier_description,`+ - ` zitadel.projections.features.state,`+ - ` zitadel.projections.features.state_description,`+ - ` zitadel.projections.features.audit_log_retention,`+ - ` zitadel.projections.features.login_policy_factors,`+ - ` zitadel.projections.features.login_policy_idp,`+ - ` zitadel.projections.features.login_policy_passwordless,`+ - ` zitadel.projections.features.login_policy_registration,`+ - ` zitadel.projections.features.login_policy_username_login,`+ - ` zitadel.projections.features.login_policy_password_reset,`+ - ` zitadel.projections.features.password_complexity_policy,`+ - ` zitadel.projections.features.label_policy_private_label,`+ - ` zitadel.projections.features.label_policy_watermark,`+ - ` zitadel.projections.features.custom_domain,`+ - ` zitadel.projections.features.privacy_policy,`+ - ` zitadel.projections.features.metadata_user,`+ - ` zitadel.projections.features.custom_text_message,`+ - ` zitadel.projections.features.custom_text_login,`+ - ` zitadel.projections.features.lockout_policy,`+ - ` zitadel.projections.features.actions_allowed,`+ - ` zitadel.projections.features.max_actions`+ - ` FROM zitadel.projections.features`), + regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+ + ` projections.features.change_date,`+ + ` projections.features.sequence,`+ + ` projections.features.is_default,`+ + ` projections.features.tier_name,`+ + ` projections.features.tier_description,`+ + ` projections.features.state,`+ + ` projections.features.state_description,`+ + ` projections.features.audit_log_retention,`+ + ` projections.features.login_policy_factors,`+ + ` projections.features.login_policy_idp,`+ + ` projections.features.login_policy_passwordless,`+ + ` projections.features.login_policy_registration,`+ + ` projections.features.login_policy_username_login,`+ + ` projections.features.login_policy_password_reset,`+ + ` projections.features.password_complexity_policy,`+ + ` projections.features.label_policy_private_label,`+ + ` projections.features.label_policy_watermark,`+ + ` projections.features.custom_domain,`+ + ` projections.features.privacy_policy,`+ + ` projections.features.metadata_user,`+ + ` projections.features.custom_text_message,`+ + ` projections.features.custom_text_login,`+ + ` projections.features.lockout_policy,`+ + ` projections.features.actions_allowed,`+ + ` projections.features.max_actions`+ + ` FROM projections.features`), []string{ "aggregate_id", "change_date", @@ -311,33 +311,33 @@ func Test_FeaturesPrepares(t *testing.T) { prepare: prepareFeaturesQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.features.aggregate_id,`+ - ` zitadel.projections.features.change_date,`+ - ` zitadel.projections.features.sequence,`+ - ` zitadel.projections.features.is_default,`+ - ` zitadel.projections.features.tier_name,`+ - ` zitadel.projections.features.tier_description,`+ - ` zitadel.projections.features.state,`+ - ` zitadel.projections.features.state_description,`+ - ` zitadel.projections.features.audit_log_retention,`+ - ` zitadel.projections.features.login_policy_factors,`+ - ` zitadel.projections.features.login_policy_idp,`+ - ` zitadel.projections.features.login_policy_passwordless,`+ - ` zitadel.projections.features.login_policy_registration,`+ - ` zitadel.projections.features.login_policy_username_login,`+ - ` zitadel.projections.features.login_policy_password_reset,`+ - ` zitadel.projections.features.password_complexity_policy,`+ - ` zitadel.projections.features.label_policy_private_label,`+ - ` zitadel.projections.features.label_policy_watermark,`+ - ` zitadel.projections.features.custom_domain,`+ - ` zitadel.projections.features.privacy_policy,`+ - ` zitadel.projections.features.metadata_user,`+ - ` zitadel.projections.features.custom_text_message,`+ - ` zitadel.projections.features.custom_text_login,`+ - ` zitadel.projections.features.lockout_policy,`+ - ` zitadel.projections.features.actions_allowed,`+ - ` zitadel.projections.features.max_actions`+ - ` FROM zitadel.projections.features`), + regexp.QuoteMeta(`SELECT projections.features.aggregate_id,`+ + ` projections.features.change_date,`+ + ` projections.features.sequence,`+ + ` projections.features.is_default,`+ + ` projections.features.tier_name,`+ + ` projections.features.tier_description,`+ + ` projections.features.state,`+ + ` projections.features.state_description,`+ + ` projections.features.audit_log_retention,`+ + ` projections.features.login_policy_factors,`+ + ` projections.features.login_policy_idp,`+ + ` projections.features.login_policy_passwordless,`+ + ` projections.features.login_policy_registration,`+ + ` projections.features.login_policy_username_login,`+ + ` projections.features.login_policy_password_reset,`+ + ` projections.features.password_complexity_policy,`+ + ` projections.features.label_policy_private_label,`+ + ` projections.features.label_policy_watermark,`+ + ` projections.features.custom_domain,`+ + ` projections.features.privacy_policy,`+ + ` projections.features.metadata_user,`+ + ` projections.features.custom_text_message,`+ + ` projections.features.custom_text_login,`+ + ` projections.features.lockout_policy,`+ + ` projections.features.actions_allowed,`+ + ` projections.features.max_actions`+ + ` FROM projections.features`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/iam.go b/internal/query/iam.go index 9554d0a4c5..3a79ca0b93 100644 --- a/internal/query/iam.go +++ b/internal/query/iam.go @@ -7,10 +7,12 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "golang.org/x/text/language" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" - "golang.org/x/text/language" ) var ( @@ -76,10 +78,10 @@ func (q *IAMSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder { return query } -func (q *Queries) IAMByID(ctx context.Context, id string) (*IAM, error) { +func (q *Queries) IAM(ctx context.Context) (*IAM, error) { stmt, scan := prepareIAMQuery() query, args, err := stmt.Where(sq.Eq{ - IAMColumnID.identifier(): id, + IAMColumnID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-d9ngs", "Errors.Query.SQLStatement") @@ -90,7 +92,7 @@ func (q *Queries) IAMByID(ctx context.Context, id string) (*IAM, error) { } func (q *Queries) GetDefaultLanguage(ctx context.Context) language.Tag { - iam, err := q.IAMByID(ctx, domain.IAMID) + iam, err := q.IAM(ctx) if err != nil { return language.Und } diff --git a/internal/query/iam_member.go b/internal/query/iam_member.go index 251081868d..e41e507021 100644 --- a/internal/query/iam_member.go +++ b/internal/query/iam_member.go @@ -7,6 +7,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -40,6 +42,10 @@ var ( name: projection.MemberResourceOwner, table: iamMemberTable, } + IAMMemberInstanceID = Column{ + name: projection.MemberInstanceID, + table: iamMemberTable, + } IAMMemberIAMID = Column{ name: projection.IAMMemberIAMIDCol, table: iamMemberTable, @@ -57,7 +63,10 @@ func (q *IAMMembersQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder { func (q *Queries) IAMMembers(ctx context.Context, queries *IAMMembersQuery) (*Members, error) { query, scan := prepareIAMMembersQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + IAMMemberInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-USNwM", "Errors.Query.InvalidRequest") } diff --git a/internal/query/iam_member_test.go b/internal/query/iam_member_test.go index 6857d8c481..1c6bab908a 100644 --- a/internal/query/iam_member_test.go +++ b/internal/query/iam_member_test.go @@ -19,22 +19,22 @@ var ( ", members.resource_owner" + ", members.user_id" + ", members.roles" + - ", zitadel.projections.login_names.login_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_machines.name" + - ", zitadel.projections.users_humans.avatar_key" + + ", projections.login_names.login_name" + + ", projections.users_humans.email" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.display_name" + + ", projections.users_machines.name" + + ", projections.users_humans.avatar_key" + ", COUNT(*) OVER () " + - "FROM zitadel.projections.iam_members as members " + - "LEFT JOIN zitadel.projections.users_humans " + - "ON members.user_id = zitadel.projections.users_humans.user_id " + - "LEFT JOIN zitadel.projections.users_machines " + - "ON members.user_id = zitadel.projections.users_machines.user_id " + - "LEFT JOIN zitadel.projections.login_names " + - "ON members.user_id = zitadel.projections.login_names.user_id " + - "WHERE zitadel.projections.login_names.is_primary = $1") + "FROM projections.iam_members as members " + + "LEFT JOIN projections.users_humans " + + "ON members.user_id = projections.users_humans.user_id " + + "LEFT JOIN projections.users_machines " + + "ON members.user_id = projections.users_machines.user_id " + + "LEFT JOIN projections.login_names " + + "ON members.user_id = projections.login_names.user_id " + + "WHERE projections.login_names.is_primary = $1") iamMembersColumns = []string{ "creation_date", "change_date", diff --git a/internal/query/iam_test.go b/internal/query/iam_test.go index 7bfc1630af..596d0df932 100644 --- a/internal/query/iam_test.go +++ b/internal/query/iam_test.go @@ -8,9 +8,10 @@ import ( "regexp" "testing" + "golang.org/x/text/language" + "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" - "golang.org/x/text/language" ) func Test_IAMPrepares(t *testing.T) { @@ -29,15 +30,15 @@ func Test_IAMPrepares(t *testing.T) { prepare: prepareIAMQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ - ` zitadel.projections.iam.change_date,`+ - ` zitadel.projections.iam.sequence,`+ - ` zitadel.projections.iam.global_org_id,`+ - ` zitadel.projections.iam.iam_project_id,`+ - ` zitadel.projections.iam.setup_started,`+ - ` zitadel.projections.iam.setup_done,`+ - ` zitadel.projections.iam.default_language`+ - ` FROM zitadel.projections.iam`), + regexp.QuoteMeta(`SELECT projections.iam.id,`+ + ` projections.iam.change_date,`+ + ` projections.iam.sequence,`+ + ` projections.iam.global_org_id,`+ + ` projections.iam.iam_project_id,`+ + ` projections.iam.setup_started,`+ + ` projections.iam.setup_done,`+ + ` projections.iam.default_language`+ + ` FROM projections.iam`), nil, nil, ), @@ -55,15 +56,15 @@ func Test_IAMPrepares(t *testing.T) { prepare: prepareIAMQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ - ` zitadel.projections.iam.change_date,`+ - ` zitadel.projections.iam.sequence,`+ - ` zitadel.projections.iam.global_org_id,`+ - ` zitadel.projections.iam.iam_project_id,`+ - ` zitadel.projections.iam.setup_started,`+ - ` zitadel.projections.iam.setup_done,`+ - ` zitadel.projections.iam.default_language`+ - ` FROM zitadel.projections.iam`), + regexp.QuoteMeta(`SELECT projections.iam.id,`+ + ` projections.iam.change_date,`+ + ` projections.iam.sequence,`+ + ` projections.iam.global_org_id,`+ + ` projections.iam.iam_project_id,`+ + ` projections.iam.setup_started,`+ + ` projections.iam.setup_done,`+ + ` projections.iam.default_language`+ + ` FROM projections.iam`), []string{ "id", "change_date", @@ -102,15 +103,15 @@ func Test_IAMPrepares(t *testing.T) { prepare: prepareIAMQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ - ` zitadel.projections.iam.change_date,`+ - ` zitadel.projections.iam.sequence,`+ - ` zitadel.projections.iam.global_org_id,`+ - ` zitadel.projections.iam.iam_project_id,`+ - ` zitadel.projections.iam.setup_started,`+ - ` zitadel.projections.iam.setup_done,`+ - ` zitadel.projections.iam.default_language`+ - ` FROM zitadel.projections.iam`), + regexp.QuoteMeta(`SELECT projections.iam.id,`+ + ` projections.iam.change_date,`+ + ` projections.iam.sequence,`+ + ` projections.iam.global_org_id,`+ + ` projections.iam.iam_project_id,`+ + ` projections.iam.setup_started,`+ + ` projections.iam.setup_done,`+ + ` projections.iam.default_language`+ + ` FROM projections.iam`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/idp.go b/internal/query/idp.go index 0ef6e4f17f..f62e577d3e 100644 --- a/internal/query/idp.go +++ b/internal/query/idp.go @@ -9,6 +9,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -79,6 +81,10 @@ var ( name: projection.IDPResourceOwnerCol, table: idpTable, } + IDPInstanceIDCol = Column{ + name: projection.IDPInstanceIDCol, + table: idpTable, + } IDPStateCol = Column{ name: projection.IDPStateCol, table: idpTable, @@ -179,7 +185,8 @@ func (q *Queries) IDPByIDAndResourceOwner(ctx context.Context, id, resourceOwner query, args, err := stmt.Where( sq.And{ sq.Eq{ - IDPIDCol.identifier(): id, + IDPIDCol.identifier(): id, + IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, }, sq.Or{ sq.Eq{ @@ -202,7 +209,10 @@ func (q *Queries) IDPByIDAndResourceOwner(ctx context.Context, id, resourceOwner //IDPs searches idps matching the query func (q *Queries) IDPs(ctx context.Context, queries *IDPSearchQueries) (idps *IDPs, err error) { query, scan := prepareIDPsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-X6X7y", "Errors.Query.InvalidRequest") } diff --git a/internal/query/idp_login_policy_link.go b/internal/query/idp_login_policy_link.go index 2172bbf4ea..c6d243044d 100644 --- a/internal/query/idp_login_policy_link.go +++ b/internal/query/idp_login_policy_link.go @@ -5,6 +5,8 @@ import ( "database/sql" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -58,6 +60,10 @@ var ( name: projection.IDPLoginPolicyLinkResourceOwnerCol, table: idpLoginPolicyLinkTable, } + IDPLoginPolicyLinkInstanceIDCol = Column{ + name: projection.IDPLoginPolicyLinkInstanceIDCol, + table: idpLoginPolicyLinkTable, + } IDPLoginPolicyLinkProviderTypeCol = Column{ name: projection.IDPLoginPolicyLinkProviderTypeCol, table: idpLoginPolicyLinkTable, @@ -67,7 +73,10 @@ var ( func (q *Queries) IDPLoginPolicyLinks(ctx context.Context, resourceOwner string, queries *IDPLoginPolicyLinksSearchQuery) (idps *IDPLoginPolicyLinks, err error) { query, scan := prepareIDPLoginPolicyLinksQuery() stmt, args, err := queries.toQuery(query).Where( - sq.Eq{IDPLoginPolicyLinkResourceOwnerCol.identifier(): resourceOwner}, + sq.Eq{ + IDPLoginPolicyLinkResourceOwnerCol.identifier(): resourceOwner, + IDPLoginPolicyLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }, ).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-FDbKW", "Errors.Query.InvalidRequest") diff --git a/internal/query/idp_login_policy_link_test.go b/internal/query/idp_login_policy_link_test.go index 0a053c1dcc..1f635d839a 100644 --- a/internal/query/idp_login_policy_link_test.go +++ b/internal/query/idp_login_policy_link_test.go @@ -12,12 +12,12 @@ import ( ) var ( - loginPolicyIDPLinksQuery = regexp.QuoteMeta(`SELECT zitadel.projections.idp_login_policy_links.idp_id,` + - ` zitadel.projections.idps.name,` + - ` zitadel.projections.idps.type,` + + loginPolicyIDPLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_login_policy_links.idp_id,` + + ` projections.idps.name,` + + ` projections.idps.type,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.idp_login_policy_links` + - ` LEFT JOIN zitadel.projections.idps ON zitadel.projections.idp_login_policy_links.idp_id = zitadel.projections.idps.id`) + ` FROM projections.idp_login_policy_links` + + ` LEFT JOIN projections.idps ON projections.idp_login_policy_links.idp_id = projections.idps.id`) loginPolicyIDPLinksCols = []string{ "idp_id", "name", diff --git a/internal/query/idp_test.go b/internal/query/idp_test.go index 5cac22bc48..27573e0936 100644 --- a/internal/query/idp_test.go +++ b/internal/query/idp_test.go @@ -8,10 +8,11 @@ import ( "regexp" "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" - "github.com/lib/pq" ) func Test_IDPPrepares(t *testing.T) { @@ -30,33 +31,33 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPByIDQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint`+ + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), nil, nil, ), @@ -74,33 +75,33 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPByIDQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint`+ + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -188,33 +189,33 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPByIDQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint`+ + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -298,33 +299,33 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPByIDQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint`+ + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -401,33 +402,33 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPByIDQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint`+ + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -444,34 +445,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), nil, nil, ), @@ -489,34 +490,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -614,34 +615,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -734,34 +735,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -847,34 +848,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), []string{ "id", "resource_owner", @@ -1058,34 +1059,34 @@ func Test_IDPPrepares(t *testing.T) { prepare: prepareIDPsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.idps.id,`+ - ` zitadel.projections.idps.resource_owner,`+ - ` zitadel.projections.idps.creation_date,`+ - ` zitadel.projections.idps.change_date,`+ - ` zitadel.projections.idps.sequence,`+ - ` zitadel.projections.idps.state,`+ - ` zitadel.projections.idps.name,`+ - ` zitadel.projections.idps.styling_type,`+ - ` zitadel.projections.idps.owner_type,`+ - ` zitadel.projections.idps.auto_register,`+ - ` zitadel.projections.idps_oidc_config.idp_id,`+ - ` zitadel.projections.idps_oidc_config.client_id,`+ - ` zitadel.projections.idps_oidc_config.client_secret,`+ - ` zitadel.projections.idps_oidc_config.issuer,`+ - ` zitadel.projections.idps_oidc_config.scopes,`+ - ` zitadel.projections.idps_oidc_config.display_name_mapping,`+ - ` zitadel.projections.idps_oidc_config.username_mapping,`+ - ` zitadel.projections.idps_oidc_config.authorization_endpoint,`+ - ` zitadel.projections.idps_oidc_config.token_endpoint,`+ - ` zitadel.projections.idps_jwt_config.idp_id,`+ - ` zitadel.projections.idps_jwt_config.issuer,`+ - ` zitadel.projections.idps_jwt_config.keys_endpoint,`+ - ` zitadel.projections.idps_jwt_config.header_name,`+ - ` zitadel.projections.idps_jwt_config.endpoint,`+ + regexp.QuoteMeta(`SELECT projections.idps.id,`+ + ` projections.idps.resource_owner,`+ + ` projections.idps.creation_date,`+ + ` projections.idps.change_date,`+ + ` projections.idps.sequence,`+ + ` projections.idps.state,`+ + ` projections.idps.name,`+ + ` projections.idps.styling_type,`+ + ` projections.idps.owner_type,`+ + ` projections.idps.auto_register,`+ + ` projections.idps_oidc_config.idp_id,`+ + ` projections.idps_oidc_config.client_id,`+ + ` projections.idps_oidc_config.client_secret,`+ + ` projections.idps_oidc_config.issuer,`+ + ` projections.idps_oidc_config.scopes,`+ + ` projections.idps_oidc_config.display_name_mapping,`+ + ` projections.idps_oidc_config.username_mapping,`+ + ` projections.idps_oidc_config.authorization_endpoint,`+ + ` projections.idps_oidc_config.token_endpoint,`+ + ` projections.idps_jwt_config.idp_id,`+ + ` projections.idps_jwt_config.issuer,`+ + ` projections.idps_jwt_config.keys_endpoint,`+ + ` projections.idps_jwt_config.header_name,`+ + ` projections.idps_jwt_config.endpoint,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.idps`+ - ` LEFT JOIN zitadel.projections.idps_oidc_config ON zitadel.projections.idps.id = zitadel.projections.idps_oidc_config.idp_id`+ - ` LEFT JOIN zitadel.projections.idps_jwt_config ON zitadel.projections.idps.id = zitadel.projections.idps_jwt_config.idp_id`), + ` FROM projections.idps`+ + ` LEFT JOIN projections.idps_oidc_config ON projections.idps.id = projections.idps_oidc_config.idp_id`+ + ` LEFT JOIN projections.idps_jwt_config ON projections.idps.id = projections.idps_jwt_config.idp_id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/idp_user_link.go b/internal/query/idp_user_link.go index e528e4bc9b..59d69940ca 100644 --- a/internal/query/idp_user_link.go +++ b/internal/query/idp_user_link.go @@ -5,6 +5,8 @@ import ( "database/sql" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -70,6 +72,10 @@ var ( name: projection.IDPUserLinkResourceOwnerCol, table: idpUserLinkTable, } + IDPUserLinkInstanceIDCol = Column{ + name: projection.IDPUserLinkInstanceIDCol, + table: idpUserLinkTable, + } IDPUserLinkDisplayNameCol = Column{ name: projection.IDPUserLinkDisplayNameCol, table: idpUserLinkTable, @@ -78,7 +84,10 @@ var ( func (q *Queries) IDPUserLinks(ctx context.Context, queries *IDPUserLinksSearchQuery) (idps *IDPUserLinks, err error) { query, scan := prepareIDPUserLinksQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + IDPUserLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-4zzFK", "Errors.Query.InvalidRequest") } diff --git a/internal/query/idp_user_link_test.go b/internal/query/idp_user_link_test.go index 2993c6a057..42117bcc9b 100644 --- a/internal/query/idp_user_link_test.go +++ b/internal/query/idp_user_link_test.go @@ -12,16 +12,16 @@ import ( ) var ( - idpUserLinksQuery = regexp.QuoteMeta(`SELECT zitadel.projections.idp_user_links.idp_id,` + - ` zitadel.projections.idp_user_links.user_id,` + - ` zitadel.projections.idps.name,` + - ` zitadel.projections.idp_user_links.external_user_id,` + - ` zitadel.projections.idp_user_links.display_name,` + - ` zitadel.projections.idps.type,` + - ` zitadel.projections.idp_user_links.resource_owner,` + + idpUserLinksQuery = regexp.QuoteMeta(`SELECT projections.idp_user_links.idp_id,` + + ` projections.idp_user_links.user_id,` + + ` projections.idps.name,` + + ` projections.idp_user_links.external_user_id,` + + ` projections.idp_user_links.display_name,` + + ` projections.idps.type,` + + ` projections.idp_user_links.resource_owner,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.idp_user_links` + - ` LEFT JOIN zitadel.projections.idps ON zitadel.projections.idp_user_links.idp_id = zitadel.projections.idps.id`) + ` FROM projections.idp_user_links` + + ` LEFT JOIN projections.idps ON projections.idp_user_links.idp_id = projections.idps.id`) idpUserLinksCols = []string{ "idp_id", "user_id", diff --git a/internal/query/key.go b/internal/query/key.go index 9ca0b9f6c3..762fe887d9 100644 --- a/internal/query/key.go +++ b/internal/query/key.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -117,6 +119,10 @@ var ( name: projection.KeyColumnResourceOwner, table: keyTable, } + KeyColInstanceID = Column{ + name: projection.KeyColumnInstanceID, + table: keyTable, + } KeyColSequence = Column{ name: projection.KeyColumnSequence, table: keyTable, @@ -173,8 +179,13 @@ func (q *Queries) ActivePublicKeys(ctx context.Context, t time.Time) (*PublicKey t = time.Now() } stmt, args, err := query.Where( - sq.Gt{ - KeyPublicColExpiry.identifier(): t, + sq.And{ + sq.Eq{ + KeyColInstanceID.identifier(): authz.GetInstance(ctx).ID, + }, + sq.Gt{ + KeyPublicColExpiry.identifier(): t, + }, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-SDFfg", "Errors.Query.SQLStatement") @@ -200,7 +211,8 @@ func (q *Queries) ActivePrivateSigningKey(ctx context.Context, t time.Time) (*Pr query, args, err := stmt.Where( sq.And{ sq.Eq{ - KeyColUse.identifier(): domain.KeyUsageSigning, + KeyColUse.identifier(): domain.KeyUsageSigning, + KeyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, sq.Gt{ KeyPrivateColExpiry.identifier(): t, diff --git a/internal/query/key_test.go b/internal/query/key_test.go index 6d3c142bb3..19ff43e7a7 100644 --- a/internal/query/key_test.go +++ b/internal/query/key_test.go @@ -31,18 +31,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePublicKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_public.expiry,`+ - ` zitadel.projections.keys_public.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_public.expiry,`+ + ` projections.keys_public.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_public ON zitadel.projections.keys.id = zitadel.projections.keys_public.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`), nil, nil, ), @@ -60,18 +60,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePublicKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_public.expiry,`+ - ` zitadel.projections.keys_public.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_public.expiry,`+ + ` projections.keys_public.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_public ON zitadel.projections.keys.id = zitadel.projections.keys_public.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`), []string{ "id", "creation_date", @@ -128,18 +128,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePublicKeysQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_public.expiry,`+ - ` zitadel.projections.keys_public.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_public.expiry,`+ + ` projections.keys_public.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_public ON zitadel.projections.keys.id = zitadel.projections.keys_public.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_public ON projections.keys.id = projections.keys_public.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -156,18 +156,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePrivateKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_private.expiry,`+ - ` zitadel.projections.keys_private.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_private.expiry,`+ + ` projections.keys_private.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_private ON zitadel.projections.keys.id = zitadel.projections.keys_private.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`), nil, nil, ), @@ -185,18 +185,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePrivateKeysQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_private.expiry,`+ - ` zitadel.projections.keys_private.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_private.expiry,`+ + ` projections.keys_private.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_private ON zitadel.projections.keys.id = zitadel.projections.keys_private.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`), []string{ "id", "creation_date", @@ -255,18 +255,18 @@ func Test_KeyPrepares(t *testing.T) { prepare: preparePrivateKeysQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.keys.id,`+ - ` zitadel.projections.keys.creation_date,`+ - ` zitadel.projections.keys.change_date,`+ - ` zitadel.projections.keys.sequence,`+ - ` zitadel.projections.keys.resource_owner,`+ - ` zitadel.projections.keys.algorithm,`+ - ` zitadel.projections.keys.use,`+ - ` zitadel.projections.keys_private.expiry,`+ - ` zitadel.projections.keys_private.key,`+ + regexp.QuoteMeta(`SELECT projections.keys.id,`+ + ` projections.keys.creation_date,`+ + ` projections.keys.change_date,`+ + ` projections.keys.sequence,`+ + ` projections.keys.resource_owner,`+ + ` projections.keys.algorithm,`+ + ` projections.keys.use,`+ + ` projections.keys_private.expiry,`+ + ` projections.keys_private.key,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.keys`+ - ` LEFT JOIN zitadel.projections.keys_private ON zitadel.projections.keys.id = zitadel.projections.keys_private.id`), + ` FROM projections.keys`+ + ` LEFT JOIN projections.keys_private ON projections.keys.id = projections.keys_private.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/label_policy.go b/internal/query/label_policy.go index 0f53124e20..7abce67ceb 100644 --- a/internal/query/label_policy.go +++ b/internal/query/label_policy.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -51,7 +53,8 @@ func (q *Queries) ActiveLabelPolicyByOrg(ctx context.Context, orgID string) (*La }, }, sq.Eq{ - LabelPolicyColState.identifier(): domain.LabelPolicyStateActive, + LabelPolicyColState.identifier(): domain.LabelPolicyStateActive, + LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, }). OrderBy(LabelPolicyColIsDefault.identifier()). @@ -77,7 +80,8 @@ func (q *Queries) PreviewLabelPolicyByOrg(ctx context.Context, orgID string) (*L }, }, sq.Eq{ - LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview, + LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview, + LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, }). OrderBy(LabelPolicyColIsDefault.identifier()). @@ -93,8 +97,9 @@ func (q *Queries) PreviewLabelPolicyByOrg(ctx context.Context, orgID string) (*L func (q *Queries) DefaultActiveLabelPolicy(ctx context.Context) (*LabelPolicy, error) { stmt, scan := prepareLabelPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - LabelPolicyColID.identifier(): domain.IAMID, - LabelPolicyColState.identifier(): domain.LabelPolicyStateActive, + LabelPolicyColID.identifier(): domain.IAMID, + LabelPolicyColState.identifier(): domain.LabelPolicyStateActive, + LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(LabelPolicyColIsDefault.identifier()). Limit(1).ToSql() @@ -109,8 +114,9 @@ func (q *Queries) DefaultActiveLabelPolicy(ctx context.Context) (*LabelPolicy, e func (q *Queries) DefaultPreviewLabelPolicy(ctx context.Context) (*LabelPolicy, error) { stmt, scan := prepareLabelPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - LabelPolicyColID.identifier(): domain.IAMID, - LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview, + LabelPolicyColID.identifier(): domain.IAMID, + LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview, + LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(LabelPolicyColIsDefault.identifier()). Limit(1).ToSql() @@ -147,6 +153,9 @@ var ( LabelPolicyColResourceOwner = Column{ name: projection.LabelPolicyResourceOwnerCol, } + LabelPolicyColInstanceID = Column{ + name: projection.LabelPolicyInstanceIDCol, + } LabelPolicyColHideLoginNameSuffix = Column{ name: projection.LabelPolicyHideLoginNameSuffixCol, } diff --git a/internal/query/lockout_policy.go b/internal/query/lockout_policy.go index db5d474708..fb7edb5860 100644 --- a/internal/query/lockout_policy.go +++ b/internal/query/lockout_policy.go @@ -7,6 +7,9 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -34,6 +37,10 @@ var ( name: projection.LockoutPolicyIDCol, table: lockoutTable, } + LockoutColInstanceID = Column{ + name: projection.LockoutPolicyInstanceIDCol, + table: lockoutTable, + } LockoutColSequence = Column{ name: projection.LockoutPolicySequenceCol, table: lockoutTable, @@ -71,12 +78,17 @@ var ( func (q *Queries) LockoutPolicyByOrg(ctx context.Context, orgID string) (*LockoutPolicy, error) { stmt, scan := prepareLockoutPolicyQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - LockoutColID.identifier(): orgID, + LockoutColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - LockoutColID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + LockoutColID.identifier(): orgID, + }, + sq.Eq{ + LockoutColID.identifier(): domain.IAMID, + }, }, }). OrderBy(LockoutColIsDefault.identifier()). @@ -92,7 +104,8 @@ func (q *Queries) LockoutPolicyByOrg(ctx context.Context, orgID string) (*Lockou func (q *Queries) DefaultLockoutPolicy(ctx context.Context) (*LockoutPolicy, error) { stmt, scan := prepareLockoutPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - LockoutColID.identifier(): domain.IAMID, + LockoutColID.identifier(): domain.IAMID, + LockoutColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(LockoutColIsDefault.identifier()). Limit(1).ToSql() diff --git a/internal/query/lockout_policy_test.go b/internal/query/lockout_policy_test.go index 2a05448459..72366dd744 100644 --- a/internal/query/lockout_policy_test.go +++ b/internal/query/lockout_policy_test.go @@ -28,16 +28,16 @@ func Test_LockoutPolicyPrepares(t *testing.T) { prepare: prepareLockoutPolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.lockout_policies.id,`+ - ` zitadel.projections.lockout_policies.sequence,`+ - ` zitadel.projections.lockout_policies.creation_date,`+ - ` zitadel.projections.lockout_policies.change_date,`+ - ` zitadel.projections.lockout_policies.resource_owner,`+ - ` zitadel.projections.lockout_policies.show_failure,`+ - ` zitadel.projections.lockout_policies.max_password_attempts,`+ - ` zitadel.projections.lockout_policies.is_default,`+ - ` zitadel.projections.lockout_policies.state`+ - ` FROM zitadel.projections.lockout_policies`), + regexp.QuoteMeta(`SELECT projections.lockout_policies.id,`+ + ` projections.lockout_policies.sequence,`+ + ` projections.lockout_policies.creation_date,`+ + ` projections.lockout_policies.change_date,`+ + ` projections.lockout_policies.resource_owner,`+ + ` projections.lockout_policies.show_failure,`+ + ` projections.lockout_policies.max_password_attempts,`+ + ` projections.lockout_policies.is_default,`+ + ` projections.lockout_policies.state`+ + ` FROM projections.lockout_policies`), nil, nil, ), @@ -55,16 +55,16 @@ func Test_LockoutPolicyPrepares(t *testing.T) { prepare: prepareLockoutPolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.lockout_policies.id,`+ - ` zitadel.projections.lockout_policies.sequence,`+ - ` zitadel.projections.lockout_policies.creation_date,`+ - ` zitadel.projections.lockout_policies.change_date,`+ - ` zitadel.projections.lockout_policies.resource_owner,`+ - ` zitadel.projections.lockout_policies.show_failure,`+ - ` zitadel.projections.lockout_policies.max_password_attempts,`+ - ` zitadel.projections.lockout_policies.is_default,`+ - ` zitadel.projections.lockout_policies.state`+ - ` FROM zitadel.projections.lockout_policies`), + regexp.QuoteMeta(`SELECT projections.lockout_policies.id,`+ + ` projections.lockout_policies.sequence,`+ + ` projections.lockout_policies.creation_date,`+ + ` projections.lockout_policies.change_date,`+ + ` projections.lockout_policies.resource_owner,`+ + ` projections.lockout_policies.show_failure,`+ + ` projections.lockout_policies.max_password_attempts,`+ + ` projections.lockout_policies.is_default,`+ + ` projections.lockout_policies.state`+ + ` FROM projections.lockout_policies`), []string{ "id", "sequence", @@ -106,16 +106,16 @@ func Test_LockoutPolicyPrepares(t *testing.T) { prepare: prepareLockoutPolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.lockout_policies.id,`+ - ` zitadel.projections.lockout_policies.sequence,`+ - ` zitadel.projections.lockout_policies.creation_date,`+ - ` zitadel.projections.lockout_policies.change_date,`+ - ` zitadel.projections.lockout_policies.resource_owner,`+ - ` zitadel.projections.lockout_policies.show_failure,`+ - ` zitadel.projections.lockout_policies.max_password_attempts,`+ - ` zitadel.projections.lockout_policies.is_default,`+ - ` zitadel.projections.lockout_policies.state`+ - ` FROM zitadel.projections.lockout_policies`), + regexp.QuoteMeta(`SELECT projections.lockout_policies.id,`+ + ` projections.lockout_policies.sequence,`+ + ` projections.lockout_policies.creation_date,`+ + ` projections.lockout_policies.change_date,`+ + ` projections.lockout_policies.resource_owner,`+ + ` projections.lockout_policies.show_failure,`+ + ` projections.lockout_policies.max_password_attempts,`+ + ` projections.lockout_policies.is_default,`+ + ` projections.lockout_policies.state`+ + ` FROM projections.lockout_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/login_name.go b/internal/query/login_name.go index 8eb7d0c62a..b0facabf95 100644 --- a/internal/query/login_name.go +++ b/internal/query/login_name.go @@ -18,4 +18,8 @@ var ( name: projection.LoginNameDomainIsPrimaryCol, table: loginNameTable, } + LoginNameInstanceIDCol = Column{ + name: projection.LoginNameUserInstanceIDCol, + table: loginNameTable, + } ) diff --git a/internal/query/login_policy.go b/internal/query/login_policy.go index 55ec82d36f..8a3d2535d8 100644 --- a/internal/query/login_policy.go +++ b/internal/query/login_policy.go @@ -7,10 +7,13 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "github.com/lib/pq" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" - "github.com/lib/pq" ) type LoginPolicy struct { @@ -52,6 +55,10 @@ var ( name: projection.LoginPolicyIDCol, table: loginPolicyTable, } + LoginPolicyColumnInstanceID = Column{ + name: projection.LoginPolicyInstanceIDCol, + table: loginPolicyTable, + } LoginPolicyColumnCreationDate = Column{ name: projection.LoginPolicyCreationDateCol, table: loginPolicyTable, @@ -125,12 +132,17 @@ var ( func (q *Queries) LoginPolicyByID(ctx context.Context, orgID string) (*LoginPolicy, error) { query, scan := prepareLoginPolicyQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - LoginPolicyColumnOrgID.identifier(): orgID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): orgID, + }, + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + }, }, }). OrderBy(LoginPolicyColumnIsDefault.identifier()). @@ -146,7 +158,8 @@ func (q *Queries) LoginPolicyByID(ctx context.Context, orgID string) (*LoginPoli func (q *Queries) DefaultLoginPolicy(ctx context.Context) (*LoginPolicy, error) { query, scan := prepareLoginPolicyQuery() stmt, args, err := query.Where(sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-t4TBK", "Errors.Query.SQLStatement") @@ -159,12 +172,17 @@ func (q *Queries) DefaultLoginPolicy(ctx context.Context) (*LoginPolicy, error) func (q *Queries) SecondFactorsByOrg(ctx context.Context, orgID string) (*SecondFactors, error) { query, scan := prepareLoginPolicy2FAsQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - LoginPolicyColumnOrgID.identifier(): orgID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): orgID, + }, + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + }, }, }). OrderBy(LoginPolicyColumnIsDefault.identifier()). @@ -185,7 +203,8 @@ func (q *Queries) SecondFactorsByOrg(ctx context.Context, orgID string) (*Second func (q *Queries) DefaultSecondFactors(ctx context.Context) (*SecondFactors, error) { query, scan := prepareLoginPolicy2FAsQuery() stmt, args, err := query.Where(sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-CZ2Nv", "Errors.Query.SQLStatement") @@ -203,12 +222,17 @@ func (q *Queries) DefaultSecondFactors(ctx context.Context) (*SecondFactors, err func (q *Queries) MultiFactorsByOrg(ctx context.Context, orgID string) (*MultiFactors, error) { query, scan := prepareLoginPolicyMFAsQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - LoginPolicyColumnOrgID.identifier(): orgID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): orgID, + }, + sq.Eq{ + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + }, }, }). OrderBy(LoginPolicyColumnIsDefault.identifier()). @@ -229,7 +253,8 @@ func (q *Queries) MultiFactorsByOrg(ctx context.Context, orgID string) (*MultiFa func (q *Queries) DefaultMultiFactors(ctx context.Context) (*MultiFactors, error) { query, scan := prepareLoginPolicyMFAsQuery() stmt, args, err := query.Where(sq.Eq{ - LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnOrgID.identifier(): domain.IAMID, + LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-WxYjr", "Errors.Query.SQLStatement") diff --git a/internal/query/login_policy_test.go b/internal/query/login_policy_test.go index ade38bdc17..9ea56add92 100644 --- a/internal/query/login_policy_test.go +++ b/internal/query/login_policy_test.go @@ -9,9 +9,10 @@ import ( "testing" "time" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" - "github.com/lib/pq" ) func Test_LoginPolicyPrepares(t *testing.T) { @@ -30,25 +31,25 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.aggregate_id,`+ - ` zitadel.projections.login_policies.creation_date,`+ - ` zitadel.projections.login_policies.change_date,`+ - ` zitadel.projections.login_policies.sequence,`+ - ` zitadel.projections.login_policies.allow_register,`+ - ` zitadel.projections.login_policies.allow_username_password,`+ - ` zitadel.projections.login_policies.allow_external_idps,`+ - ` zitadel.projections.login_policies.force_mfa,`+ - ` zitadel.projections.login_policies.second_factors,`+ - ` zitadel.projections.login_policies.multi_factors,`+ - ` zitadel.projections.login_policies.passwordless_type,`+ - ` zitadel.projections.login_policies.is_default,`+ - ` zitadel.projections.login_policies.hide_password_reset,`+ - ` zitadel.projections.login_policies.password_check_lifetime,`+ - ` zitadel.projections.login_policies.external_login_check_lifetime,`+ - ` zitadel.projections.login_policies.mfa_init_skip_lifetime,`+ - ` zitadel.projections.login_policies.second_factor_check_lifetime,`+ - ` zitadel.projections.login_policies.multi_factor_check_lifetime`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.aggregate_id,`+ + ` projections.login_policies.creation_date,`+ + ` projections.login_policies.change_date,`+ + ` projections.login_policies.sequence,`+ + ` projections.login_policies.allow_register,`+ + ` projections.login_policies.allow_username_password,`+ + ` projections.login_policies.allow_external_idps,`+ + ` projections.login_policies.force_mfa,`+ + ` projections.login_policies.second_factors,`+ + ` projections.login_policies.multi_factors,`+ + ` projections.login_policies.passwordless_type,`+ + ` projections.login_policies.is_default,`+ + ` projections.login_policies.hide_password_reset,`+ + ` projections.login_policies.password_check_lifetime,`+ + ` projections.login_policies.external_login_check_lifetime,`+ + ` projections.login_policies.mfa_init_skip_lifetime,`+ + ` projections.login_policies.second_factor_check_lifetime,`+ + ` projections.login_policies.multi_factor_check_lifetime`+ + ` FROM projections.login_policies`), nil, nil, ), @@ -66,25 +67,25 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.aggregate_id,`+ - ` zitadel.projections.login_policies.creation_date,`+ - ` zitadel.projections.login_policies.change_date,`+ - ` zitadel.projections.login_policies.sequence,`+ - ` zitadel.projections.login_policies.allow_register,`+ - ` zitadel.projections.login_policies.allow_username_password,`+ - ` zitadel.projections.login_policies.allow_external_idps,`+ - ` zitadel.projections.login_policies.force_mfa,`+ - ` zitadel.projections.login_policies.second_factors,`+ - ` zitadel.projections.login_policies.multi_factors,`+ - ` zitadel.projections.login_policies.passwordless_type,`+ - ` zitadel.projections.login_policies.is_default,`+ - ` zitadel.projections.login_policies.hide_password_reset,`+ - ` zitadel.projections.login_policies.password_check_lifetime,`+ - ` zitadel.projections.login_policies.external_login_check_lifetime,`+ - ` zitadel.projections.login_policies.mfa_init_skip_lifetime,`+ - ` zitadel.projections.login_policies.second_factor_check_lifetime,`+ - ` zitadel.projections.login_policies.multi_factor_check_lifetime`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.aggregate_id,`+ + ` projections.login_policies.creation_date,`+ + ` projections.login_policies.change_date,`+ + ` projections.login_policies.sequence,`+ + ` projections.login_policies.allow_register,`+ + ` projections.login_policies.allow_username_password,`+ + ` projections.login_policies.allow_external_idps,`+ + ` projections.login_policies.force_mfa,`+ + ` projections.login_policies.second_factors,`+ + ` projections.login_policies.multi_factors,`+ + ` projections.login_policies.passwordless_type,`+ + ` projections.login_policies.is_default,`+ + ` projections.login_policies.hide_password_reset,`+ + ` projections.login_policies.password_check_lifetime,`+ + ` projections.login_policies.external_login_check_lifetime,`+ + ` projections.login_policies.mfa_init_skip_lifetime,`+ + ` projections.login_policies.second_factor_check_lifetime,`+ + ` projections.login_policies.multi_factor_check_lifetime`+ + ` FROM projections.login_policies`), []string{ "aggregate_id", "creation_date", @@ -153,25 +154,25 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.aggregate_id,`+ - ` zitadel.projections.login_policies.creation_date,`+ - ` zitadel.projections.login_policies.change_date,`+ - ` zitadel.projections.login_policies.sequence,`+ - ` zitadel.projections.login_policies.allow_register,`+ - ` zitadel.projections.login_policies.allow_username_password,`+ - ` zitadel.projections.login_policies.allow_external_idps,`+ - ` zitadel.projections.login_policies.force_mfa,`+ - ` zitadel.projections.login_policies.second_factors,`+ - ` zitadel.projections.login_policies.multi_factors,`+ - ` zitadel.projections.login_policies.passwordless_type,`+ - ` zitadel.projections.login_policies.is_default,`+ - ` zitadel.projections.login_policies.hide_password_reset,`+ - ` zitadel.projections.login_policies.password_check_lifetime,`+ - ` zitadel.projections.login_policies.external_login_check_lifetime,`+ - ` zitadel.projections.login_policies.mfa_init_skip_lifetime,`+ - ` zitadel.projections.login_policies.second_factor_check_lifetime,`+ - ` zitadel.projections.login_policies.multi_factor_check_lifetime`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.aggregate_id,`+ + ` projections.login_policies.creation_date,`+ + ` projections.login_policies.change_date,`+ + ` projections.login_policies.sequence,`+ + ` projections.login_policies.allow_register,`+ + ` projections.login_policies.allow_username_password,`+ + ` projections.login_policies.allow_external_idps,`+ + ` projections.login_policies.force_mfa,`+ + ` projections.login_policies.second_factors,`+ + ` projections.login_policies.multi_factors,`+ + ` projections.login_policies.passwordless_type,`+ + ` projections.login_policies.is_default,`+ + ` projections.login_policies.hide_password_reset,`+ + ` projections.login_policies.password_check_lifetime,`+ + ` projections.login_policies.external_login_check_lifetime,`+ + ` projections.login_policies.mfa_init_skip_lifetime,`+ + ` projections.login_policies.second_factor_check_lifetime,`+ + ` projections.login_policies.multi_factor_check_lifetime`+ + ` FROM projections.login_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -188,8 +189,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicy2FAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.second_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.second_factors`+ + ` FROM projections.login_policies`), []string{ "second_factors", }, @@ -209,8 +210,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicy2FAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.second_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.second_factors`+ + ` FROM projections.login_policies`), []string{ "second_factors", }, @@ -231,8 +232,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicy2FAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.second_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.second_factors`+ + ` FROM projections.login_policies`), []string{ "second_factors", }, @@ -248,8 +249,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicy2FAsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.second_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.second_factors`+ + ` FROM projections.login_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -267,8 +268,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyMFAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.multi_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.multi_factors`+ + ` FROM projections.login_policies`), []string{ "multi_factors", }, @@ -288,8 +289,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyMFAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.multi_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.multi_factors`+ + ` FROM projections.login_policies`), []string{ "multi_factors", }, @@ -310,8 +311,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyMFAsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.multi_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.multi_factors`+ + ` FROM projections.login_policies`), []string{ "multi_factors", }, @@ -327,8 +328,8 @@ func Test_LoginPolicyPrepares(t *testing.T) { prepare: prepareLoginPolicyMFAsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.login_policies.multi_factors`+ - ` FROM zitadel.projections.login_policies`), + regexp.QuoteMeta(`SELECT projections.login_policies.multi_factors`+ + ` FROM projections.login_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/mail_template.go b/internal/query/mail_template.go index daba2b7f25..df5450306b 100644 --- a/internal/query/mail_template.go +++ b/internal/query/mail_template.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -31,6 +33,10 @@ var ( name: projection.MailTemplateAggregateIDCol, table: mailTemplateTable, } + MailTemplateColInstanceID = Column{ + name: projection.MailTemplateInstanceIDCol, + table: mailTemplateTable, + } MailTemplateColSequence = Column{ name: projection.MailTemplateSequenceCol, table: mailTemplateTable, @@ -60,12 +66,17 @@ var ( func (q *Queries) MailTemplateByOrg(ctx context.Context, orgID string) (*MailTemplate, error) { stmt, scan := prepareMailTemplateQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - MailTemplateColAggregateID.identifier(): orgID, + MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - MailTemplateColAggregateID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + MailTemplateColAggregateID.identifier(): orgID, + }, + sq.Eq{ + MailTemplateColAggregateID.identifier(): domain.IAMID, + }, }, }). OrderBy(MailTemplateColIsDefault.identifier()). @@ -82,6 +93,7 @@ func (q *Queries) DefaultMailTemplate(ctx context.Context) (*MailTemplate, error stmt, scan := prepareMailTemplateQuery() query, args, err := stmt.Where(sq.Eq{ MailTemplateColAggregateID.identifier(): domain.IAMID, + MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(MailTemplateColIsDefault.identifier()). Limit(1).ToSql() diff --git a/internal/query/member_roles.go b/internal/query/member_roles.go index 740cfb10cc..105e79952c 100644 --- a/internal/query/member_roles.go +++ b/internal/query/member_roles.go @@ -32,7 +32,7 @@ func (q *Queries) GetOrgMemberRoles(isGlobal bool) []string { } func (q *Queries) GetProjectMemberRoles(ctx context.Context) ([]string, error) { - iam, err := q.IAMByID(ctx, domain.IAMID) + iam, err := q.IAM(ctx) if err != nil { return nil, err } diff --git a/internal/query/message_text.go b/internal/query/message_text.go index ecdc67487d..45c5bf7c3f 100644 --- a/internal/query/message_text.go +++ b/internal/query/message_text.go @@ -15,6 +15,8 @@ import ( "golang.org/x/text/language" "sigs.k8s.io/yaml" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -57,6 +59,10 @@ var ( name: projection.MessageTextAggregateIDCol, table: messageTextTable, } + MessageTextColInstanceID = Column{ + name: projection.MessageTextInstanceIDCol, + table: messageTextTable, + } MessageTextColSequence = Column{ name: projection.MessageTextSequenceCol, table: messageTextTable, @@ -114,12 +120,17 @@ var ( func (q *Queries) MessageTextByOrg(ctx context.Context, orgID string) (*MessageText, error) { stmt, scan := prepareMessageTextQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - MessageTextColAggregateID.identifier(): orgID, + MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - MessageTextColAggregateID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + MessageTextColAggregateID.identifier(): orgID, + }, + sq.Eq{ + MessageTextColAggregateID.identifier(): domain.IAMID, + }, }, }). OrderBy(MessageTextColAggregateID.identifier()). @@ -136,6 +147,7 @@ func (q *Queries) DefaultMessageText(ctx context.Context) (*MessageText, error) stmt, scan := prepareMessageTextQuery() query, args, err := stmt.Where(sq.Eq{ MessageTextColAggregateID.identifier(): domain.IAMID, + MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). Limit(1).ToSql() if err != nil { @@ -161,16 +173,11 @@ func (q *Queries) DefaultMessageTextByTypeAndLanguageFromFileSystem(messageType, func (q *Queries) CustomMessageTextByTypeAndLanguage(ctx context.Context, aggregateID, messageType, language string) (*MessageText, error) { stmt, scan := prepareMessageTextQuery() query, args, err := stmt.Where( - sq.And{ - sq.Eq{ - MessageTextColLanguage.identifier(): language, - }, - sq.Eq{ - MessageTextColType.identifier(): messageType, - }, - sq.Eq{ - MessageTextColAggregateID.identifier(): aggregateID, - }, + sq.Eq{ + MessageTextColLanguage.identifier(): language, + MessageTextColType.identifier(): messageType, + MessageTextColAggregateID.identifier(): aggregateID, + MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ). OrderBy(MessageTextColAggregateID.identifier()). diff --git a/internal/query/message_text_test.go b/internal/query/message_text_test.go index ebc0131d3e..5a27b66cc4 100644 --- a/internal/query/message_text_test.go +++ b/internal/query/message_text_test.go @@ -8,9 +8,10 @@ import ( "regexp" "testing" + "golang.org/x/text/language" + "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" - "golang.org/x/text/language" ) func Test_MessageTextPrepares(t *testing.T) { @@ -29,21 +30,21 @@ func Test_MessageTextPrepares(t *testing.T) { prepare: prepareMessageTextQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+ - ` zitadel.projections.message_texts.sequence,`+ - ` zitadel.projections.message_texts.creation_date,`+ - ` zitadel.projections.message_texts.change_date,`+ - ` zitadel.projections.message_texts.state,`+ - ` zitadel.projections.message_texts.type,`+ - ` zitadel.projections.message_texts.language,`+ - ` zitadel.projections.message_texts.title,`+ - ` zitadel.projections.message_texts.pre_header,`+ - ` zitadel.projections.message_texts.subject,`+ - ` zitadel.projections.message_texts.greeting,`+ - ` zitadel.projections.message_texts.text,`+ - ` zitadel.projections.message_texts.button_text,`+ - ` zitadel.projections.message_texts.footer_text`+ - ` FROM zitadel.projections.message_texts`), + regexp.QuoteMeta(`SELECT projections.message_texts.aggregate_id,`+ + ` projections.message_texts.sequence,`+ + ` projections.message_texts.creation_date,`+ + ` projections.message_texts.change_date,`+ + ` projections.message_texts.state,`+ + ` projections.message_texts.type,`+ + ` projections.message_texts.language,`+ + ` projections.message_texts.title,`+ + ` projections.message_texts.pre_header,`+ + ` projections.message_texts.subject,`+ + ` projections.message_texts.greeting,`+ + ` projections.message_texts.text,`+ + ` projections.message_texts.button_text,`+ + ` projections.message_texts.footer_text`+ + ` FROM projections.message_texts`), nil, nil, ), @@ -61,21 +62,21 @@ func Test_MessageTextPrepares(t *testing.T) { prepare: prepareMessageTextQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+ - ` zitadel.projections.message_texts.sequence,`+ - ` zitadel.projections.message_texts.creation_date,`+ - ` zitadel.projections.message_texts.change_date,`+ - ` zitadel.projections.message_texts.state,`+ - ` zitadel.projections.message_texts.type,`+ - ` zitadel.projections.message_texts.language,`+ - ` zitadel.projections.message_texts.title,`+ - ` zitadel.projections.message_texts.pre_header,`+ - ` zitadel.projections.message_texts.subject,`+ - ` zitadel.projections.message_texts.greeting,`+ - ` zitadel.projections.message_texts.text,`+ - ` zitadel.projections.message_texts.button_text,`+ - ` zitadel.projections.message_texts.footer_text`+ - ` FROM zitadel.projections.message_texts`), + regexp.QuoteMeta(`SELECT projections.message_texts.aggregate_id,`+ + ` projections.message_texts.sequence,`+ + ` projections.message_texts.creation_date,`+ + ` projections.message_texts.change_date,`+ + ` projections.message_texts.state,`+ + ` projections.message_texts.type,`+ + ` projections.message_texts.language,`+ + ` projections.message_texts.title,`+ + ` projections.message_texts.pre_header,`+ + ` projections.message_texts.subject,`+ + ` projections.message_texts.greeting,`+ + ` projections.message_texts.text,`+ + ` projections.message_texts.button_text,`+ + ` projections.message_texts.footer_text`+ + ` FROM projections.message_texts`), []string{ "aggregate_id", "sequence", @@ -132,21 +133,21 @@ func Test_MessageTextPrepares(t *testing.T) { prepare: prepareMessageTextQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.message_texts.aggregate_id,`+ - ` zitadel.projections.message_texts.sequence,`+ - ` zitadel.projections.message_texts.creation_date,`+ - ` zitadel.projections.message_texts.change_date,`+ - ` zitadel.projections.message_texts.state,`+ - ` zitadel.projections.message_texts.type,`+ - ` zitadel.projections.message_texts.language,`+ - ` zitadel.projections.message_texts.title,`+ - ` zitadel.projections.message_texts.pre_header,`+ - ` zitadel.projections.message_texts.subject,`+ - ` zitadel.projections.message_texts.greeting,`+ - ` zitadel.projections.message_texts.text,`+ - ` zitadel.projections.message_texts.button_text,`+ - ` zitadel.projections.message_texts.footer_text`+ - ` FROM zitadel.projections.message_texts`), + regexp.QuoteMeta(`SELECT projections.message_texts.aggregate_id,`+ + ` projections.message_texts.sequence,`+ + ` projections.message_texts.creation_date,`+ + ` projections.message_texts.change_date,`+ + ` projections.message_texts.state,`+ + ` projections.message_texts.type,`+ + ` projections.message_texts.language,`+ + ` projections.message_texts.title,`+ + ` projections.message_texts.pre_header,`+ + ` projections.message_texts.subject,`+ + ` projections.message_texts.greeting,`+ + ` projections.message_texts.text,`+ + ` projections.message_texts.button_text,`+ + ` projections.message_texts.footer_text`+ + ` FROM projections.message_texts`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/notification_provider.go b/internal/query/notification_provider.go index 5bd605d5db..aa2ca80049 100644 --- a/internal/query/notification_provider.go +++ b/internal/query/notification_provider.go @@ -7,6 +7,9 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -47,6 +50,10 @@ var ( name: projection.DebugNotificationProviderResourceOwnerCol, table: notificationProviderTable, } + NotificationProviderColumnInstanceID = Column{ + name: projection.DebugNotificationProviderInstanceIDCol, + table: notificationProviderTable, + } NotificationProviderColumnState = Column{ name: projection.DebugNotificationProviderStateCol, table: notificationProviderTable, @@ -64,9 +71,15 @@ var ( func (q *Queries) NotificationProviderByIDAndType(ctx context.Context, aggID string, providerType domain.NotificationProviderType) (*DebugNotificationProvider, error) { query, scan := prepareDebugNotificationProviderQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - LoginPolicyColumnOrgID.identifier(): aggID, + NotificationProviderColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }, + sq.Or{ + sq.Eq{ + NotificationProviderColumnAggID.identifier(): aggID, + NotificationProviderColumnType.identifier(): providerType, + }, }, }). Limit(1).ToSql() diff --git a/internal/query/notification_provider_test.go b/internal/query/notification_provider_test.go index 82103e620b..81493125e4 100644 --- a/internal/query/notification_provider_test.go +++ b/internal/query/notification_provider_test.go @@ -28,15 +28,15 @@ func Test_NotificationProviderPrepares(t *testing.T) { prepare: prepareDebugNotificationProviderQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+ - ` zitadel.projections.notification_providers.creation_date,`+ - ` zitadel.projections.notification_providers.change_date,`+ - ` zitadel.projections.notification_providers.sequence,`+ - ` zitadel.projections.notification_providers.resource_owner,`+ - ` zitadel.projections.notification_providers.state,`+ - ` zitadel.projections.notification_providers.provider_type,`+ - ` zitadel.projections.notification_providers.compact`+ - ` FROM zitadel.projections.notification_providers`), + regexp.QuoteMeta(`SELECT projections.notification_providers.aggregate_id,`+ + ` projections.notification_providers.creation_date,`+ + ` projections.notification_providers.change_date,`+ + ` projections.notification_providers.sequence,`+ + ` projections.notification_providers.resource_owner,`+ + ` projections.notification_providers.state,`+ + ` projections.notification_providers.provider_type,`+ + ` projections.notification_providers.compact`+ + ` FROM projections.notification_providers`), nil, nil, ), @@ -54,15 +54,15 @@ func Test_NotificationProviderPrepares(t *testing.T) { prepare: prepareDebugNotificationProviderQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+ - ` zitadel.projections.notification_providers.creation_date,`+ - ` zitadel.projections.notification_providers.change_date,`+ - ` zitadel.projections.notification_providers.sequence,`+ - ` zitadel.projections.notification_providers.resource_owner,`+ - ` zitadel.projections.notification_providers.state,`+ - ` zitadel.projections.notification_providers.provider_type,`+ - ` zitadel.projections.notification_providers.compact`+ - ` FROM zitadel.projections.notification_providers`), + regexp.QuoteMeta(`SELECT projections.notification_providers.aggregate_id,`+ + ` projections.notification_providers.creation_date,`+ + ` projections.notification_providers.change_date,`+ + ` projections.notification_providers.sequence,`+ + ` projections.notification_providers.resource_owner,`+ + ` projections.notification_providers.state,`+ + ` projections.notification_providers.provider_type,`+ + ` projections.notification_providers.compact`+ + ` FROM projections.notification_providers`), []string{ "aggregate_id", "creation_date", @@ -101,15 +101,15 @@ func Test_NotificationProviderPrepares(t *testing.T) { prepare: prepareDebugNotificationProviderQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.notification_providers.aggregate_id,`+ - ` zitadel.projections.notification_providers.creation_date,`+ - ` zitadel.projections.notification_providers.change_date,`+ - ` zitadel.projections.notification_providers.sequence,`+ - ` zitadel.projections.notification_providers.resource_owner,`+ - ` zitadel.projections.notification_providers.state,`+ - ` zitadel.projections.notification_providers.provider_type,`+ - ` zitadel.projections.notification_providers.compact`+ - ` FROM zitadel.projections.notification_providers`), + regexp.QuoteMeta(`SELECT projections.notification_providers.aggregate_id,`+ + ` projections.notification_providers.creation_date,`+ + ` projections.notification_providers.change_date,`+ + ` projections.notification_providers.sequence,`+ + ` projections.notification_providers.resource_owner,`+ + ` projections.notification_providers.state,`+ + ` projections.notification_providers.provider_type,`+ + ` projections.notification_providers.compact`+ + ` FROM projections.notification_providers`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/oidc_settings.go b/internal/query/oidc_settings.go index 61323cc32f..be0d96f02d 100644 --- a/internal/query/oidc_settings.go +++ b/internal/query/oidc_settings.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -31,6 +33,10 @@ var ( name: projection.OIDCSettingsColumnResourceOwner, table: oidcSettingsTable, } + OIDCSettingsColumnInstanceID = Column{ + name: projection.OIDCSettingsColumnInstanceID, + table: oidcSettingsTable, + } OIDCSettingsColumnSequence = Column{ name: projection.OIDCSettingsColumnSequence, table: oidcSettingsTable, @@ -70,6 +76,7 @@ func (q *Queries) OIDCSettingsByAggID(ctx context.Context, aggregateID string) ( stmt, scan := prepareOIDCSettingsQuery() query, args, err := stmt.Where(sq.Eq{ OIDCSettingsColumnAggregateID.identifier(): aggregateID, + OIDCSettingsColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-s9nle", "Errors.Query.SQLStatment") diff --git a/internal/query/oidc_settings_test.go b/internal/query/oidc_settings_test.go index 601766023f..ca893b5ab3 100644 --- a/internal/query/oidc_settings_test.go +++ b/internal/query/oidc_settings_test.go @@ -28,16 +28,16 @@ func Test_OIDCConfigsPrepares(t *testing.T) { prepare: prepareOIDCSettingsQuery, want: want{ sqlExpectations: mockQueries( - `SELECT zitadel.projections.oidc_settings.aggregate_id,`+ - ` zitadel.projections.oidc_settings.creation_date,`+ - ` zitadel.projections.oidc_settings.change_date,`+ - ` zitadel.projections.oidc_settings.resource_owner,`+ - ` zitadel.projections.oidc_settings.sequence,`+ - ` zitadel.projections.oidc_settings.access_token_lifetime,`+ - ` zitadel.projections.oidc_settings.id_token_lifetime,`+ - ` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+ - ` zitadel.projections.oidc_settings.refresh_token_expiration`+ - ` FROM zitadel.projections.oidc_settings`, + `SELECT projections.oidc_settings.aggregate_id,`+ + ` projections.oidc_settings.creation_date,`+ + ` projections.oidc_settings.change_date,`+ + ` projections.oidc_settings.resource_owner,`+ + ` projections.oidc_settings.sequence,`+ + ` projections.oidc_settings.access_token_lifetime,`+ + ` projections.oidc_settings.id_token_lifetime,`+ + ` projections.oidc_settings.refresh_token_idle_expiration,`+ + ` projections.oidc_settings.refresh_token_expiration`+ + ` FROM projections.oidc_settings`, nil, nil, ), @@ -55,16 +55,16 @@ func Test_OIDCConfigsPrepares(t *testing.T) { prepare: prepareOIDCSettingsQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.oidc_settings.aggregate_id,`+ - ` zitadel.projections.oidc_settings.creation_date,`+ - ` zitadel.projections.oidc_settings.change_date,`+ - ` zitadel.projections.oidc_settings.resource_owner,`+ - ` zitadel.projections.oidc_settings.sequence,`+ - ` zitadel.projections.oidc_settings.access_token_lifetime,`+ - ` zitadel.projections.oidc_settings.id_token_lifetime,`+ - ` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+ - ` zitadel.projections.oidc_settings.refresh_token_expiration`+ - ` FROM zitadel.projections.oidc_settings`), + regexp.QuoteMeta(`SELECT projections.oidc_settings.aggregate_id,`+ + ` projections.oidc_settings.creation_date,`+ + ` projections.oidc_settings.change_date,`+ + ` projections.oidc_settings.resource_owner,`+ + ` projections.oidc_settings.sequence,`+ + ` projections.oidc_settings.access_token_lifetime,`+ + ` projections.oidc_settings.id_token_lifetime,`+ + ` projections.oidc_settings.refresh_token_idle_expiration,`+ + ` projections.oidc_settings.refresh_token_expiration`+ + ` FROM projections.oidc_settings`), []string{ "aggregate_id", "creation_date", @@ -106,16 +106,16 @@ func Test_OIDCConfigsPrepares(t *testing.T) { prepare: prepareOIDCSettingsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.oidc_settings.aggregate_id,`+ - ` zitadel.projections.oidc_settings.creation_date,`+ - ` zitadel.projections.oidc_settings.change_date,`+ - ` zitadel.projections.oidc_settings.resource_owner,`+ - ` zitadel.projections.oidc_settings.sequence,`+ - ` zitadel.projections.oidc_settings.access_token_lifetime,`+ - ` zitadel.projections.oidc_settings.id_token_lifetime,`+ - ` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+ - ` zitadel.projections.oidc_settings.refresh_token_expiration`+ - ` FROM zitadel.projections.oidc_settings`), + regexp.QuoteMeta(`SELECT projections.oidc_settings.aggregate_id,`+ + ` projections.oidc_settings.creation_date,`+ + ` projections.oidc_settings.change_date,`+ + ` projections.oidc_settings.resource_owner,`+ + ` projections.oidc_settings.sequence,`+ + ` projections.oidc_settings.access_token_lifetime,`+ + ` projections.oidc_settings.id_token_lifetime,`+ + ` projections.oidc_settings.refresh_token_idle_expiration,`+ + ` projections.oidc_settings.refresh_token_expiration`+ + ` FROM projections.oidc_settings`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/org.go b/internal/query/org.go index d2481a7414..9f6e18e212 100644 --- a/internal/query/org.go +++ b/internal/query/org.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -32,6 +34,10 @@ var ( name: projection.OrgColumnResourceOwner, table: orgsTable, } + OrgColumnInstanceID = Column{ + name: projection.OrgColumnInstanceID, + table: orgsTable, + } OrgColumnState = Column{ name: projection.OrgColumnState, table: orgsTable, @@ -83,7 +89,8 @@ func (q *OrgSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder { func (q *Queries) OrgByID(ctx context.Context, id string) (*Org, error) { stmt, scan := prepareOrgQuery() query, args, err := stmt.Where(sq.Eq{ - OrgColumnID.identifier(): id, + OrgColumnID.identifier(): id, + OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-AWx52", "Errors.Query.SQLStatement") @@ -96,7 +103,8 @@ func (q *Queries) OrgByID(ctx context.Context, id string) (*Org, error) { func (q *Queries) OrgByDomainGlobal(ctx context.Context, domain string) (*Org, error) { stmt, scan := prepareOrgQuery() query, args, err := stmt.Where(sq.Eq{ - OrgColumnDomain.identifier(): domain, + OrgColumnDomain.identifier(): domain, + OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-TYUCE", "Errors.Query.SQLStatement") @@ -109,12 +117,17 @@ func (q *Queries) OrgByDomainGlobal(ctx context.Context, domain string) (*Org, e func (q *Queries) IsOrgUnique(ctx context.Context, name, domain string) (isUnique bool, err error) { query, scan := prepareOrgUniqueQuery() stmt, args, err := query.Where( - sq.Or{ + sq.And{ sq.Eq{ - OrgColumnDomain.identifier(): domain, + OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - OrgColumnName.identifier(): name, + sq.Or{ + sq.Eq{ + OrgColumnDomain.identifier(): domain, + }, + sq.Eq{ + OrgColumnName.identifier(): name, + }, }, }).ToSql() if err != nil { @@ -132,7 +145,10 @@ func (q *Queries) ExistsOrg(ctx context.Context, id string) (err error) { func (q *Queries) SearchOrgs(ctx context.Context, queries *OrgSearchQueries) (orgs *Orgs, err error) { query, scan := prepareOrgsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-wQ3by", "Errors.Query.InvalidRequest") } diff --git a/internal/query/org_domain.go b/internal/query/org_domain.go index 31dc64c4f0..b8c85eb7c1 100644 --- a/internal/query/org_domain.go +++ b/internal/query/org_domain.go @@ -6,6 +6,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -54,7 +56,10 @@ func NewOrgDomainVerifiedSearchQuery(verified bool) (SearchQuery, error) { func (q *Queries) SearchOrgDomains(ctx context.Context, queries *OrgDomainSearchQueries) (domains *Domains, err error) { query, scan := prepareDomainsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + OrgDomainInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-ZRfj1", "Errors.Query.SQLStatement") } @@ -143,6 +148,10 @@ var ( name: projection.OrgDomainOrgIDCol, table: orgDomainsTable, } + OrgDomainInstanceIDCol = Column{ + name: projection.OrgDomainInstanceIDCol, + table: orgDomainsTable, + } OrgDomainIsVerifiedCol = Column{ name: projection.OrgDomainIsVerifiedCol, table: orgDomainsTable, diff --git a/internal/query/org_domain_test.go b/internal/query/org_domain_test.go index cc31f9a6ca..d2b5e3880d 100644 --- a/internal/query/org_domain_test.go +++ b/internal/query/org_domain_test.go @@ -27,16 +27,16 @@ func Test_OrgDomainPrepares(t *testing.T) { prepare: prepareDomainsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.org_domains.creation_date,`+ - ` zitadel.projections.org_domains.change_date,`+ - ` zitadel.projections.org_domains.sequence,`+ - ` zitadel.projections.org_domains.domain,`+ - ` zitadel.projections.org_domains.org_id,`+ - ` zitadel.projections.org_domains.is_verified,`+ - ` zitadel.projections.org_domains.is_primary,`+ - ` zitadel.projections.org_domains.validation_type,`+ + regexp.QuoteMeta(`SELECT projections.org_domains.creation_date,`+ + ` projections.org_domains.change_date,`+ + ` projections.org_domains.sequence,`+ + ` projections.org_domains.domain,`+ + ` projections.org_domains.org_id,`+ + ` projections.org_domains.is_verified,`+ + ` projections.org_domains.is_primary,`+ + ` projections.org_domains.validation_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.org_domains`), + ` FROM projections.org_domains`), nil, nil, ), @@ -48,16 +48,16 @@ func Test_OrgDomainPrepares(t *testing.T) { prepare: prepareDomainsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.org_domains.creation_date,`+ - ` zitadel.projections.org_domains.change_date,`+ - ` zitadel.projections.org_domains.sequence,`+ - ` zitadel.projections.org_domains.domain,`+ - ` zitadel.projections.org_domains.org_id,`+ - ` zitadel.projections.org_domains.is_verified,`+ - ` zitadel.projections.org_domains.is_primary,`+ - ` zitadel.projections.org_domains.validation_type,`+ + regexp.QuoteMeta(`SELECT projections.org_domains.creation_date,`+ + ` projections.org_domains.change_date,`+ + ` projections.org_domains.sequence,`+ + ` projections.org_domains.domain,`+ + ` projections.org_domains.org_id,`+ + ` projections.org_domains.is_verified,`+ + ` projections.org_domains.is_primary,`+ + ` projections.org_domains.validation_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.org_domains`), + ` FROM projections.org_domains`), []string{ "id", "creation_date", @@ -106,16 +106,16 @@ func Test_OrgDomainPrepares(t *testing.T) { prepare: prepareDomainsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.org_domains.creation_date,`+ - ` zitadel.projections.org_domains.change_date,`+ - ` zitadel.projections.org_domains.sequence,`+ - ` zitadel.projections.org_domains.domain,`+ - ` zitadel.projections.org_domains.org_id,`+ - ` zitadel.projections.org_domains.is_verified,`+ - ` zitadel.projections.org_domains.is_primary,`+ - ` zitadel.projections.org_domains.validation_type,`+ + regexp.QuoteMeta(`SELECT projections.org_domains.creation_date,`+ + ` projections.org_domains.change_date,`+ + ` projections.org_domains.sequence,`+ + ` projections.org_domains.domain,`+ + ` projections.org_domains.org_id,`+ + ` projections.org_domains.is_verified,`+ + ` projections.org_domains.is_primary,`+ + ` projections.org_domains.validation_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.org_domains`), + ` FROM projections.org_domains`), []string{ "id", "creation_date", @@ -184,16 +184,16 @@ func Test_OrgDomainPrepares(t *testing.T) { prepare: prepareDomainsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.org_domains.creation_date,`+ - ` zitadel.projections.org_domains.change_date,`+ - ` zitadel.projections.org_domains.sequence,`+ - ` zitadel.projections.org_domains.domain,`+ - ` zitadel.projections.org_domains.org_id,`+ - ` zitadel.projections.org_domains.is_verified,`+ - ` zitadel.projections.org_domains.is_primary,`+ - ` zitadel.projections.org_domains.validation_type,`+ + regexp.QuoteMeta(`SELECT projections.org_domains.creation_date,`+ + ` projections.org_domains.change_date,`+ + ` projections.org_domains.sequence,`+ + ` projections.org_domains.domain,`+ + ` projections.org_domains.org_id,`+ + ` projections.org_domains.is_verified,`+ + ` projections.org_domains.is_primary,`+ + ` projections.org_domains.validation_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.org_domains`), + ` FROM projections.org_domains`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/org_iam_policy.go b/internal/query/org_iam_policy.go index f31439dfa5..5d25f09da9 100644 --- a/internal/query/org_iam_policy.go +++ b/internal/query/org_iam_policy.go @@ -7,6 +7,9 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -49,6 +52,10 @@ var ( name: projection.OrgIAMPolicyResourceOwnerCol, table: orgIAMTable, } + OrgIAMColInstanceID = Column{ + name: projection.OrgIAMPolicyInstanceIDCol, + table: orgIAMTable, + } OrgIAMColUserLoginMustBeDomain = Column{ name: projection.OrgIAMPolicyUserLoginMustBeDomainCol, table: orgIAMTable, @@ -66,12 +73,17 @@ var ( func (q *Queries) OrgIAMPolicyByOrg(ctx context.Context, orgID string) (*OrgIAMPolicy, error) { stmt, scan := prepareOrgIAMPolicyQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - OrgIAMColID.identifier(): orgID, + OrgIAMColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - OrgIAMColID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + OrgIAMColID.identifier(): orgID, + }, + sq.Eq{ + OrgIAMColID.identifier(): domain.IAMID, + }, }, }). OrderBy(OrgIAMColIsDefault.identifier()). @@ -87,7 +99,8 @@ func (q *Queries) OrgIAMPolicyByOrg(ctx context.Context, orgID string) (*OrgIAMP func (q *Queries) DefaultOrgIAMPolicy(ctx context.Context) (*OrgIAMPolicy, error) { stmt, scan := prepareOrgIAMPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - OrgIAMColID.identifier(): domain.IAMID, + OrgIAMColID.identifier(): domain.IAMID, + OrgIAMColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(OrgIAMColIsDefault.identifier()). Limit(1).ToSql() diff --git a/internal/query/org_iam_policy_test.go b/internal/query/org_iam_policy_test.go index bc0a596484..e7c8ffbecb 100644 --- a/internal/query/org_iam_policy_test.go +++ b/internal/query/org_iam_policy_test.go @@ -28,15 +28,15 @@ func Test_OrgIAMPolicyPrepares(t *testing.T) { prepare: prepareOrgIAMPolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.org_iam_policies.id,`+ - ` zitadel.projections.org_iam_policies.sequence,`+ - ` zitadel.projections.org_iam_policies.creation_date,`+ - ` zitadel.projections.org_iam_policies.change_date,`+ - ` zitadel.projections.org_iam_policies.resource_owner,`+ - ` zitadel.projections.org_iam_policies.user_login_must_be_domain,`+ - ` zitadel.projections.org_iam_policies.is_default,`+ - ` zitadel.projections.org_iam_policies.state`+ - ` FROM zitadel.projections.org_iam_policies`), + regexp.QuoteMeta(`SELECT projections.org_iam_policies.id,`+ + ` projections.org_iam_policies.sequence,`+ + ` projections.org_iam_policies.creation_date,`+ + ` projections.org_iam_policies.change_date,`+ + ` projections.org_iam_policies.resource_owner,`+ + ` projections.org_iam_policies.user_login_must_be_domain,`+ + ` projections.org_iam_policies.is_default,`+ + ` projections.org_iam_policies.state`+ + ` FROM projections.org_iam_policies`), nil, nil, ), @@ -54,15 +54,15 @@ func Test_OrgIAMPolicyPrepares(t *testing.T) { prepare: prepareOrgIAMPolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.org_iam_policies.id,`+ - ` zitadel.projections.org_iam_policies.sequence,`+ - ` zitadel.projections.org_iam_policies.creation_date,`+ - ` zitadel.projections.org_iam_policies.change_date,`+ - ` zitadel.projections.org_iam_policies.resource_owner,`+ - ` zitadel.projections.org_iam_policies.user_login_must_be_domain,`+ - ` zitadel.projections.org_iam_policies.is_default,`+ - ` zitadel.projections.org_iam_policies.state`+ - ` FROM zitadel.projections.org_iam_policies`), + regexp.QuoteMeta(`SELECT projections.org_iam_policies.id,`+ + ` projections.org_iam_policies.sequence,`+ + ` projections.org_iam_policies.creation_date,`+ + ` projections.org_iam_policies.change_date,`+ + ` projections.org_iam_policies.resource_owner,`+ + ` projections.org_iam_policies.user_login_must_be_domain,`+ + ` projections.org_iam_policies.is_default,`+ + ` projections.org_iam_policies.state`+ + ` FROM projections.org_iam_policies`), []string{ "id", "sequence", @@ -101,15 +101,15 @@ func Test_OrgIAMPolicyPrepares(t *testing.T) { prepare: prepareOrgIAMPolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.org_iam_policies.id,`+ - ` zitadel.projections.org_iam_policies.sequence,`+ - ` zitadel.projections.org_iam_policies.creation_date,`+ - ` zitadel.projections.org_iam_policies.change_date,`+ - ` zitadel.projections.org_iam_policies.resource_owner,`+ - ` zitadel.projections.org_iam_policies.user_login_must_be_domain,`+ - ` zitadel.projections.org_iam_policies.is_default,`+ - ` zitadel.projections.org_iam_policies.state`+ - ` FROM zitadel.projections.org_iam_policies`), + regexp.QuoteMeta(`SELECT projections.org_iam_policies.id,`+ + ` projections.org_iam_policies.sequence,`+ + ` projections.org_iam_policies.creation_date,`+ + ` projections.org_iam_policies.change_date,`+ + ` projections.org_iam_policies.resource_owner,`+ + ` projections.org_iam_policies.user_login_must_be_domain,`+ + ` projections.org_iam_policies.is_default,`+ + ` projections.org_iam_policies.state`+ + ` FROM projections.org_iam_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/org_member.go b/internal/query/org_member.go index 2803244e31..6c6794f8de 100644 --- a/internal/query/org_member.go +++ b/internal/query/org_member.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -40,6 +41,10 @@ var ( name: projection.MemberResourceOwner, table: orgMemberTable, } + OrgMemberInstanceID = Column{ + name: projection.MemberInstanceID, + table: orgMemberTable, + } OrgMemberOrgID = Column{ name: projection.OrgMemberOrgIDCol, table: orgMemberTable, @@ -59,7 +64,10 @@ func (q *OrgMembersQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder { func (q *Queries) OrgMembers(ctx context.Context, queries *OrgMembersQuery) (*Members, error) { query, scan := prepareOrgMembersQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + OrgMemberInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-PDAVB", "Errors.Query.InvalidRequest") } diff --git a/internal/query/org_member_test.go b/internal/query/org_member_test.go index 7fb61e2fac..e176774c31 100644 --- a/internal/query/org_member_test.go +++ b/internal/query/org_member_test.go @@ -19,22 +19,22 @@ var ( ", members.resource_owner" + ", members.user_id" + ", members.roles" + - ", zitadel.projections.login_names.login_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_machines.name" + - ", zitadel.projections.users_humans.avatar_key" + + ", projections.login_names.login_name" + + ", projections.users_humans.email" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.display_name" + + ", projections.users_machines.name" + + ", projections.users_humans.avatar_key" + ", COUNT(*) OVER () " + - "FROM zitadel.projections.org_members as members " + - "LEFT JOIN zitadel.projections.users_humans " + - "ON members.user_id = zitadel.projections.users_humans.user_id " + - "LEFT JOIN zitadel.projections.users_machines " + - "ON members.user_id = zitadel.projections.users_machines.user_id " + - "LEFT JOIN zitadel.projections.login_names " + - "ON members.user_id = zitadel.projections.login_names.user_id " + - "WHERE zitadel.projections.login_names.is_primary = $1") + "FROM projections.org_members as members " + + "LEFT JOIN projections.users_humans " + + "ON members.user_id = projections.users_humans.user_id " + + "LEFT JOIN projections.users_machines " + + "ON members.user_id = projections.users_machines.user_id " + + "LEFT JOIN projections.login_names " + + "ON members.user_id = projections.login_names.user_id " + + "WHERE projections.login_names.is_primary = $1") orgMembersColumns = []string{ "creation_date", "change_date", diff --git a/internal/query/org_test.go b/internal/query/org_test.go index e208e9a48a..51455545c0 100644 --- a/internal/query/org_test.go +++ b/internal/query/org_test.go @@ -28,16 +28,16 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain,`+ + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), nil, nil, ), @@ -49,16 +49,16 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain,`+ + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), []string{ "id", "creation_date", @@ -107,16 +107,16 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain,`+ + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), []string{ "id", "creation_date", @@ -185,16 +185,16 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain,`+ + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -211,15 +211,15 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain`+ - ` FROM zitadel.projections.orgs`), + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain`+ + ` FROM projections.orgs`), nil, nil, ), @@ -237,15 +237,15 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain`+ - ` FROM zitadel.projections.orgs`), + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain`+ + ` FROM projections.orgs`), []string{ "id", "creation_date", @@ -284,15 +284,15 @@ func Test_OrgPrepares(t *testing.T) { prepare: prepareOrgQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ - ` zitadel.projections.orgs.creation_date,`+ - ` zitadel.projections.orgs.change_date,`+ - ` zitadel.projections.orgs.resource_owner,`+ - ` zitadel.projections.orgs.org_state,`+ - ` zitadel.projections.orgs.sequence,`+ - ` zitadel.projections.orgs.name,`+ - ` zitadel.projections.orgs.primary_domain`+ - ` FROM zitadel.projections.orgs`), + regexp.QuoteMeta(`SELECT projections.orgs.id,`+ + ` projections.orgs.creation_date,`+ + ` projections.orgs.change_date,`+ + ` projections.orgs.resource_owner,`+ + ` projections.orgs.org_state,`+ + ` projections.orgs.sequence,`+ + ` projections.orgs.name,`+ + ` projections.orgs.primary_domain`+ + ` FROM projections.orgs`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -310,7 +310,7 @@ func Test_OrgPrepares(t *testing.T) { want: want{ sqlExpectations: mockQueries( regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), nil, nil, ), @@ -329,7 +329,7 @@ func Test_OrgPrepares(t *testing.T) { want: want{ sqlExpectations: mockQuery( regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), []string{ "count", }, @@ -346,7 +346,7 @@ func Test_OrgPrepares(t *testing.T) { want: want{ sqlExpectations: mockQueryErr( regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ - ` FROM zitadel.projections.orgs`), + ` FROM projections.orgs`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/password_age_policy.go b/internal/query/password_age_policy.go index c0acf97508..1658e68650 100644 --- a/internal/query/password_age_policy.go +++ b/internal/query/password_age_policy.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -50,6 +52,10 @@ var ( name: projection.AgePolicyResourceOwnerCol, table: passwordAgeTable, } + PasswordAgeColInstanceID = Column{ + name: projection.AgePolicyInstanceIDCol, + table: passwordAgeTable, + } PasswordAgeColWarnDays = Column{ name: projection.AgePolicyExpireWarnDaysCol, table: passwordAgeTable, @@ -71,12 +77,17 @@ var ( func (q *Queries) PasswordAgePolicyByOrg(ctx context.Context, orgID string) (*PasswordAgePolicy, error) { stmt, scan := preparePasswordAgePolicyQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - PasswordAgeColID.identifier(): orgID, + PasswordAgeColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - PasswordAgeColID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + PasswordAgeColID.identifier(): orgID, + }, + sq.Eq{ + PasswordAgeColID.identifier(): domain.IAMID, + }, }, }). OrderBy(PasswordAgeColIsDefault.identifier()). diff --git a/internal/query/password_age_policy_test.go b/internal/query/password_age_policy_test.go index d0dad615c3..acfbc5fbd1 100644 --- a/internal/query/password_age_policy_test.go +++ b/internal/query/password_age_policy_test.go @@ -28,16 +28,16 @@ func Test_PasswordAgePolicyPrepares(t *testing.T) { prepare: preparePasswordAgePolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.password_age_policies.id,`+ - ` zitadel.projections.password_age_policies.sequence,`+ - ` zitadel.projections.password_age_policies.creation_date,`+ - ` zitadel.projections.password_age_policies.change_date,`+ - ` zitadel.projections.password_age_policies.resource_owner,`+ - ` zitadel.projections.password_age_policies.expire_warn_days,`+ - ` zitadel.projections.password_age_policies.max_age_days,`+ - ` zitadel.projections.password_age_policies.is_default,`+ - ` zitadel.projections.password_age_policies.state`+ - ` FROM zitadel.projections.password_age_policies`), + regexp.QuoteMeta(`SELECT projections.password_age_policies.id,`+ + ` projections.password_age_policies.sequence,`+ + ` projections.password_age_policies.creation_date,`+ + ` projections.password_age_policies.change_date,`+ + ` projections.password_age_policies.resource_owner,`+ + ` projections.password_age_policies.expire_warn_days,`+ + ` projections.password_age_policies.max_age_days,`+ + ` projections.password_age_policies.is_default,`+ + ` projections.password_age_policies.state`+ + ` FROM projections.password_age_policies`), nil, nil, ), @@ -55,16 +55,16 @@ func Test_PasswordAgePolicyPrepares(t *testing.T) { prepare: preparePasswordAgePolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.password_age_policies.id,`+ - ` zitadel.projections.password_age_policies.sequence,`+ - ` zitadel.projections.password_age_policies.creation_date,`+ - ` zitadel.projections.password_age_policies.change_date,`+ - ` zitadel.projections.password_age_policies.resource_owner,`+ - ` zitadel.projections.password_age_policies.expire_warn_days,`+ - ` zitadel.projections.password_age_policies.max_age_days,`+ - ` zitadel.projections.password_age_policies.is_default,`+ - ` zitadel.projections.password_age_policies.state`+ - ` FROM zitadel.projections.password_age_policies`), + regexp.QuoteMeta(`SELECT projections.password_age_policies.id,`+ + ` projections.password_age_policies.sequence,`+ + ` projections.password_age_policies.creation_date,`+ + ` projections.password_age_policies.change_date,`+ + ` projections.password_age_policies.resource_owner,`+ + ` projections.password_age_policies.expire_warn_days,`+ + ` projections.password_age_policies.max_age_days,`+ + ` projections.password_age_policies.is_default,`+ + ` projections.password_age_policies.state`+ + ` FROM projections.password_age_policies`), []string{ "id", "sequence", @@ -106,16 +106,16 @@ func Test_PasswordAgePolicyPrepares(t *testing.T) { prepare: preparePasswordAgePolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.password_age_policies.id,`+ - ` zitadel.projections.password_age_policies.sequence,`+ - ` zitadel.projections.password_age_policies.creation_date,`+ - ` zitadel.projections.password_age_policies.change_date,`+ - ` zitadel.projections.password_age_policies.resource_owner,`+ - ` zitadel.projections.password_age_policies.expire_warn_days,`+ - ` zitadel.projections.password_age_policies.max_age_days,`+ - ` zitadel.projections.password_age_policies.is_default,`+ - ` zitadel.projections.password_age_policies.state`+ - ` FROM zitadel.projections.password_age_policies`), + regexp.QuoteMeta(`SELECT projections.password_age_policies.id,`+ + ` projections.password_age_policies.sequence,`+ + ` projections.password_age_policies.creation_date,`+ + ` projections.password_age_policies.change_date,`+ + ` projections.password_age_policies.resource_owner,`+ + ` projections.password_age_policies.expire_warn_days,`+ + ` projections.password_age_policies.max_age_days,`+ + ` projections.password_age_policies.is_default,`+ + ` projections.password_age_policies.state`+ + ` FROM projections.password_age_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/password_complexity_policy.go b/internal/query/password_complexity_policy.go index b3c1b0c48b..f2d4be0a08 100644 --- a/internal/query/password_complexity_policy.go +++ b/internal/query/password_complexity_policy.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -32,12 +34,17 @@ type PasswordComplexityPolicy struct { func (q *Queries) PasswordComplexityPolicyByOrg(ctx context.Context, orgID string) (*PasswordComplexityPolicy, error) { stmt, scan := preparePasswordComplexityPolicyQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - PasswordComplexityColID.identifier(): orgID, + PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - PasswordComplexityColID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + PasswordComplexityColID.identifier(): orgID, + }, + sq.Eq{ + PasswordComplexityColID.identifier(): domain.IAMID, + }, }, }). OrderBy(PasswordComplexityColIsDefault.identifier()). @@ -53,7 +60,8 @@ func (q *Queries) PasswordComplexityPolicyByOrg(ctx context.Context, orgID strin func (q *Queries) DefaultPasswordComplexityPolicy(ctx context.Context) (*PasswordComplexityPolicy, error) { stmt, scan := preparePasswordComplexityPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - PasswordComplexityColID.identifier(): domain.IAMID, + PasswordComplexityColID.identifier(): domain.IAMID, + PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(PasswordComplexityColIsDefault.identifier()). Limit(1).ToSql() @@ -89,6 +97,10 @@ var ( name: projection.ComplexityPolicyResourceOwnerCol, table: passwordComplexityTable, } + PasswordComplexityColInstanceID = Column{ + name: projection.ComplexityPolicyInstanceIDCol, + table: passwordComplexityTable, + } PasswordComplexityColMinLength = Column{ name: projection.ComplexityPolicyMinLengthCol, table: passwordComplexityTable, diff --git a/internal/query/password_complexity_policy_test.go b/internal/query/password_complexity_policy_test.go index 55ebfd1b94..552e913da8 100644 --- a/internal/query/password_complexity_policy_test.go +++ b/internal/query/password_complexity_policy_test.go @@ -28,19 +28,19 @@ func Test_PasswordComplexityPolicyPrepares(t *testing.T) { prepare: preparePasswordComplexityPolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.password_complexity_policies.id,`+ - ` zitadel.projections.password_complexity_policies.sequence,`+ - ` zitadel.projections.password_complexity_policies.creation_date,`+ - ` zitadel.projections.password_complexity_policies.change_date,`+ - ` zitadel.projections.password_complexity_policies.resource_owner,`+ - ` zitadel.projections.password_complexity_policies.min_length,`+ - ` zitadel.projections.password_complexity_policies.has_lowercase,`+ - ` zitadel.projections.password_complexity_policies.has_uppercase,`+ - ` zitadel.projections.password_complexity_policies.has_number,`+ - ` zitadel.projections.password_complexity_policies.has_symbol,`+ - ` zitadel.projections.password_complexity_policies.is_default,`+ - ` zitadel.projections.password_complexity_policies.state`+ - ` FROM zitadel.projections.password_complexity_policies`), + regexp.QuoteMeta(`SELECT projections.password_complexity_policies.id,`+ + ` projections.password_complexity_policies.sequence,`+ + ` projections.password_complexity_policies.creation_date,`+ + ` projections.password_complexity_policies.change_date,`+ + ` projections.password_complexity_policies.resource_owner,`+ + ` projections.password_complexity_policies.min_length,`+ + ` projections.password_complexity_policies.has_lowercase,`+ + ` projections.password_complexity_policies.has_uppercase,`+ + ` projections.password_complexity_policies.has_number,`+ + ` projections.password_complexity_policies.has_symbol,`+ + ` projections.password_complexity_policies.is_default,`+ + ` projections.password_complexity_policies.state`+ + ` FROM projections.password_complexity_policies`), nil, nil, ), @@ -58,19 +58,19 @@ func Test_PasswordComplexityPolicyPrepares(t *testing.T) { prepare: preparePasswordComplexityPolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.password_complexity_policies.id,`+ - ` zitadel.projections.password_complexity_policies.sequence,`+ - ` zitadel.projections.password_complexity_policies.creation_date,`+ - ` zitadel.projections.password_complexity_policies.change_date,`+ - ` zitadel.projections.password_complexity_policies.resource_owner,`+ - ` zitadel.projections.password_complexity_policies.min_length,`+ - ` zitadel.projections.password_complexity_policies.has_lowercase,`+ - ` zitadel.projections.password_complexity_policies.has_uppercase,`+ - ` zitadel.projections.password_complexity_policies.has_number,`+ - ` zitadel.projections.password_complexity_policies.has_symbol,`+ - ` zitadel.projections.password_complexity_policies.is_default,`+ - ` zitadel.projections.password_complexity_policies.state`+ - ` FROM zitadel.projections.password_complexity_policies`), + regexp.QuoteMeta(`SELECT projections.password_complexity_policies.id,`+ + ` projections.password_complexity_policies.sequence,`+ + ` projections.password_complexity_policies.creation_date,`+ + ` projections.password_complexity_policies.change_date,`+ + ` projections.password_complexity_policies.resource_owner,`+ + ` projections.password_complexity_policies.min_length,`+ + ` projections.password_complexity_policies.has_lowercase,`+ + ` projections.password_complexity_policies.has_uppercase,`+ + ` projections.password_complexity_policies.has_number,`+ + ` projections.password_complexity_policies.has_symbol,`+ + ` projections.password_complexity_policies.is_default,`+ + ` projections.password_complexity_policies.state`+ + ` FROM projections.password_complexity_policies`), []string{ "id", "sequence", @@ -121,19 +121,19 @@ func Test_PasswordComplexityPolicyPrepares(t *testing.T) { prepare: preparePasswordComplexityPolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.password_complexity_policies.id,`+ - ` zitadel.projections.password_complexity_policies.sequence,`+ - ` zitadel.projections.password_complexity_policies.creation_date,`+ - ` zitadel.projections.password_complexity_policies.change_date,`+ - ` zitadel.projections.password_complexity_policies.resource_owner,`+ - ` zitadel.projections.password_complexity_policies.min_length,`+ - ` zitadel.projections.password_complexity_policies.has_lowercase,`+ - ` zitadel.projections.password_complexity_policies.has_uppercase,`+ - ` zitadel.projections.password_complexity_policies.has_number,`+ - ` zitadel.projections.password_complexity_policies.has_symbol,`+ - ` zitadel.projections.password_complexity_policies.is_default,`+ - ` zitadel.projections.password_complexity_policies.state`+ - ` FROM zitadel.projections.password_complexity_policies`), + regexp.QuoteMeta(`SELECT projections.password_complexity_policies.id,`+ + ` projections.password_complexity_policies.sequence,`+ + ` projections.password_complexity_policies.creation_date,`+ + ` projections.password_complexity_policies.change_date,`+ + ` projections.password_complexity_policies.resource_owner,`+ + ` projections.password_complexity_policies.min_length,`+ + ` projections.password_complexity_policies.has_lowercase,`+ + ` projections.password_complexity_policies.has_uppercase,`+ + ` projections.password_complexity_policies.has_number,`+ + ` projections.password_complexity_policies.has_symbol,`+ + ` projections.password_complexity_policies.is_default,`+ + ` projections.password_complexity_policies.state`+ + ` FROM projections.password_complexity_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/privacy_policy.go b/internal/query/privacy_policy.go index 7c4c613a0f..98fe95d190 100644 --- a/internal/query/privacy_policy.go +++ b/internal/query/privacy_policy.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -50,6 +52,10 @@ var ( name: projection.PrivacyPolicyResourceOwnerCol, table: privacyTable, } + PrivacyColInstanceID = Column{ + name: projection.PrivacyPolicyInstanceIDCol, + table: privacyTable, + } PrivacyColPrivacyLink = Column{ name: projection.PrivacyPolicyPrivacyLinkCol, table: privacyTable, @@ -71,12 +77,17 @@ var ( func (q *Queries) PrivacyPolicyByOrg(ctx context.Context, orgID string) (*PrivacyPolicy, error) { stmt, scan := preparePrivacyPolicyQuery() query, args, err := stmt.Where( - sq.Or{ + sq.And{ sq.Eq{ - PrivacyColID.identifier(): orgID, + PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }, - sq.Eq{ - PrivacyColID.identifier(): domain.IAMID, + sq.Or{ + sq.Eq{ + PrivacyColID.identifier(): orgID, + }, + sq.Eq{ + PrivacyColID.identifier(): domain.IAMID, + }, }, }). OrderBy(PrivacyColIsDefault.identifier()). @@ -92,7 +103,8 @@ func (q *Queries) PrivacyPolicyByOrg(ctx context.Context, orgID string) (*Privac func (q *Queries) DefaultPrivacyPolicy(ctx context.Context) (*PrivacyPolicy, error) { stmt, scan := preparePrivacyPolicyQuery() query, args, err := stmt.Where(sq.Eq{ - PrivacyColID.identifier(): domain.IAMID, + PrivacyColID.identifier(): domain.IAMID, + PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).ID, }). OrderBy(PrivacyColIsDefault.identifier()). Limit(1).ToSql() diff --git a/internal/query/privacy_policy_test.go b/internal/query/privacy_policy_test.go index 0bbeaa052c..389ad4d46e 100644 --- a/internal/query/privacy_policy_test.go +++ b/internal/query/privacy_policy_test.go @@ -28,16 +28,16 @@ func Test_PrivacyPolicyPrepares(t *testing.T) { prepare: preparePrivacyPolicyQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.privacy_policies.id,`+ - ` zitadel.projections.privacy_policies.sequence,`+ - ` zitadel.projections.privacy_policies.creation_date,`+ - ` zitadel.projections.privacy_policies.change_date,`+ - ` zitadel.projections.privacy_policies.resource_owner,`+ - ` zitadel.projections.privacy_policies.privacy_link,`+ - ` zitadel.projections.privacy_policies.tos_link,`+ - ` zitadel.projections.privacy_policies.is_default,`+ - ` zitadel.projections.privacy_policies.state`+ - ` FROM zitadel.projections.privacy_policies`), + regexp.QuoteMeta(`SELECT projections.privacy_policies.id,`+ + ` projections.privacy_policies.sequence,`+ + ` projections.privacy_policies.creation_date,`+ + ` projections.privacy_policies.change_date,`+ + ` projections.privacy_policies.resource_owner,`+ + ` projections.privacy_policies.privacy_link,`+ + ` projections.privacy_policies.tos_link,`+ + ` projections.privacy_policies.is_default,`+ + ` projections.privacy_policies.state`+ + ` FROM projections.privacy_policies`), nil, nil, ), @@ -55,16 +55,16 @@ func Test_PrivacyPolicyPrepares(t *testing.T) { prepare: preparePrivacyPolicyQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.privacy_policies.id,`+ - ` zitadel.projections.privacy_policies.sequence,`+ - ` zitadel.projections.privacy_policies.creation_date,`+ - ` zitadel.projections.privacy_policies.change_date,`+ - ` zitadel.projections.privacy_policies.resource_owner,`+ - ` zitadel.projections.privacy_policies.privacy_link,`+ - ` zitadel.projections.privacy_policies.tos_link,`+ - ` zitadel.projections.privacy_policies.is_default,`+ - ` zitadel.projections.privacy_policies.state`+ - ` FROM zitadel.projections.privacy_policies`), + regexp.QuoteMeta(`SELECT projections.privacy_policies.id,`+ + ` projections.privacy_policies.sequence,`+ + ` projections.privacy_policies.creation_date,`+ + ` projections.privacy_policies.change_date,`+ + ` projections.privacy_policies.resource_owner,`+ + ` projections.privacy_policies.privacy_link,`+ + ` projections.privacy_policies.tos_link,`+ + ` projections.privacy_policies.is_default,`+ + ` projections.privacy_policies.state`+ + ` FROM projections.privacy_policies`), []string{ "id", "sequence", @@ -106,16 +106,16 @@ func Test_PrivacyPolicyPrepares(t *testing.T) { prepare: preparePrivacyPolicyQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.privacy_policies.id,`+ - ` zitadel.projections.privacy_policies.sequence,`+ - ` zitadel.projections.privacy_policies.creation_date,`+ - ` zitadel.projections.privacy_policies.change_date,`+ - ` zitadel.projections.privacy_policies.resource_owner,`+ - ` zitadel.projections.privacy_policies.privacy_link,`+ - ` zitadel.projections.privacy_policies.tos_link,`+ - ` zitadel.projections.privacy_policies.is_default,`+ - ` zitadel.projections.privacy_policies.state`+ - ` FROM zitadel.projections.privacy_policies`), + regexp.QuoteMeta(`SELECT projections.privacy_policies.id,`+ + ` projections.privacy_policies.sequence,`+ + ` projections.privacy_policies.creation_date,`+ + ` projections.privacy_policies.change_date,`+ + ` projections.privacy_policies.resource_owner,`+ + ` projections.privacy_policies.privacy_link,`+ + ` projections.privacy_policies.tos_link,`+ + ` projections.privacy_policies.is_default,`+ + ` projections.privacy_policies.state`+ + ` FROM projections.privacy_policies`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/project.go b/internal/query/project.go index b13448da32..910b7678f3 100644 --- a/internal/query/project.go +++ b/internal/query/project.go @@ -7,6 +7,7 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/query/projection" @@ -54,6 +55,10 @@ var ( name: projection.ProjectColumnResourceOwner, table: projectsTable, } + ProjectColumnInstanceID = Column{ + name: projection.ProjectColumnInstanceID, + table: projectsTable, + } ProjectColumnCreator = Column{ name: projection.ProjectColumnCreator, table: projectsTable, @@ -96,7 +101,8 @@ type ProjectSearchQueries struct { func (q *Queries) ProjectByID(ctx context.Context, id string) (*Project, error) { stmt, scan := prepareProjectQuery() query, args, err := stmt.Where(sq.Eq{ - ProjectColumnID.identifier(): id, + ProjectColumnID.identifier(): id, + ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-2m00Q", "Errors.Query.SQLStatment") @@ -113,7 +119,10 @@ func (q *Queries) ExistsProject(ctx context.Context, id string) (err error) { func (q *Queries) SearchProjects(ctx context.Context, queries *ProjectSearchQueries) (projects *Projects, err error) { query, scan := prepareProjectsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-fn9ew", "Errors.Query.InvalidRequest") } diff --git a/internal/query/project_grant.go b/internal/query/project_grant.go index 32225ef035..e21f1565ed 100644 --- a/internal/query/project_grant.go +++ b/internal/query/project_grant.go @@ -7,9 +7,10 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/query/projection" - "github.com/lib/pq" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -36,6 +37,10 @@ var ( name: projection.ProjectGrantColumnResourceOwner, table: projectGrantsTable, } + ProjectGrantColumnInstanceID = Column{ + name: projection.ProjectGrantColumnInstanceID, + table: projectGrantsTable, + } ProjectGrantColumnState = Column{ name: projection.ProjectGrantColumnState, table: projectGrantsTable, @@ -103,7 +108,8 @@ type ProjectGrantSearchQueries struct { func (q *Queries) ProjectGrantByID(ctx context.Context, id string) (*ProjectGrant, error) { stmt, scan := prepareProjectGrantQuery() query, args, err := stmt.Where(sq.Eq{ - ProjectGrantColumnGrantID.identifier(): id, + ProjectGrantColumnGrantID.identifier(): id, + ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Nf93d", "Errors.Query.SQLStatment") @@ -118,6 +124,7 @@ func (q *Queries) ProjectGrantByIDAndGrantedOrg(ctx context.Context, id, granted query, args, err := stmt.Where(sq.Eq{ ProjectGrantColumnGrantID.identifier(): id, ProjectGrantColumnGrantedOrgID.identifier(): grantedOrg, + ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-MO9fs", "Errors.Query.SQLStatment") @@ -134,7 +141,10 @@ func (q *Queries) ExistsProjectGrant(ctx context.Context, id string) (err error) func (q *Queries) SearchProjectGrants(ctx context.Context, queries *ProjectGrantSearchQueries) (projects *ProjectGrants, err error) { query, scan := prepareProjectGrantsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-N9fsg", "Errors.Query.InvalidRequest") } diff --git a/internal/query/project_grant_member.go b/internal/query/project_grant_member.go index 3cf1bd7cf3..154dffae23 100644 --- a/internal/query/project_grant_member.go +++ b/internal/query/project_grant_member.go @@ -7,6 +7,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -40,6 +42,10 @@ var ( name: projection.MemberResourceOwner, table: projectGrantMemberTable, } + ProjectGrantMemberInstanceID = Column{ + name: projection.MemberInstanceID, + table: projectGrantMemberTable, + } ProjectGrantMemberProjectID = Column{ name: projection.ProjectGrantMemberProjectIDCol, table: projectGrantMemberTable, @@ -66,7 +72,10 @@ func (q *ProjectGrantMembersQuery) toQuery(query sq.SelectBuilder) sq.SelectBuil func (q *Queries) ProjectGrantMembers(ctx context.Context, queries *ProjectGrantMembersQuery) (*Members, error) { query, scan := prepareProjectGrantMembersQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectGrantMemberInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-USNwM", "Errors.Query.InvalidRequest") } diff --git a/internal/query/project_grant_member_test.go b/internal/query/project_grant_member_test.go index d80e117e30..9e7e0102a1 100644 --- a/internal/query/project_grant_member_test.go +++ b/internal/query/project_grant_member_test.go @@ -19,22 +19,22 @@ var ( ", members.resource_owner" + ", members.user_id" + ", members.roles" + - ", zitadel.projections.login_names.login_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_machines.name" + - ", zitadel.projections.users_humans.avatar_key" + + ", projections.login_names.login_name" + + ", projections.users_humans.email" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.display_name" + + ", projections.users_machines.name" + + ", projections.users_humans.avatar_key" + ", COUNT(*) OVER () " + - "FROM zitadel.projections.project_grant_members as members " + - "LEFT JOIN zitadel.projections.users_humans " + - "ON members.user_id = zitadel.projections.users_humans.user_id " + - "LEFT JOIN zitadel.projections.users_machines " + - "ON members.user_id = zitadel.projections.users_machines.user_id " + - "LEFT JOIN zitadel.projections.login_names " + - "ON members.user_id = zitadel.projections.login_names.user_id " + - "WHERE zitadel.projections.login_names.is_primary = $1") + "FROM projections.project_grant_members as members " + + "LEFT JOIN projections.users_humans " + + "ON members.user_id = projections.users_humans.user_id " + + "LEFT JOIN projections.users_machines " + + "ON members.user_id = projections.users_machines.user_id " + + "LEFT JOIN projections.login_names " + + "ON members.user_id = projections.login_names.user_id " + + "WHERE projections.login_names.is_primary = $1") projectGrantMembersColumns = []string{ "creation_date", "change_date", diff --git a/internal/query/project_grant_test.go b/internal/query/project_grant_test.go index 6ed75fb992..22c4f35be6 100644 --- a/internal/query/project_grant_test.go +++ b/internal/query/project_grant_test.go @@ -8,9 +8,10 @@ import ( "regexp" "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" - "github.com/lib/pq" ) func Test_ProjectGrantPrepares(t *testing.T) { @@ -29,23 +30,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), nil, nil, ), @@ -57,23 +58,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.project_grants`+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id`+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants`+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id`+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -134,23 +135,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -211,23 +212,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -288,23 +289,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -365,23 +366,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -470,23 +471,23 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name,`+ ` COUNT(*) OVER () `+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -503,22 +504,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), nil, nil, ), @@ -536,22 +537,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -602,22 +603,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -668,22 +669,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -734,22 +735,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), []string{ "project_id", "grant_id", @@ -800,22 +801,22 @@ func Test_ProjectGrantPrepares(t *testing.T) { prepare: prepareProjectGrantQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(` SELECT zitadel.projections.project_grants.project_id,`+ - ` zitadel.projections.project_grants.grant_id,`+ - ` zitadel.projections.project_grants.creation_date,`+ - ` zitadel.projections.project_grants.change_date,`+ - ` zitadel.projections.project_grants.resource_owner,`+ - ` zitadel.projections.project_grants.state,`+ - ` zitadel.projections.project_grants.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.project_grants.granted_org_id,`+ + regexp.QuoteMeta(` SELECT projections.project_grants.project_id,`+ + ` projections.project_grants.grant_id,`+ + ` projections.project_grants.creation_date,`+ + ` projections.project_grants.change_date,`+ + ` projections.project_grants.resource_owner,`+ + ` projections.project_grants.state,`+ + ` projections.project_grants.sequence,`+ + ` projections.projects.name,`+ + ` projections.project_grants.granted_org_id,`+ ` o.name,`+ - ` zitadel.projections.project_grants.granted_role_keys,`+ + ` projections.project_grants.granted_role_keys,`+ ` r.name`+ - ` FROM zitadel.projections.project_grants `+ - ` LEFT JOIN zitadel.projections.projects ON zitadel.projections.project_grants.project_id = zitadel.projections.projects.id `+ - ` LEFT JOIN zitadel.projections.orgs as r ON zitadel.projections.project_grants.resource_owner = r.id`+ - ` LEFT JOIN zitadel.projections.orgs as o ON zitadel.projections.project_grants.granted_org_id = o.id`), + ` FROM projections.project_grants `+ + ` LEFT JOIN projections.projects ON projections.project_grants.project_id = projections.projects.id `+ + ` LEFT JOIN projections.orgs as r ON projections.project_grants.resource_owner = r.id`+ + ` LEFT JOIN projections.orgs as o ON projections.project_grants.granted_org_id = o.id`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/project_member.go b/internal/query/project_member.go index 9489f0f445..919508bb53 100644 --- a/internal/query/project_member.go +++ b/internal/query/project_member.go @@ -7,6 +7,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -40,6 +42,10 @@ var ( name: projection.MemberResourceOwner, table: projectMemberTable, } + ProjectMemberInstanceID = Column{ + name: projection.MemberInstanceID, + table: projectMemberTable, + } ProjectMemberProjectID = Column{ name: projection.ProjectMemberProjectIDCol, table: projectMemberTable, @@ -59,7 +65,10 @@ func (q *ProjectMembersQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder { func (q *Queries) ProjectMembers(ctx context.Context, queries *ProjectMembersQuery) (*Members, error) { query, scan := prepareProjectMembersQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectMemberInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-T8CuT", "Errors.Query.InvalidRequest") } diff --git a/internal/query/project_member_test.go b/internal/query/project_member_test.go index 3278ed761d..222153a100 100644 --- a/internal/query/project_member_test.go +++ b/internal/query/project_member_test.go @@ -19,22 +19,22 @@ var ( ", members.resource_owner" + ", members.user_id" + ", members.roles" + - ", zitadel.projections.login_names.login_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_machines.name" + - ", zitadel.projections.users_humans.avatar_key" + + ", projections.login_names.login_name" + + ", projections.users_humans.email" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.display_name" + + ", projections.users_machines.name" + + ", projections.users_humans.avatar_key" + ", COUNT(*) OVER () " + - "FROM zitadel.projections.project_members as members " + - "LEFT JOIN zitadel.projections.users_humans " + - "ON members.user_id = zitadel.projections.users_humans.user_id " + - "LEFT JOIN zitadel.projections.users_machines " + - "ON members.user_id = zitadel.projections.users_machines.user_id " + - "LEFT JOIN zitadel.projections.login_names " + - "ON members.user_id = zitadel.projections.login_names.user_id " + - "WHERE zitadel.projections.login_names.is_primary = $1") + "FROM projections.project_members as members " + + "LEFT JOIN projections.users_humans " + + "ON members.user_id = projections.users_humans.user_id " + + "LEFT JOIN projections.users_machines " + + "ON members.user_id = projections.users_machines.user_id " + + "LEFT JOIN projections.login_names " + + "ON members.user_id = projections.login_names.user_id " + + "WHERE projections.login_names.is_primary = $1") projectMembersColumns = []string{ "creation_date", "change_date", diff --git a/internal/query/project_role.go b/internal/query/project_role.go index e2ded091a8..3e6043699b 100644 --- a/internal/query/project_role.go +++ b/internal/query/project_role.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -27,6 +29,10 @@ var ( name: projection.ProjectRoleColumnResourceOwner, table: projectRolesTable, } + ProjectRoleColumnInstanceID = Column{ + name: projection.ProjectRoleColumnInstanceID, + table: projectRolesTable, + } ProjectRoleColumnSequence = Column{ name: projection.ProjectRoleColumnSequence, table: projectRolesTable, @@ -79,8 +85,9 @@ func (q *Queries) ProjectRoleByID(ctx context.Context, projectID, key string) (* stmt, scan := prepareProjectRoleQuery() query, args, err := stmt. Where(sq.Eq{ - ProjectRoleColumnProjectID.identifier(): projectID, - ProjectRoleColumnKey.identifier(): key, + ProjectRoleColumnProjectID.identifier(): projectID, + ProjectRoleColumnKey.identifier(): key, + ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-2N0fs", "Errors.Query.SQLStatment") @@ -97,7 +104,10 @@ func (q *Queries) ExistsProjectRole(ctx context.Context, projectID, key string) func (q *Queries) SearchProjectRoles(ctx context.Context, queries *ProjectRoleSearchQueries) (projects *ProjectRoles, err error) { query, scan := prepareProjectRolesQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-3N9ff", "Errors.Query.InvalidRequest") } @@ -124,7 +134,10 @@ func (q *Queries) SearchGrantedProjectRoles(ctx context.Context, grantID, grante return nil, err } query, scan := prepareProjectRolesQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-3N9ff", "Errors.Query.InvalidRequest") } diff --git a/internal/query/project_role_test.go b/internal/query/project_role_test.go index 18ee4ae152..22fe0f04d1 100644 --- a/internal/query/project_role_test.go +++ b/internal/query/project_role_test.go @@ -27,16 +27,16 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRolesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name,`+ + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.project_roles`), + ` FROM projections.project_roles`), nil, nil, ), @@ -48,16 +48,16 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRolesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name,`+ + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.project_roles`), + ` FROM projections.project_roles`), []string{ "project_id", "creation_date", @@ -106,16 +106,16 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRolesQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name,`+ + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.project_roles`), + ` FROM projections.project_roles`), []string{ "project_id", "creation_date", @@ -184,16 +184,16 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRolesQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name,`+ + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.project_roles`), + ` FROM projections.project_roles`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -210,15 +210,15 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRoleQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name`+ - ` FROM zitadel.projections.project_roles`), + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name`+ + ` FROM projections.project_roles`), nil, nil, ), @@ -236,15 +236,15 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRoleQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name`+ - ` FROM zitadel.projections.project_roles`), + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name`+ + ` FROM projections.project_roles`), []string{ "project_id", "creation_date", @@ -283,15 +283,15 @@ func Test_ProjectRolePrepares(t *testing.T) { prepare: prepareProjectRoleQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.project_roles.project_id,`+ - ` zitadel.projections.project_roles.creation_date,`+ - ` zitadel.projections.project_roles.change_date,`+ - ` zitadel.projections.project_roles.resource_owner,`+ - ` zitadel.projections.project_roles.sequence,`+ - ` zitadel.projections.project_roles.role_key,`+ - ` zitadel.projections.project_roles.display_name,`+ - ` zitadel.projections.project_roles.group_name`+ - ` FROM zitadel.projections.project_roles`), + regexp.QuoteMeta(`SELECT projections.project_roles.project_id,`+ + ` projections.project_roles.creation_date,`+ + ` projections.project_roles.change_date,`+ + ` projections.project_roles.resource_owner,`+ + ` projections.project_roles.sequence,`+ + ` projections.project_roles.role_key,`+ + ` projections.project_roles.display_name,`+ + ` projections.project_roles.group_name`+ + ` FROM projections.project_roles`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/project_test.go b/internal/query/project_test.go index f7ef3a5e98..6c3d52cac7 100644 --- a/internal/query/project_test.go +++ b/internal/query/project_test.go @@ -44,19 +44,19 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting,`+ + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.projects`), + ` FROM projections.projects`), nil, nil, ), @@ -68,19 +68,19 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting,`+ + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.projects`), + ` FROM projections.projects`), []string{ "id", "creation_date", @@ -138,19 +138,19 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting,`+ + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.projects`), + ` FROM projections.projects`), []string{ "id", "creation_date", @@ -234,19 +234,19 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting,`+ + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.projects`), + ` FROM projections.projects`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -263,18 +263,18 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectQuery, want: want{ sqlExpectations: mockQueries( - `SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting`+ - ` FROM zitadel.projections.projects`, + `SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting`+ + ` FROM projections.projects`, nil, nil, ), @@ -292,18 +292,18 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting`+ - ` FROM zitadel.projections.projects`), + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting`+ + ` FROM projections.projects`), []string{ "id", "creation_date", @@ -351,18 +351,18 @@ func Test_ProjectPrepares(t *testing.T) { prepare: prepareProjectQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.projects.id,`+ - ` zitadel.projections.projects.creation_date,`+ - ` zitadel.projections.projects.change_date,`+ - ` zitadel.projections.projects.resource_owner,`+ - ` zitadel.projections.projects.state,`+ - ` zitadel.projections.projects.sequence,`+ - ` zitadel.projections.projects.name,`+ - ` zitadel.projections.projects.project_role_assertion,`+ - ` zitadel.projections.projects.project_role_check,`+ - ` zitadel.projections.projects.has_project_check,`+ - ` zitadel.projections.projects.private_labeling_setting`+ - ` FROM zitadel.projections.projects`), + regexp.QuoteMeta(`SELECT projections.projects.id,`+ + ` projections.projects.creation_date,`+ + ` projections.projects.change_date,`+ + ` projections.projects.resource_owner,`+ + ` projections.projects.state,`+ + ` projections.projects.sequence,`+ + ` projections.projects.name,`+ + ` projections.projects.project_role_assertion,`+ + ` projections.projects.project_role_check,`+ + ` projections.projects.has_project_check,`+ + ` projections.projects.private_labeling_setting`+ + ` FROM projections.projects`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/projection/action.go b/internal/query/projection/action.go index 923e0cf105..05e8cca3ab 100644 --- a/internal/query/projection/action.go +++ b/internal/query/projection/action.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,11 +12,12 @@ import ( ) const ( - ActionTable = "zitadel.projections.actions" + ActionTable = "projections.actions" ActionIDCol = "id" ActionCreationDateCol = "creation_date" ActionChangeDateCol = "change_date" ActionResourceOwnerCol = "resource_owner" + ActionInstanceIDCol = "instance_id" ActionStateCol = "action_state" ActionSequenceCol = "sequence" ActionNameCol = "name" @@ -35,6 +34,24 @@ func NewActionProjection(ctx context.Context, config crdb.StatementHandlerConfig p := new(ActionProjection) config.ProjectionName = ActionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(ActionIDCol, crdb.ColumnTypeText), + crdb.NewColumn(ActionCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ActionChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ActionResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(ActionInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(ActionStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(ActionSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(ActionNameCol, crdb.ColumnTypeText), + crdb.NewColumn(ActionScriptCol, crdb.ColumnTypeText, crdb.Default("")), + crdb.NewColumn(ActionTimeoutCol, crdb.ColumnTypeInt64, crdb.Default(0)), + crdb.NewColumn(ActionAllowedToFailCol, crdb.ColumnTypeBool, crdb.Default(false)), + }, + crdb.NewPrimaryKey(ActionInstanceIDCol, ActionIDCol), + crdb.NewIndex("ro_idx", []string{ActionResourceOwnerCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -72,8 +89,7 @@ func (p *ActionProjection) reducers() []handler.AggregateReducer { func (p *ActionProjection) reduceActionAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*action.AddedEvent) if !ok { - logging.LogWithFields("HANDL-Sgg31", "seq", event.Sequence, "expectedType", action.AddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dff21", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dff21", "reduce.wrong.event.type% s", action.AddedEventType) } return crdb.NewCreateStatement( e, @@ -82,6 +98,7 @@ func (p *ActionProjection) reduceActionAdded(event eventstore.Event) (*handler.S handler.NewCol(ActionCreationDateCol, e.CreationDate()), handler.NewCol(ActionChangeDateCol, e.CreationDate()), handler.NewCol(ActionResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(ActionInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(ActionSequenceCol, e.Sequence()), handler.NewCol(ActionNameCol, e.Name), handler.NewCol(ActionScriptCol, e.Script), @@ -95,8 +112,7 @@ func (p *ActionProjection) reduceActionAdded(event eventstore.Event) (*handler.S func (p *ActionProjection) reduceActionChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*action.ChangedEvent) if !ok { - logging.LogWithFields("HANDL-Dg2th", "seq", event.Sequence, "expected", action.ChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Gg43d", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Gg43d", "reduce.wrong.event.type %s", action.ChangedEventType) } values := []handler.Column{ handler.NewCol(ActionChangeDateCol, e.CreationDate()), @@ -126,8 +142,7 @@ func (p *ActionProjection) reduceActionChanged(event eventstore.Event) (*handler func (p *ActionProjection) reduceActionDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*action.DeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-Fhhjd", "seq", event.Sequence, "expectedType", action.DeactivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Fgh32", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Fgh32", "reduce.wrong.event.type %s", action.DeactivatedEventType) } return crdb.NewUpdateStatement( e, @@ -145,8 +160,7 @@ func (p *ActionProjection) reduceActionDeactivated(event eventstore.Event) (*han func (p *ActionProjection) reduceActionReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*action.ReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-Fg4r3", "seq", event.Sequence, "expectedType", action.ReactivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-hwdqa", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-hwdqa", "reduce.wrong.event.type% s", action.ReactivatedEventType) } return crdb.NewUpdateStatement( e, @@ -164,8 +178,7 @@ func (p *ActionProjection) reduceActionReactivated(event eventstore.Event) (*han func (p *ActionProjection) reduceActionRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*action.RemovedEvent) if !ok { - logging.LogWithFields("HANDL-Dgwh2", "seq", event.Sequence, "expectedType", action.RemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dgh2d", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dgh2d", "reduce.wrong.event.type% s", action.RemovedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/action_test.go b/internal/query/projection/action_test.go index 7fbc646982..96160068da 100644 --- a/internal/query/projection/action_test.go +++ b/internal/query/projection/action_test.go @@ -40,12 +40,13 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.actions (id, creation_date, change_date, resource_owner, sequence, name, script, timeout, allowed_to_fail, action_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.actions (id, creation_date, change_date, resource_owner, instance_id, sequence, name, script, timeout, allowed_to_fail, action_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "name", "name(){}", @@ -76,7 +77,7 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.actions SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.actions SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -107,7 +108,7 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -137,7 +138,7 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.actions SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -167,7 +168,7 @@ func TestActionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.actions WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.actions WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/app.go b/internal/query/projection/app.go index 7e82b2100a..cf8bb6f07e 100644 --- a/internal/query/projection/app.go +++ b/internal/query/projection/app.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/lib/pq" "github.com/caos/zitadel/internal/domain" @@ -14,20 +13,104 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + AppProjectionTable = "projections.apps" + AppAPITable = AppProjectionTable + "_" + appAPITableSuffix + AppOIDCTable = AppProjectionTable + "_" + appOIDCTableSuffix + + AppColumnID = "id" + AppColumnName = "name" + AppColumnProjectID = "project_id" + AppColumnCreationDate = "creation_date" + AppColumnChangeDate = "change_date" + AppColumnResourceOwner = "resource_owner" + AppColumnInstanceID = "instance_id" + AppColumnState = "state" + AppColumnSequence = "sequence" + + appAPITableSuffix = "api_configs" + AppAPIConfigColumnAppID = "app_id" + AppAPIConfigColumnClientID = "client_id" + AppAPIConfigColumnClientSecret = "client_secret" + AppAPIConfigColumnAuthMethod = "auth_method" + + appOIDCTableSuffix = "oidc_configs" + AppOIDCConfigColumnAppID = "app_id" + AppOIDCConfigColumnVersion = "version" + AppOIDCConfigColumnClientID = "client_id" + AppOIDCConfigColumnClientSecret = "client_secret" + AppOIDCConfigColumnRedirectUris = "redirect_uris" + AppOIDCConfigColumnResponseTypes = "response_types" + AppOIDCConfigColumnGrantTypes = "grant_types" + AppOIDCConfigColumnApplicationType = "application_type" + AppOIDCConfigColumnAuthMethodType = "auth_method_type" + AppOIDCConfigColumnPostLogoutRedirectUris = "post_logout_redirect_uris" + AppOIDCConfigColumnDevMode = "is_dev_mode" + AppOIDCConfigColumnAccessTokenType = "access_token_type" + AppOIDCConfigColumnAccessTokenRoleAssertion = "access_token_role_assertion" + AppOIDCConfigColumnIDTokenRoleAssertion = "id_token_role_assertion" + AppOIDCConfigColumnIDTokenUserinfoAssertion = "id_token_userinfo_assertion" + AppOIDCConfigColumnClockSkew = "clock_skew" + AppOIDCConfigColumnAdditionalOrigins = "additional_origins" +) + type AppProjection struct { crdb.StatementHandler } -const ( - AppProjectionTable = "zitadel.projections.apps" - AppAPITable = AppProjectionTable + "_" + appAPITableSuffix - AppOIDCTable = AppProjectionTable + "_" + appOIDCTableSuffix -) - func NewAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *AppProjection { p := new(AppProjection) config.ProjectionName = AppProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(AppColumnID, crdb.ColumnTypeText), + crdb.NewColumn(AppColumnName, crdb.ColumnTypeText), + crdb.NewColumn(AppColumnProjectID, crdb.ColumnTypeText), + crdb.NewColumn(AppColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AppColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AppColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(AppColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(AppColumnState, crdb.ColumnTypeEnum), + crdb.NewColumn(AppColumnSequence, crdb.ColumnTypeInt64), + }, + crdb.NewPrimaryKey(AppColumnInstanceID, ActionIDCol), + crdb.NewIndex("project_id_idx", []string{AppColumnProjectID}), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(AppAPIConfigColumnAppID, crdb.ColumnTypeText, crdb.DeleteCascade(AppColumnID)), + crdb.NewColumn(AppAPIConfigColumnClientID, crdb.ColumnTypeText), + crdb.NewColumn(AppAPIConfigColumnClientSecret, crdb.ColumnTypeJSONB, crdb.Nullable()), + crdb.NewColumn(AppAPIConfigColumnAuthMethod, crdb.ColumnTypeEnum), + }, + crdb.NewPrimaryKey(AppAPIConfigColumnAppID), + appAPITableSuffix, + crdb.NewIndex("client_id_idx", []string{AppAPIConfigColumnClientID}), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(AppOIDCConfigColumnAppID, crdb.ColumnTypeText, crdb.DeleteCascade(AppColumnID)), + crdb.NewColumn(AppOIDCConfigColumnVersion, crdb.ColumnTypeText), + crdb.NewColumn(AppOIDCConfigColumnClientID, crdb.ColumnTypeText), + crdb.NewColumn(AppOIDCConfigColumnClientSecret, crdb.ColumnTypeJSONB, crdb.Nullable()), + crdb.NewColumn(AppOIDCConfigColumnRedirectUris, crdb.ColumnTypeTextArray, crdb.Nullable()), + crdb.NewColumn(AppOIDCConfigColumnResponseTypes, crdb.ColumnTypeEnumArray, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnGrantTypes, crdb.ColumnTypeEnumArray, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnApplicationType, crdb.ColumnTypeEnum), + crdb.NewColumn(AppOIDCConfigColumnAuthMethodType, crdb.ColumnTypeEnum), + crdb.NewColumn(AppOIDCConfigColumnPostLogoutRedirectUris, crdb.ColumnTypeTextArray, crdb.Nullable()), + crdb.NewColumn(AppOIDCConfigColumnDevMode, crdb.ColumnTypeBool), + crdb.NewColumn(AppOIDCConfigColumnAccessTokenType, crdb.ColumnTypeEnum), + crdb.NewColumn(AppOIDCConfigColumnAccessTokenRoleAssertion, crdb.ColumnTypeBool, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnIDTokenRoleAssertion, crdb.ColumnTypeBool, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnIDTokenUserinfoAssertion, crdb.ColumnTypeBool, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnClockSkew, crdb.ColumnTypeInt64, crdb.Nullable()), //TODO: null? + crdb.NewColumn(AppOIDCConfigColumnAdditionalOrigins, crdb.ColumnTypeTextArray, crdb.Nullable()), + }, + crdb.NewPrimaryKey(AppOIDCConfigColumnAppID), + appOIDCTableSuffix, + crdb.NewIndex("client_id_idx", []string{AppOIDCConfigColumnClientID}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -90,47 +173,10 @@ func (p *AppProjection) reducers() []handler.AggregateReducer { } } -const ( - AppColumnID = "id" - AppColumnName = "name" - AppColumnProjectID = "project_id" - AppColumnCreationDate = "creation_date" - AppColumnChangeDate = "change_date" - AppColumnResourceOwner = "resource_owner" - AppColumnState = "state" - AppColumnSequence = "sequence" - - appAPITableSuffix = "api_configs" - AppAPIConfigColumnAppID = "app_id" - AppAPIConfigColumnClientID = "client_id" - AppAPIConfigColumnClientSecret = "client_secret" - AppAPIConfigColumnAuthMethod = "auth_method" - - appOIDCTableSuffix = "oidc_configs" - AppOIDCConfigColumnAppID = "app_id" - AppOIDCConfigColumnVersion = "version" - AppOIDCConfigColumnClientID = "client_id" - AppOIDCConfigColumnClientSecret = "client_secret" - AppOIDCConfigColumnRedirectUris = "redirect_uris" - AppOIDCConfigColumnResponseTypes = "response_types" - AppOIDCConfigColumnGrantTypes = "grant_types" - AppOIDCConfigColumnApplicationType = "application_type" - AppOIDCConfigColumnAuthMethodType = "auth_method_type" - AppOIDCConfigColumnPostLogoutRedirectUris = "post_logout_redirect_uris" - AppOIDCConfigColumnDevMode = "is_dev_mode" - AppOIDCConfigColumnAccessTokenType = "access_token_type" - AppOIDCConfigColumnAccessTokenRoleAssertion = "access_token_role_assertion" - AppOIDCConfigColumnIDTokenRoleAssertion = "id_token_role_assertion" - AppOIDCConfigColumnIDTokenUserinfoAssertion = "id_token_userinfo_assertion" - AppOIDCConfigColumnClockSkew = "clock_skew" - AppOIDCConfigColumnAdditionalOrigins = "additional_origins" -) - func (p *AppProjection) reduceAppAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ApplicationAddedEvent) if !ok { - logging.LogWithFields("HANDL-OzK4m", "seq", event.Sequence(), "expectedType", project.ApplicationAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-1xYE6", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-1xYE6", "reduce.wrong.event.type %s", project.ApplicationAddedType) } return crdb.NewCreateStatement( e, @@ -141,6 +187,7 @@ func (p *AppProjection) reduceAppAdded(event eventstore.Event) (*handler.Stateme handler.NewCol(AppColumnCreationDate, e.CreationDate()), handler.NewCol(AppColumnChangeDate, e.CreationDate()), handler.NewCol(AppColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(AppColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(AppColumnState, domain.AppStateActive), handler.NewCol(AppColumnSequence, e.Sequence()), }, @@ -150,8 +197,7 @@ func (p *AppProjection) reduceAppAdded(event eventstore.Event) (*handler.Stateme func (p *AppProjection) reduceAppChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ApplicationChangedEvent) if !ok { - logging.LogWithFields("HANDL-4Fjh2", "seq", event.Sequence(), "expectedType", project.ApplicationChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ZJ8JA", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ZJ8JA", "reduce.wrong.event.type %s", project.ApplicationChangedType) } if e.Name == "" { return crdb.NewNoOpStatement(event), nil @@ -172,8 +218,7 @@ func (p *AppProjection) reduceAppChanged(event eventstore.Event) (*handler.State func (p *AppProjection) reduceAppDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ApplicationDeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-hZ9to", "seq", event.Sequence(), "expectedType", project.ApplicationDeactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-MVWxZ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-MVWxZ", "reduce.wrong.event.type %s", project.ApplicationDeactivatedType) } return crdb.NewUpdateStatement( e, @@ -191,8 +236,7 @@ func (p *AppProjection) reduceAppDeactivated(event eventstore.Event) (*handler.S func (p *AppProjection) reduceAppReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ApplicationReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-AbK3B", "seq", event.Sequence(), "expectedType", project.ApplicationReactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-D0HZO", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-D0HZO", "reduce.wrong.event.type %s", project.ApplicationReactivatedType) } return crdb.NewUpdateStatement( e, @@ -210,8 +254,7 @@ func (p *AppProjection) reduceAppReactivated(event eventstore.Event) (*handler.S func (p *AppProjection) reduceAppRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ApplicationRemovedEvent) if !ok { - logging.LogWithFields("HANDL-tdRId", "seq", event.Sequence(), "expectedType", project.ApplicationRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Y99aq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Y99aq", "reduce.wrong.event.type %s", project.ApplicationRemovedType) } return crdb.NewDeleteStatement( e, @@ -224,8 +267,7 @@ func (p *AppProjection) reduceAppRemoved(event eventstore.Event) (*handler.State func (p *AppProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-ZxQnj", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-DlUlO", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-DlUlO", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return crdb.NewDeleteStatement( e, @@ -238,8 +280,7 @@ func (p *AppProjection) reduceProjectRemoved(event eventstore.Event) (*handler.S func (p *AppProjection) reduceAPIConfigAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.APIConfigAddedEvent) if !ok { - logging.LogWithFields("HANDL-tdRId", "seq", event.Sequence(), "expectedType", project.APIConfigAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Y99aq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Y99aq", "reduce.wrong.event.type %s", project.APIConfigAddedType) } return crdb.NewMultiStatement( e, @@ -267,8 +308,7 @@ func (p *AppProjection) reduceAPIConfigAdded(event eventstore.Event) (*handler.S func (p *AppProjection) reduceAPIConfigChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.APIConfigChangedEvent) if !ok { - logging.LogWithFields("HANDL-C6b4f", "seq", event.Sequence(), "expectedType", project.APIConfigChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-vnZKi", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-vnZKi", "reduce.wrong.event.type %s", project.APIConfigChangedType) } cols := make([]handler.Column, 0, 2) if e.ClientSecret != nil { @@ -304,8 +344,7 @@ func (p *AppProjection) reduceAPIConfigChanged(event eventstore.Event) (*handler func (p *AppProjection) reduceAPIConfigSecretChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.APIConfigSecretChangedEvent) if !ok { - logging.LogWithFields("HANDL-dssSI", "seq", event.Sequence(), "expectedType", project.APIConfigSecretChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ttb0I", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ttb0I", "reduce.wrong.event.type %s", project.APIConfigSecretChangedType) } return crdb.NewMultiStatement( e, @@ -333,8 +372,7 @@ func (p *AppProjection) reduceAPIConfigSecretChanged(event eventstore.Event) (*h func (p *AppProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.OIDCConfigAddedEvent) if !ok { - logging.LogWithFields("HANDL-nlDQv", "seq", event.Sequence(), "expectedType", project.OIDCConfigAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-GNHU1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-GNHU1", "reduce.wrong.event.type %s", project.OIDCConfigAddedType) } return crdb.NewMultiStatement( e, @@ -375,8 +413,7 @@ func (p *AppProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler. func (p *AppProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.OIDCConfigChangedEvent) if !ok { - logging.LogWithFields("HANDL-nlDQv", "seq", event.Sequence(), "expectedType", project.OIDCConfigChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-GNHU1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-GNHU1", "reduce.wrong.event.type %s", project.OIDCConfigChangedType) } cols := make([]handler.Column, 0, 15) @@ -451,8 +488,7 @@ func (p *AppProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle func (p *AppProjection) reduceOIDCConfigSecretChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.OIDCConfigSecretChangedEvent) if !ok { - logging.LogWithFields("HANDL-nlDQv", "seq", event.Sequence(), "expectedType", project.OIDCConfigSecretChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-GNHU1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-GNHU1", "reduce.wrong.event.type %s", project.OIDCConfigSecretChangedType) } return crdb.NewMultiStatement( e, diff --git a/internal/query/projection/app_test.go b/internal/query/projection/app_test.go index 217717ab4b..8e88df5652 100644 --- a/internal/query/projection/app_test.go +++ b/internal/query/projection/app_test.go @@ -4,13 +4,14 @@ import ( "testing" "time" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/repository/project" - "github.com/lib/pq" ) func TestAppProjection_reduces(t *testing.T) { @@ -44,7 +45,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.apps (id, name, project_id, creation_date, change_date, resource_owner, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.apps (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "app-id", "my-app", @@ -52,6 +53,7 @@ func TestAppProjection_reduces(t *testing.T) { anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.AppStateActive, uint64(15), }, @@ -81,7 +83,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.apps SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ "my-app", anyArg{}, @@ -113,7 +115,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.AppStateInactive, anyArg{}, @@ -145,7 +147,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.apps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.AppStateActive, anyArg{}, @@ -177,7 +179,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.apps WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.apps WHERE (id = $1)", expectedArgs: []interface{}{ "app-id", }, @@ -204,7 +206,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.apps WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.apps WHERE (project_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -236,7 +238,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.apps_api_configs (app_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4)", + expectedStmt: "INSERT INTO projections.apps_api_configs (app_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ "app-id", "client-id", @@ -245,7 +247,7 @@ func TestAppProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -279,7 +281,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3)", + expectedStmt: "UPDATE projections.apps_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3)", expectedArgs: []interface{}{ anyArg{}, domain.APIAuthMethodTypePrivateKeyJWT, @@ -287,7 +289,7 @@ func TestAppProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -341,14 +343,14 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps_api_configs SET (client_secret) = ($1) WHERE (app_id = $2)", + expectedStmt: "UPDATE projections.apps_api_configs SET (client_secret) = ($1) WHERE (app_id = $2)", expectedArgs: []interface{}{ anyArg{}, "app-id", }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -395,7 +397,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.apps_oidc_configs (app_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)", + expectedStmt: "INSERT INTO projections.apps_oidc_configs (app_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)", expectedArgs: []interface{}{ "app-id", domain.OIDCVersionV1, @@ -417,7 +419,7 @@ func TestAppProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -462,7 +464,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE (app_id = $15)", + expectedStmt: "UPDATE projections.apps_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE (app_id = $15)", expectedArgs: []interface{}{ domain.OIDCVersionV1, pq.StringArray{"redirect.one.ch", "redirect.two.ch"}, @@ -482,7 +484,7 @@ func TestAppProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -536,14 +538,14 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.apps_oidc_configs SET (client_secret) = ($1) WHERE (app_id = $2)", + expectedStmt: "UPDATE projections.apps_oidc_configs SET (client_secret) = ($1) WHERE (app_id = $2)", expectedArgs: []interface{}{ anyArg{}, "app-id", }, }, { - expectedStmt: "UPDATE zitadel.projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.apps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/authn_key.go b/internal/query/projection/authn_key.go index 27c090f452..9864b0f4b7 100644 --- a/internal/query/projection/authn_key.go +++ b/internal/query/projection/authn_key.go @@ -4,8 +4,6 @@ import ( "context" "time" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -16,10 +14,11 @@ import ( ) const ( - AuthNKeyTable = "zitadel.projections.authn_keys" + AuthNKeyTable = "projections.authn_keys" AuthNKeyIDCol = "id" AuthNKeyCreationDateCol = "creation_date" AuthNKeyResourceOwnerCol = "resource_owner" + AuthNKeyInstanceIDCol = "instance_id" AuthNKeyAggregateIDCol = "aggregate_id" AuthNKeySequenceCol = "sequence" AuthNKeyObjectIDCol = "object_id" @@ -38,6 +37,26 @@ func NewAuthNKeyProjection(ctx context.Context, config crdb.StatementHandlerConf p := new(AuthNKeyProjection) config.ProjectionName = AuthNKeyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(AuthNKeyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AuthNKeyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeyAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(AuthNKeyObjectIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeyExpirationCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AuthNKeyIdentifierCol, crdb.ColumnTypeText), + crdb.NewColumn(AuthNKeyPublicKeyCol, crdb.ColumnTypeBytes), + crdb.NewColumn(AuthNKeyEnabledCol, crdb.ColumnTypeBool, crdb.Default(true)), + crdb.NewColumn(AuthNKeyTypeCol, crdb.ColumnTypeEnum, crdb.Default(0)), + }, + crdb.NewPrimaryKey(AuthNKeyInstanceIDCol, AuthNKeyIDCol), + crdb.NewIndex("enabled_idx", []string{AuthNKeyEnabledCol}), + crdb.NewIndex("identifier_idx", []string{AuthNKeyIdentifierCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -121,8 +140,7 @@ func (p *AuthNKeyProjection) reduceAuthNKeyAdded(event eventstore.Event) (*handl authNKeyEvent.publicKey = e.PublicKey authNKeyEvent.keyType = e.KeyType default: - logging.LogWithFields("PROJE-Dbr3g", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{project.ApplicationKeyAddedEventType, user.MachineKeyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Dgb32", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Dgb32", "reduce.wrong.event.type %v", []eventstore.EventType{project.ApplicationKeyAddedEventType, user.MachineKeyAddedEventType}) } return crdb.NewMultiStatement( &authNKeyEvent, @@ -131,6 +149,7 @@ func (p *AuthNKeyProjection) reduceAuthNKeyAdded(event eventstore.Event) (*handl handler.NewCol(AuthNKeyIDCol, authNKeyEvent.keyID), handler.NewCol(AuthNKeyCreationDateCol, authNKeyEvent.CreationDate()), handler.NewCol(AuthNKeyResourceOwnerCol, authNKeyEvent.Aggregate().ResourceOwner), + handler.NewCol(AuthNKeyInstanceIDCol, authNKeyEvent.Aggregate().InstanceID), handler.NewCol(AuthNKeyAggregateIDCol, authNKeyEvent.Aggregate().ID), handler.NewCol(AuthNKeySequenceCol, authNKeyEvent.Sequence()), handler.NewCol(AuthNKeyObjectIDCol, authNKeyEvent.objectID), @@ -160,8 +179,7 @@ func (p *AuthNKeyProjection) reduceAuthNKeyEnabledChanged(event eventstore.Event appID = e.AppID enabled = *e.AuthMethodType == domain.OIDCAuthMethodTypePrivateKeyJWT default: - logging.LogWithFields("PROJE-Db5u3", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{project.APIConfigChangedType, project.OIDCConfigChangedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Dbrt1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Dbrt1", "reduce.wrong.event.type %v", []eventstore.EventType{project.APIConfigChangedType, project.OIDCConfigChangedType}) } return crdb.NewUpdateStatement( event, @@ -184,9 +202,7 @@ func (p *AuthNKeyProjection) reduceAuthNKeyRemoved(event eventstore.Event) (*han case *user.UserRemovedEvent: condition = handler.NewCond(AuthNKeyAggregateIDCol, e.Aggregate().ID) default: - logging.LogWithFields("PROJE-Sfdg3", "seq", event.Sequence(), "expectedTypes", - []eventstore.EventType{project.ApplicationKeyRemovedEventType, project.ApplicationRemovedType, project.ProjectRemovedType, user.MachineKeyRemovedEventType, user.UserRemovedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-BGge42", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-BGge42", "reduce.wrong.event.type %v", []eventstore.EventType{project.ApplicationKeyRemovedEventType, project.ApplicationRemovedType, project.ProjectRemovedType, user.MachineKeyRemovedEventType, user.UserRemovedType}) } return crdb.NewDeleteStatement( event, diff --git a/internal/query/projection/authn_key_test.go b/internal/query/projection/authn_key_test.go index 24f1e84e4a..a3f69823bf 100644 --- a/internal/query/projection/authn_key_test.go +++ b/internal/query/projection/authn_key_test.go @@ -40,11 +40,12 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.authn_keys (id, creation_date, resource_owner, aggregate_id, sequence, object_id, expiration, identifier, public_key, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.authn_keys (id, creation_date, resource_owner, instance_id, aggregate_id, sequence, object_id, expiration, identifier, public_key, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "keyId", anyArg{}, "ro-id", + "instance-id", "agg-id", uint64(15), "appId", @@ -76,11 +77,12 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.authn_keys (id, creation_date, resource_owner, aggregate_id, sequence, object_id, expiration, identifier, public_key, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.authn_keys (id, creation_date, resource_owner, instance_id, aggregate_id, sequence, object_id, expiration, identifier, public_key, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "keyId", anyArg{}, "ro-id", + "instance-id", "agg-id", uint64(15), "agg-id", @@ -112,7 +114,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1)", expectedArgs: []interface{}{ "keyId", }, @@ -159,7 +161,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", expectedArgs: []interface{}{ false, "appId", @@ -187,7 +189,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", expectedArgs: []interface{}{ true, "appId", @@ -215,7 +217,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1)", expectedArgs: []interface{}{ "keyId", }, @@ -262,7 +264,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", expectedArgs: []interface{}{ false, "appId", @@ -290,7 +292,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", expectedArgs: []interface{}{ true, "appId", @@ -318,7 +320,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1)", expectedArgs: []interface{}{ "keyId", }, @@ -345,7 +347,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (object_id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (object_id = $1)", expectedArgs: []interface{}{ "appId", }, @@ -372,7 +374,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (aggregate_id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (aggregate_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -399,7 +401,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1)", expectedArgs: []interface{}{ "keyId", }, @@ -426,7 +428,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.authn_keys WHERE (aggregate_id = $1)", + expectedStmt: "DELETE FROM projections.authn_keys WHERE (aggregate_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/custom_text.go b/internal/query/projection/custom_text.go index e49a8b202c..8a1277b663 100644 --- a/internal/query/projection/custom_text.go +++ b/internal/query/projection/custom_text.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -14,14 +12,11 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type CustomTextProjection struct { - crdb.StatementHandler -} - const ( - CustomTextTable = "zitadel.projections.custom_texts" + CustomTextTable = "projections.custom_texts" CustomTextAggregateIDCol = "aggregate_id" + CustomTextInstanceIDCol = "instance_id" CustomTextCreationDateCol = "creation_date" CustomTextChangeDateCol = "change_date" CustomTextSequenceCol = "sequence" @@ -32,10 +27,30 @@ const ( CustomTextTextCol = "text" ) +type CustomTextProjection struct { + crdb.StatementHandler +} + func NewCustomTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *CustomTextProjection { p := new(CustomTextProjection) config.ProjectionName = CustomTextTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(CustomTextAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(CustomTextInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(CustomTextCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(CustomTextChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(CustomTextSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(CustomTextIsDefaultCol, crdb.ColumnTypeBool), + crdb.NewColumn(CustomTextTemplateCol, crdb.ColumnTypeText), + crdb.NewColumn(CustomTextLanguageCol, crdb.ColumnTypeText), + crdb.NewColumn(CustomTextKeyCol, crdb.ColumnTypeText), + crdb.NewColumn(CustomTextTextCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(CustomTextInstanceIDCol, CustomTextAggregateIDCol, CustomTextTemplateCol, CustomTextKeyCol, CustomTextLanguageCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -90,13 +105,13 @@ func (p *CustomTextProjection) reduceSet(event eventstore.Event) (*handler.State customTextEvent = e.CustomTextSetEvent isDefault = true default: - logging.LogWithFields("PROJE-g0Jfs", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-KKfw4", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-KKfw4", "reduce.wrong.event.type %v", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}) } return crdb.NewUpsertStatement( &customTextEvent, []handler.Column{ handler.NewCol(CustomTextAggregateIDCol, customTextEvent.Aggregate().ID), + handler.NewCol(CustomTextInstanceIDCol, customTextEvent.Aggregate().InstanceID), handler.NewCol(CustomTextCreationDateCol, customTextEvent.CreationDate()), handler.NewCol(CustomTextChangeDateCol, customTextEvent.CreationDate()), handler.NewCol(CustomTextSequenceCol, customTextEvent.Sequence()), @@ -116,8 +131,7 @@ func (p *CustomTextProjection) reduceRemoved(event eventstore.Event) (*handler.S case *iam.CustomTextRemovedEvent: customTextEvent = e.CustomTextRemovedEvent default: - logging.LogWithFields("PROJE-2Nigw", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextRemovedEventType, iam.CustomTextRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-n9wJg", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-n9wJg", "reduce.wrong.event.type %v", []eventstore.EventType{org.CustomTextRemovedEventType, iam.CustomTextRemovedEventType}) } return crdb.NewDeleteStatement( &customTextEvent, @@ -137,8 +151,7 @@ func (p *CustomTextProjection) reduceTemplateRemoved(event eventstore.Event) (*h case *iam.CustomTextTemplateRemovedEvent: customTextEvent = e.CustomTextTemplateRemovedEvent default: - logging.LogWithFields("PROJE-J9wfg", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextTemplateRemovedEventType, iam.CustomTextTemplateRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-29iPf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-29iPf", "reduce.wrong.event.type %v", []eventstore.EventType{org.CustomTextTemplateRemovedEventType, iam.CustomTextTemplateRemovedEventType}) } return crdb.NewDeleteStatement( &customTextEvent, diff --git a/internal/query/projection/custom_text_test.go b/internal/query/projection/custom_text_test.go index 73041927b8..dea54347ce 100644 --- a/internal/query/projection/custom_text_test.go +++ b/internal/query/projection/custom_text_test.go @@ -44,9 +44,10 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "UPSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -83,7 +84,7 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4)", + expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4)", expectedArgs: []interface{}{ "agg-id", "InitCode", @@ -117,7 +118,7 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3)", + expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3)", expectedArgs: []interface{}{ "agg-id", "InitCode", @@ -151,9 +152,10 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.custom_texts (aggregate_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "UPSERT INTO projections.custom_texts (aggregate_id, instance_id, creation_date, change_date, sequence, is_default, template, language, key, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -190,7 +192,7 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4)", + expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4)", expectedArgs: []interface{}{ "agg-id", "InitCode", @@ -224,7 +226,7 @@ func TestCustomTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3)", + expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3)", expectedArgs: []interface{}{ "agg-id", "InitCode", diff --git a/internal/query/projection/debug_notification.go b/internal/query/projection/debug_notification.go index 1c2846df74..33a42bc2f2 100644 --- a/internal/query/projection/debug_notification.go +++ b/internal/query/projection/debug_notification.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/repository/settings" @@ -14,18 +13,43 @@ import ( "github.com/caos/zitadel/internal/repository/iam" ) +const ( + DebugNotificationProviderTable = "projections.notification_providers" + + DebugNotificationProviderAggIDCol = "aggregate_id" + DebugNotificationProviderCreationDateCol = "creation_date" + DebugNotificationProviderChangeDateCol = "change_date" + DebugNotificationProviderSequenceCol = "sequence" + DebugNotificationProviderResourceOwnerCol = "resource_owner" + DebugNotificationProviderInstanceIDCol = "instance_id" + DebugNotificationProviderStateCol = "state" + DebugNotificationProviderTypeCol = "provider_type" + DebugNotificationProviderCompactCol = "compact" +) + type DebugNotificationProviderProjection struct { crdb.StatementHandler } -const ( - DebugNotificationProviderTable = "zitadel.projections.notification_providers" -) - func NewDebugNotificationProviderProjection(ctx context.Context, config crdb.StatementHandlerConfig) *DebugNotificationProviderProjection { p := &DebugNotificationProviderProjection{} config.ProjectionName = DebugNotificationProviderTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(DebugNotificationProviderAggIDCol, crdb.ColumnTypeText), + crdb.NewColumn(DebugNotificationProviderCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(DebugNotificationProviderChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(DebugNotificationProviderSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(DebugNotificationProviderResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(DebugNotificationProviderInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(DebugNotificationProviderStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(DebugNotificationProviderTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(DebugNotificationProviderCompactCol, crdb.ColumnTypeBool), + }, + crdb.NewPrimaryKey(DebugNotificationProviderInstanceIDCol, DebugNotificationProviderAggIDCol, DebugNotificationProviderTypeCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -64,17 +88,6 @@ func (p *DebugNotificationProviderProjection) reducers() []handler.AggregateRedu } } -const ( - DebugNotificationProviderAggIDCol = "aggregate_id" - DebugNotificationProviderCreationDateCol = "creation_date" - DebugNotificationProviderChangeDateCol = "change_date" - DebugNotificationProviderSequenceCol = "sequence" - DebugNotificationProviderResourceOwnerCol = "resource_owner" - DebugNotificationProviderStateCol = "state" - DebugNotificationProviderTypeCol = "provider_type" - DebugNotificationProviderCompactCol = "compact" -) - func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderAdded(event eventstore.Event) (*handler.Statement, error) { var providerEvent settings.DebugNotificationProviderAddedEvent var providerType domain.NotificationProviderType @@ -86,8 +99,7 @@ func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderAdd providerEvent = e.DebugNotificationProviderAddedEvent providerType = domain.NotificationProviderTypeLog default: - logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileAddedEventType, iam.DebugNotificationProviderLogAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-pYPxS", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-pYPxS", "reduce.wrong.event.type %v", []eventstore.EventType{iam.DebugNotificationProviderFileAddedEventType, iam.DebugNotificationProviderLogAddedEventType}) } return crdb.NewCreateStatement(&providerEvent, []handler.Column{ @@ -96,6 +108,7 @@ func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderAdd handler.NewCol(DebugNotificationProviderChangeDateCol, providerEvent.CreationDate()), handler.NewCol(DebugNotificationProviderSequenceCol, providerEvent.Sequence()), handler.NewCol(DebugNotificationProviderResourceOwnerCol, providerEvent.Aggregate().ResourceOwner), + handler.NewCol(DebugNotificationProviderInstanceIDCol, providerEvent.Aggregate().InstanceID), handler.NewCol(DebugNotificationProviderStateCol, domain.NotificationProviderStateActive), handler.NewCol(DebugNotificationProviderTypeCol, providerType), handler.NewCol(DebugNotificationProviderCompactCol, providerEvent.Compact), @@ -113,8 +126,7 @@ func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderCha providerEvent = e.DebugNotificationProviderChangedEvent providerType = domain.NotificationProviderTypeLog default: - logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileChangedEventType, iam.DebugNotificationProviderLogChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-pYPxS", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-pYPxS", "reduce.wrong.event.type %v", []eventstore.EventType{iam.DebugNotificationProviderFileChangedEventType, iam.DebugNotificationProviderLogChangedEventType}) } cols := []handler.Column{ @@ -146,8 +158,7 @@ func (p *DebugNotificationProviderProjection) reduceDebugNotificationProviderRem providerEvent = e.DebugNotificationProviderRemovedEvent providerType = domain.NotificationProviderTypeLog default: - logging.WithFields("seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.DebugNotificationProviderFileRemovedEventType, iam.DebugNotificationProviderLogRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-dow9f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-dow9f", "reduce.wrong.event.type %v", []eventstore.EventType{iam.DebugNotificationProviderFileRemovedEventType, iam.DebugNotificationProviderLogRemovedEventType}) } return crdb.NewDeleteStatement( diff --git a/internal/query/projection/debug_notification_provider_test.go b/internal/query/projection/debug_notification_provider_test.go index b1e201a1d0..b779a37b17 100644 --- a/internal/query/projection/debug_notification_provider_test.go +++ b/internal/query/projection/debug_notification_provider_test.go @@ -41,13 +41,14 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, uint64(15), "ro-id", + "instance-id", domain.NotificationProviderStateActive, domain.NotificationProviderTypeFile, true, @@ -77,7 +78,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)", + expectedStmt: "UPDATE projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -108,7 +109,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)", + expectedStmt: "DELETE FROM projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)", expectedArgs: []interface{}{ "agg-id", domain.NotificationProviderTypeFile, @@ -138,13 +139,14 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.notification_providers (aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, state, provider_type, compact) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, uint64(15), "ro-id", + "instance-id", domain.NotificationProviderStateActive, domain.NotificationProviderTypeLog, true, @@ -174,7 +176,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)", + expectedStmt: "UPDATE projections.notification_providers SET (change_date, sequence, compact) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (provider_type = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -205,7 +207,7 @@ func TestDebugNotificationProviderProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)", + expectedStmt: "DELETE FROM projections.notification_providers WHERE (aggregate_id = $1) AND (provider_type = $2)", expectedArgs: []interface{}{ "agg-id", domain.NotificationProviderTypeLog, diff --git a/internal/query/projection/event_test.go b/internal/query/projection/event_test.go index 7ad27fd0ba..09f54931dd 100644 --- a/internal/query/projection/event_test.go +++ b/internal/query/projection/event_test.go @@ -26,6 +26,7 @@ func testEvent( Version: "v1", AggregateID: "agg-id", ResourceOwner: sql.NullString{String: "ro-id", Valid: true}, + InstanceID: sql.NullString{String: "instance-id", Valid: true}, ID: "event-id", EditorService: "editor-svc", EditorUser: "editor-user", diff --git a/internal/query/projection/feature.go b/internal/query/projection/feature.go index 7e411aafe8..a517763441 100644 --- a/internal/query/projection/feature.go +++ b/internal/query/projection/feature.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -16,18 +14,79 @@ import ( "github.com/caos/zitadel/internal/repository/org" ) +const ( + FeatureTable = "projections.features" + + FeatureAggregateIDCol = "aggregate_id" + FeatureInstanceIDCol = "instance_id" + FeatureChangeDateCol = "change_date" + FeatureSequenceCol = "sequence" + FeatureIsDefaultCol = "is_default" + FeatureTierNameCol = "tier_name" + FeatureTierDescriptionCol = "tier_description" + FeatureStateCol = "state" + FeatureStateDescriptionCol = "state_description" + FeatureAuditLogRetentionCol = "audit_log_retention" + FeatureLoginPolicyFactorsCol = "login_policy_factors" + FeatureLoginPolicyIDPCol = "login_policy_idp" + FeatureLoginPolicyPasswordlessCol = "login_policy_passwordless" + FeatureLoginPolicyRegistrationCol = "login_policy_registration" + FeatureLoginPolicyUsernameLoginCol = "login_policy_username_login" + FeatureLoginPolicyPasswordResetCol = "login_policy_password_reset" + FeaturePasswordComplexityPolicyCol = "password_complexity_policy" + FeatureLabelPolicyPrivateLabelCol = "label_policy_private_label" + FeatureLabelPolicyWatermarkCol = "label_policy_watermark" + FeatureCustomDomainCol = "custom_domain" + FeaturePrivacyPolicyCol = "privacy_policy" + FeatureMetadataUserCol = "metadata_user" + FeatureCustomTextMessageCol = "custom_text_message" + FeatureCustomTextLoginCol = "custom_text_login" + FeatureLockoutPolicyCol = "lockout_policy" + FeatureActionsAllowedCol = "actions_allowed" + FeatureMaxActionsCol = "max_actions" +) + type FeatureProjection struct { crdb.StatementHandler } -const ( - FeatureTable = "zitadel.projections.features" -) - func NewFeatureProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FeatureProjection { p := new(FeatureProjection) config.ProjectionName = FeatureTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(FeatureAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(FeatureInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(FeatureChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(FeatureSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(FeatureIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureTierNameCol, crdb.ColumnTypeText), + crdb.NewColumn(FeatureTierDescriptionCol, crdb.ColumnTypeText), + crdb.NewColumn(FeatureStateCol, crdb.ColumnTypeEnum, crdb.Default(0)), + crdb.NewColumn(FeatureStateDescriptionCol, crdb.ColumnTypeText), + crdb.NewColumn(FeatureAuditLogRetentionCol, crdb.ColumnTypeInt64, crdb.Default(0)), + crdb.NewColumn(FeatureLoginPolicyFactorsCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLoginPolicyIDPCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLoginPolicyPasswordlessCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLoginPolicyRegistrationCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLoginPolicyUsernameLoginCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLoginPolicyPasswordResetCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeaturePasswordComplexityPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLabelPolicyPrivateLabelCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLabelPolicyWatermarkCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureCustomDomainCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeaturePrivacyPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureMetadataUserCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureCustomTextMessageCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureCustomTextLoginCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureLockoutPolicyCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(FeatureActionsAllowedCol, crdb.ColumnTypeEnum, crdb.Default(0)), + crdb.NewColumn(FeatureMaxActionsCol, crdb.ColumnTypeInt64, crdb.Default(0)), + }, + crdb.NewPrimaryKey(FeatureInstanceIDCol, FeatureAggregateIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -59,35 +118,6 @@ func (p *FeatureProjection) reducers() []handler.AggregateReducer { } } -const ( - FeatureAggregateIDCol = "aggregate_id" - FeatureChangeDateCol = "change_date" - FeatureSequenceCol = "sequence" - FeatureIsDefaultCol = "is_default" - FeatureTierNameCol = "tier_name" - FeatureTierDescriptionCol = "tier_description" - FeatureStateCol = "state" - FeatureStateDescriptionCol = "state_description" - FeatureAuditLogRetentionCol = "audit_log_retention" - FeatureLoginPolicyFactorsCol = "login_policy_factors" - FeatureLoginPolicyIDPCol = "login_policy_idp" - FeatureLoginPolicyPasswordlessCol = "login_policy_passwordless" - FeatureLoginPolicyRegistrationCol = "login_policy_registration" - FeatureLoginPolicyUsernameLoginCol = "login_policy_username_login" - FeatureLoginPolicyPasswordResetCol = "login_policy_password_reset" - FeaturePasswordComplexityPolicyCol = "password_complexity_policy" - FeatureLabelPolicyPrivateLabelCol = "label_policy_private_label" - FeatureLabelPolicyWatermarkCol = "label_policy_watermark" - FeatureCustomDomainCol = "custom_domain" - FeaturePrivacyPolicyCol = "privacy_policy" - FeatureMetadataUserCol = "metadata_user" - FeatureCustomTextMessageCol = "custom_text_message" - FeatureCustomTextLoginCol = "custom_text_login" - FeatureLockoutPolicyCol = "lockout_policy" - FeatureActionsAllowedCol = "actions_allowed" - FeatureMaxActionsCol = "max_actions" -) - func (p *FeatureProjection) reduceFeatureSet(event eventstore.Event) (*handler.Statement, error) { var featureEvent features.FeaturesSetEvent var isDefault bool @@ -99,12 +129,12 @@ func (p *FeatureProjection) reduceFeatureSet(event eventstore.Event) (*handler.S featureEvent = e.FeaturesSetEvent isDefault = false default: - logging.LogWithFields("HANDL-M9ets", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.FeaturesSetEventType, iam.FeaturesSetEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-K0erf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-K0erf", "reduce.wrong.event.type %v", []eventstore.EventType{org.FeaturesSetEventType, iam.FeaturesSetEventType}) } cols := []handler.Column{ handler.NewCol(FeatureAggregateIDCol, featureEvent.Aggregate().ID), + handler.NewCol(FeatureInstanceIDCol, featureEvent.Aggregate().InstanceID), handler.NewCol(FeatureChangeDateCol, featureEvent.CreationDate()), handler.NewCol(FeatureSequenceCol, featureEvent.Sequence()), handler.NewCol(FeatureIsDefaultCol, isDefault), @@ -196,8 +226,7 @@ func (p *FeatureProjection) reduceFeatureSet(event eventstore.Event) (*handler.S func (p *FeatureProjection) reduceFeatureRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.FeaturesRemovedEvent) if !ok { - logging.LogWithFields("HANDL-fN903", "seq", event.Sequence(), "expectedType", org.FeaturesRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-0p4rf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-0p4rf", "reduce.wrong.event.type %s", org.FeaturesRemovedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/feature_test.go b/internal/query/projection/feature_test.go index 3ccf26b5aa..f0c4c89efa 100644 --- a/internal/query/projection/feature_test.go +++ b/internal/query/projection/feature_test.go @@ -64,9 +64,10 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.features (aggregate_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)", + expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, uint64(15), false, @@ -138,9 +139,10 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.features (aggregate_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)", + expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, uint64(15), false, @@ -189,9 +191,10 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.features (aggregate_id, change_date, sequence, is_default) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default) VALUES ($1, $2, $3, $4, $5)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, uint64(15), false, @@ -219,7 +222,7 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.features WHERE (aggregate_id = $1)", + expectedStmt: "DELETE FROM projections.features WHERE (aggregate_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -268,9 +271,10 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.features (aggregate_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)", + expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, uint64(15), true, @@ -342,9 +346,10 @@ func TestFeatureProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.features (aggregate_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26)", + expectedStmt: "UPSERT INTO projections.features (aggregate_id, instance_id, change_date, sequence, is_default, tier_name, tier_description, state, state_description, audit_log_retention, login_policy_factors, login_policy_idp, login_policy_passwordless, login_policy_registration, login_policy_username_login, login_policy_password_reset, password_complexity_policy, label_policy_private_label, label_policy_watermark, custom_domain, privacy_policy, metadata_user, custom_text_message, custom_text_login, lockout_policy, actions_allowed, max_actions) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, uint64(15), true, diff --git a/internal/query/projection/flow.go b/internal/query/projection/flow.go index 37c3008cbc..eeed193e13 100644 --- a/internal/query/projection/flow.go +++ b/internal/query/projection/flow.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -13,10 +11,13 @@ import ( ) const ( - FlowTriggerTable = "zitadel.projections.flows_triggers" + FlowTriggerTable = "projections.flows_triggers" FlowTypeCol = "flow_type" + FlowChangeDateCol = "change_date" + FlowSequenceCol = "sequence" FlowTriggerTypeCol = "trigger_type" FlowResourceOwnerCol = "resource_owner" + FlowInstanceIDCol = "instance_id" FlowActionTriggerSequenceCol = "trigger_sequence" FlowActionIDCol = "action_id" ) @@ -29,6 +30,20 @@ func NewFlowProjection(ctx context.Context, config crdb.StatementHandlerConfig) p := new(FlowProjection) config.ProjectionName = FlowTriggerTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(FlowTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(FlowChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(FlowSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(FlowTriggerTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(FlowResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(FlowInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(FlowActionTriggerSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(FlowActionIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(FlowInstanceIDCol, FlowTypeCol, FlowTriggerTypeCol, FlowResourceOwnerCol, FlowActionIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -54,8 +69,7 @@ func (p *FlowProjection) reducers() []handler.AggregateReducer { func (p *FlowProjection) reduceTriggerActionsSetEventType(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.TriggerActionsSetEvent) if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence, "expectedType", org.TriggerActionsSetEventType).Error("was not an trigger actions set event") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uYq4r", "reduce.wrong.event.type %s", org.TriggerActionsSetEventType) } stmts := make([]func(reader eventstore.Event) crdb.Exec, len(e.ActionIDs)+1) stmts[0] = crdb.AddDeleteStatement( @@ -68,7 +82,10 @@ func (p *FlowProjection) reduceTriggerActionsSetEventType(event eventstore.Event stmts[i+1] = crdb.AddCreateStatement( []handler.Column{ handler.NewCol(FlowResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(FlowInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(FlowTypeCol, e.FlowType), + handler.NewCol(FlowChangeDateCol, e.CreationDate()), + handler.NewCol(FlowSequenceCol, e.Sequence()), handler.NewCol(FlowTriggerTypeCol, e.TriggerType), handler.NewCol(FlowActionIDCol, id), handler.NewCol(FlowActionTriggerSequenceCol, i), @@ -81,8 +98,7 @@ func (p *FlowProjection) reduceTriggerActionsSetEventType(event eventstore.Event func (p *FlowProjection) reduceFlowClearedEventType(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.FlowClearedEvent) if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence, "expectedType", org.FlowClearedEventType).Error("was not a flow cleared event") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uYq4r", "reduce.wrong.event.type %s", org.FlowClearedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/flow/flow.go b/internal/query/projection/flow/flow.go deleted file mode 100644 index 972c5d0b44..0000000000 --- a/internal/query/projection/flow/flow.go +++ /dev/null @@ -1,184 +0,0 @@ -package flow - -import ( - "context" - - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/handler" - "github.com/caos/zitadel/internal/eventstore/handler/crdb" - "github.com/caos/zitadel/internal/repository/action" - "github.com/caos/zitadel/internal/repository/org" -) - -type FlowProjection struct { - crdb.StatementHandler -} - -func NewFlowProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FlowProjection { - p := &FlowProjection{} - config.ProjectionName = "projections.flows" - config.Reducers = p.reducers() - p.StatementHandler = crdb.NewStatementHandler(ctx, config) - return p -} - -func (p *FlowProjection) reducers() []handler.AggregateReducer { - return []handler.AggregateReducer{ - { - Aggregate: org.AggregateType, - EventRedusers: []handler.EventReducer{ - { - Event: org.TriggerActionsSetEventType, - Reduce: p.reduceTriggerActionsSetEventType, - }, - { - Event: org.FlowClearedEventType, - Reduce: p.reduceFlowClearedEventType, - }, - }, - }, - { - Aggregate: action.AggregateType, - EventRedusers: []handler.EventReducer{ - { - Event: action.AddedEventType, - Reduce: p.reduceFlowActionAdded, - }, - { - Event: action.ChangedEventType, - Reduce: p.reduceFlowActionChanged, - }, - { - Event: action.RemovedEventType, - Reduce: p.reduceFlowActionRemoved, - }, - }, - }, - } -} - -const ( - triggerTableSuffix = "triggers" - flowTypeCol = "flow_type" - flowTriggerTypeCol = "trigger_type" - flowResourceOwnerCol = "resource_owner" - flowActionTriggerSequenceCol = "trigger_sequence" - flowActionIDCol = "action_id" - - actionTableSuffix = "actions" - actionIDCol = "id" - actionCreationDateCol = "creation_date" - actionChangeDateCol = "change_date" - actionResourceOwnerCol = "resource_owner" - actionSequenceCol = "sequence" - actionNameCol = "name" - actionScriptCol = "script" -) - -func (p *FlowProjection) reduceTriggerActionsSetEventType(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.TriggerActionsSetEvent) - if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence, "expectedType", action.AddedEventType).Error("was not an trigger actions set event") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") - } - stmts := make([]func(reader eventstore.Event) crdb.Exec, len(e.ActionIDs)+1) - stmts[0] = crdb.AddDeleteStatement( - []handler.Condition{ - handler.NewCond(flowTypeCol, e.FlowType), - handler.NewCond(flowTriggerTypeCol, e.TriggerType), - }, - crdb.WithTableSuffix(triggerTableSuffix), - ) - for i, id := range e.ActionIDs { - stmts[i+1] = crdb.AddCreateStatement( - []handler.Column{ - handler.NewCol(flowResourceOwnerCol, e.Aggregate().ResourceOwner), - handler.NewCol(flowTypeCol, e.FlowType), - handler.NewCol(flowTriggerTypeCol, e.TriggerType), - handler.NewCol(flowActionIDCol, id), - handler.NewCol(flowActionTriggerSequenceCol, i), - }, - crdb.WithTableSuffix(triggerTableSuffix), - ) - } - return crdb.NewMultiStatement(e, stmts...), nil -} - -func (p *FlowProjection) reduceFlowClearedEventType(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.FlowClearedEvent) - if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence, "expectedType", action.AddedEventType).Error("was not an trigger actions set event") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") - } - return crdb.NewDeleteStatement( - e, - []handler.Condition{ - handler.NewCond(flowTypeCol, e.FlowType), - }, - crdb.WithTableSuffix(triggerTableSuffix), - ), nil -} - -func (p *FlowProjection) reduceFlowActionAdded(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*action.AddedEvent) - if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence, "expectedType", action.AddedEventType).Error("was not an flow action added event") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") - } - return crdb.NewCreateStatement( - e, - []handler.Column{ - handler.NewCol(actionIDCol, e.Aggregate().ID), - handler.NewCol(actionCreationDateCol, e.CreationDate()), - handler.NewCol(actionChangeDateCol, e.CreationDate()), - handler.NewCol(actionResourceOwnerCol, e.Aggregate().ResourceOwner), - handler.NewCol(actionSequenceCol, e.Sequence()), - handler.NewCol(actionNameCol, e.Name), - handler.NewCol(actionScriptCol, e.Script), - }, - crdb.WithTableSuffix(actionTableSuffix), - ), nil -} - -func (p *FlowProjection) reduceFlowActionChanged(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*action.ChangedEvent) - if !ok { - logging.LogWithFields("HANDL-q4oq8", "seq", event.Sequence, "expected", action.ChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Bg8oM", "reduce.wrong.event.type") - } - values := []handler.Column{ - handler.NewCol(actionChangeDateCol, e.CreationDate()), - handler.NewCol(actionSequenceCol, e.Sequence()), - } - if e.Name != nil { - values = append(values, handler.NewCol(actionNameCol, *e.Name)) - } - if e.Script != nil { - values = append(values, handler.NewCol(actionScriptCol, *e.Script)) - } - return crdb.NewUpdateStatement( - e, - values, - []handler.Condition{ - handler.NewCond(actionIDCol, e.Aggregate().ID), - }, - crdb.WithTableSuffix(actionTableSuffix), - ), nil -} - -func (p *FlowProjection) reduceFlowActionRemoved(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*action.RemovedEvent) - if !ok { - logging.LogWithFields("HANDL-79OhB", "seq", event.Sequence, "expectedType", action.RemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-4TbKT", "reduce.wrong.event.type") - } - return crdb.NewDeleteStatement( - e, - []handler.Condition{ - handler.NewCond(actionIDCol, e.Aggregate().ID), - }, - crdb.WithTableSuffix(actionTableSuffix), - ), nil -} diff --git a/internal/query/projection/flow_test.go b/internal/query/projection/flow_test.go index afd7904afc..6124875d79 100644 --- a/internal/query/projection/flow_test.go +++ b/internal/query/projection/flow_test.go @@ -39,27 +39,33 @@ func TestFlowProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.flows_triggers WHERE (flow_type = $1) AND (trigger_type = $2)", + expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (trigger_type = $2)", expectedArgs: []interface{}{ domain.FlowTypeExternalAuthentication, domain.TriggerTypePostAuthentication, }, }, { - expectedStmt: "INSERT INTO zitadel.projections.flows_triggers (resource_owner, flow_type, trigger_type, action_id, trigger_sequence) VALUES ($1, $2, $3, $4, $5)", + expectedStmt: "INSERT INTO projections.flows_triggers (resource_owner, instance_id, flow_type, change_date, sequence, trigger_type, action_id, trigger_sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "ro-id", + "instance-id", domain.FlowTypeExternalAuthentication, + anyArg{}, + uint64(15), domain.TriggerTypePostAuthentication, "id1", 0, }, }, { - expectedStmt: "INSERT INTO zitadel.projections.flows_triggers (resource_owner, flow_type, trigger_type, action_id, trigger_sequence) VALUES ($1, $2, $3, $4, $5)", + expectedStmt: "INSERT INTO projections.flows_triggers (resource_owner, instance_id, flow_type, change_date, sequence, trigger_type, action_id, trigger_sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "ro-id", + "instance-id", domain.FlowTypeExternalAuthentication, + anyArg{}, + uint64(15), domain.TriggerTypePostAuthentication, "id2", 1, @@ -87,7 +93,7 @@ func TestFlowProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.flows_triggers WHERE (flow_type = $1)", + expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1)", expectedArgs: []interface{}{ domain.FlowTypeExternalAuthentication, }, diff --git a/internal/query/projection/iam.go b/internal/query/projection/iam.go index ad1ce047d0..dfd0539080 100644 --- a/internal/query/projection/iam.go +++ b/internal/query/projection/iam.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -11,18 +10,41 @@ import ( "github.com/caos/zitadel/internal/repository/iam" ) +const ( + IAMProjectionTable = "projections.iam" + + IAMColumnID = "id" + IAMColumnChangeDate = "change_date" + IAMColumnGlobalOrgID = "global_org_id" + IAMColumnProjectID = "iam_project_id" + IAMColumnSequence = "sequence" + IAMColumnSetUpStarted = "setup_started" + IAMColumnSetUpDone = "setup_done" + IAMColumnDefaultLanguage = "default_language" +) + type IAMProjection struct { crdb.StatementHandler } -const ( - IAMProjectionTable = "zitadel.projections.iam" -) - func NewIAMProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMProjection { p := new(IAMProjection) config.ProjectionName = IAMProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(IAMColumnID, crdb.ColumnTypeText), + crdb.NewColumn(IAMColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IAMColumnGlobalOrgID, crdb.ColumnTypeText, crdb.Default("")), + crdb.NewColumn(IAMColumnProjectID, crdb.ColumnTypeText, crdb.Default("")), + crdb.NewColumn(IAMColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(IAMColumnSetUpStarted, crdb.ColumnTypeInt64, crdb.Default(0)), + crdb.NewColumn(IAMColumnSetUpDone, crdb.ColumnTypeInt64, crdb.Default(0)), + crdb.NewColumn(IAMColumnDefaultLanguage, crdb.ColumnTypeText, crdb.Default("")), + }, + crdb.NewPrimaryKey(IAMColumnID), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -57,29 +79,15 @@ func (p *IAMProjection) reducers() []handler.AggregateReducer { } } -type IAMColumn string - -const ( - IAMColumnID = "id" - IAMColumnChangeDate = "change_date" - IAMColumnGlobalOrgID = "global_org_id" - IAMColumnProjectID = "iam_project_id" - IAMColumnSequence = "sequence" - IAMColumnSetUpStarted = "setup_started" - IAMColumnSetUpDone = "setup_done" - IAMColumnDefaultLanguage = "default_language" -) - func (p *IAMProjection) reduceGlobalOrgSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.GlobalOrgSetEvent) if !ok { - logging.LogWithFields("HANDL-3n89fs", "seq", event.Sequence(), "expectedType", iam.GlobalOrgSetEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-2n9f2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2n9f2", "reduce.wrong.event.type %s", iam.GlobalOrgSetEventType) } return crdb.NewUpsertStatement( e, []handler.Column{ - handler.NewCol(IAMColumnID, e.Aggregate().ID), + handler.NewCol(IAMColumnID, e.Aggregate().InstanceID), handler.NewCol(IAMColumnChangeDate, e.CreationDate()), handler.NewCol(IAMColumnSequence, e.Sequence()), handler.NewCol(IAMColumnGlobalOrgID, e.OrgID), @@ -90,13 +98,12 @@ func (p *IAMProjection) reduceGlobalOrgSet(event eventstore.Event) (*handler.Sta func (p *IAMProjection) reduceIAMProjectSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.ProjectSetEvent) if !ok { - logging.LogWithFields("HANDL-2j9fw", "seq", event.Sequence(), "expectedType", iam.ProjectSetEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-30o0e", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-30o0e", "reduce.wrong.event.type %s", iam.ProjectSetEventType) } return crdb.NewUpsertStatement( e, []handler.Column{ - handler.NewCol(IAMColumnID, e.Aggregate().ID), + handler.NewCol(IAMColumnID, e.Aggregate().InstanceID), handler.NewCol(IAMColumnChangeDate, e.CreationDate()), handler.NewCol(IAMColumnSequence, e.Sequence()), handler.NewCol(IAMColumnProjectID, e.ProjectID), @@ -107,13 +114,12 @@ func (p *IAMProjection) reduceIAMProjectSet(event eventstore.Event) (*handler.St func (p *IAMProjection) reduceDefaultLanguageSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.DefaultLanguageSetEvent) if !ok { - logging.LogWithFields("HANDL-3n9le", "seq", event.Sequence(), "expectedType", iam.DefaultLanguageSetEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-30o0e", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-30o0e", "reduce.wrong.event.type %s", iam.DefaultLanguageSetEventType) } return crdb.NewUpsertStatement( e, []handler.Column{ - handler.NewCol(IAMColumnID, e.Aggregate().ID), + handler.NewCol(IAMColumnID, e.Aggregate().InstanceID), handler.NewCol(IAMColumnChangeDate, e.CreationDate()), handler.NewCol(IAMColumnSequence, e.Sequence()), handler.NewCol(IAMColumnDefaultLanguage, e.Language.String()), @@ -124,11 +130,10 @@ func (p *IAMProjection) reduceDefaultLanguageSet(event eventstore.Event) (*handl func (p *IAMProjection) reduceSetupEvent(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SetupStepEvent) if !ok { - logging.LogWithFields("HANDL-39fjw", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.SetupDoneEventType, iam.SetupStartedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-d9nfw", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-d9nfw", "reduce.wrong.event.type %v", []eventstore.EventType{iam.SetupDoneEventType, iam.SetupStartedEventType}) } columns := []handler.Column{ - handler.NewCol(IAMColumnID, e.Aggregate().ID), + handler.NewCol(IAMColumnID, e.Aggregate().InstanceID), handler.NewCol(IAMColumnChangeDate, e.CreationDate()), handler.NewCol(IAMColumnSequence, e.Sequence()), } diff --git a/internal/query/projection/iam_member.go b/internal/query/projection/iam_member.go index 3d16267caf..5d8eee2811 100644 --- a/internal/query/projection/iam_member.go +++ b/internal/query/projection/iam_member.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -13,18 +11,28 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + IAMMemberProjectionTable = "projections.iam_members" + + IAMMemberIAMIDCol = "iam_id" +) + type IAMMemberProjection struct { crdb.StatementHandler } -const ( - IAMMemberProjectionTable = "zitadel.projections.iam_members" -) - func NewIAMMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMMemberProjection { p := new(IAMMemberProjection) config.ProjectionName = IAMMemberProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable( + append(memberColumns, crdb.NewColumn(IAMColumnID, crdb.ColumnTypeText)), + crdb.NewPrimaryKey(MemberInstanceID, IAMColumnID, MemberUserIDCol), + crdb.NewIndex("user_idx", []string{MemberUserIDCol}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -64,17 +72,10 @@ func (p *IAMMemberProjection) reducers() []handler.AggregateReducer { } } -type IAMMemberColumn string - -const ( - IAMMemberIAMIDCol = "iam_id" -) - func (p *IAMMemberProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.MemberAddedEvent) if !ok { - logging.LogWithFields("HANDL-c8SBb", "seq", event.Sequence(), "expectedType", iam.MemberAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-pGNCu", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-pGNCu", "reduce.wrong.event.type %s", iam.MemberAddedEventType) } return reduceMemberAdded(e.MemberAddedEvent, withMemberCol(IAMMemberIAMIDCol, e.Aggregate().ID)) } @@ -82,8 +83,7 @@ func (p *IAMMemberProjection) reduceAdded(event eventstore.Event) (*handler.Stat func (p *IAMMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.MemberChangedEvent) if !ok { - logging.LogWithFields("HANDL-QsjwO", "seq", event.Sequence(), "expected", iam.MemberChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-5WQcZ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-5WQcZ", "reduce.wrong.event.type %s", iam.MemberChangedEventType) } return reduceMemberChanged(e.MemberChangedEvent) } @@ -91,8 +91,7 @@ func (p *IAMMemberProjection) reduceChanged(event eventstore.Event) (*handler.St func (p *IAMMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.MemberCascadeRemovedEvent) if !ok { - logging.LogWithFields("HANDL-mOncs", "seq", event.Sequence(), "expected", iam.MemberCascadeRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dmdf2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dmdf2", "reduce.wrong.event.type %s", iam.MemberCascadeRemovedEventType) } return reduceMemberCascadeRemoved(e.MemberCascadeRemovedEvent) } @@ -100,8 +99,7 @@ func (p *IAMMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*han func (p *IAMMemberProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.MemberRemovedEvent) if !ok { - logging.LogWithFields("HANDL-lW1Zv", "seq", event.Sequence(), "expected", iam.MemberRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-exVqy", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-exVqy", "reduce.wrong.event.type %s", iam.MemberRemovedEventType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.UserID)) } @@ -109,8 +107,7 @@ func (p *IAMMemberProjection) reduceRemoved(event eventstore.Event) (*handler.St func (p *IAMMemberProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-rBuvT", "seq", event.Sequence(), "expected", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-mkDHF", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-mkDHF", "reduce.wrong.event.type %s", user.UserRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.Aggregate().ID)) } diff --git a/internal/query/projection/iam_member_test.go b/internal/query/projection/iam_member_test.go index ed68fb7ccc..5242d62d02 100644 --- a/internal/query/projection/iam_member_test.go +++ b/internal/query/projection/iam_member_test.go @@ -3,13 +3,14 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/repository/user" - "github.com/lib/pq" ) func TestIAMMemberProjection_reduces(t *testing.T) { @@ -43,7 +44,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.iam_members (user_id, roles, creation_date, change_date, sequence, resource_owner, iam_id) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.iam_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, iam_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "user-id", pq.StringArray{"role"}, @@ -51,6 +52,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", "agg-id", }, }, @@ -79,7 +81,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.iam_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4)", + expectedStmt: "UPDATE projections.iam_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4)", expectedArgs: []interface{}{ pq.StringArray{"role", "changed"}, anyArg{}, @@ -111,7 +113,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.iam_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.iam_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "user-id", }, @@ -140,7 +142,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.iam_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.iam_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "user-id", }, @@ -167,7 +169,7 @@ func TestIAMMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.iam_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.iam_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/iam_test.go b/internal/query/projection/iam_test.go index b3bd0ce012..e5c8b299d7 100644 --- a/internal/query/projection/iam_test.go +++ b/internal/query/projection/iam_test.go @@ -39,9 +39,9 @@ func TestIAMProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, global_org_id) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.iam (id, change_date, sequence, global_org_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ - "agg-id", + "instance-id", anyArg{}, uint64(15), "orgid", @@ -69,9 +69,9 @@ func TestIAMProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, iam_project_id) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.iam (id, change_date, sequence, iam_project_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ - "agg-id", + "instance-id", anyArg{}, uint64(15), "project-id", @@ -99,9 +99,9 @@ func TestIAMProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, default_language) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.iam (id, change_date, sequence, default_language) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ - "agg-id", + "instance-id", anyArg{}, uint64(15), "en", @@ -129,9 +129,9 @@ func TestIAMProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, setup_started) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.iam (id, change_date, sequence, setup_started) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ - "agg-id", + "instance-id", anyArg{}, uint64(15), domain.Step1, @@ -159,9 +159,9 @@ func TestIAMProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, setup_done) VALUES ($1, $2, $3, $4)", + expectedStmt: "UPSERT INTO projections.iam (id, change_date, sequence, setup_done) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ - "agg-id", + "instance-id", anyArg{}, uint64(15), domain.Step1, diff --git a/internal/query/projection/idp.go b/internal/query/projection/idp.go index 31125b6bc9..a6731b0c88 100644 --- a/internal/query/projection/idp.go +++ b/internal/query/projection/idp.go @@ -3,7 +3,8 @@ package projection import ( "context" - "github.com/caos/logging" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -12,23 +13,97 @@ import ( "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/repository/idpconfig" "github.com/caos/zitadel/internal/repository/org" - "github.com/lib/pq" +) + +const ( + IDPTable = "projections.idps" + IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix + IDPJWTTable = IDPTable + "_" + IDPJWTSuffix + + IDPOIDCSuffix = "oidc_config" + IDPJWTSuffix = "jwt_config" + + IDPIDCol = "id" + IDPCreationDateCol = "creation_date" + IDPChangeDateCol = "change_date" + IDPSequenceCol = "sequence" + IDPResourceOwnerCol = "resource_owner" + IDPInstanceIDCol = "instance_id" + IDPStateCol = "state" + IDPNameCol = "name" + IDPStylingTypeCol = "styling_type" + IDPOwnerTypeCol = "owner_type" + IDPAutoRegisterCol = "auto_register" + IDPTypeCol = "type" + + OIDCConfigIDPIDCol = "idp_id" + OIDCConfigClientIDCol = "client_id" + OIDCConfigClientSecretCol = "client_secret" + OIDCConfigIssuerCol = "issuer" + OIDCConfigScopesCol = "scopes" + OIDCConfigDisplayNameMappingCol = "display_name_mapping" + OIDCConfigUsernameMappingCol = "username_mapping" + OIDCConfigAuthorizationEndpointCol = "authorization_endpoint" + OIDCConfigTokenEndpointCol = "token_endpoint" + + JWTConfigIDPIDCol = "idp_id" + JWTConfigIssuerCol = "issuer" + JWTConfigKeysEndpointCol = "keys_endpoint" + JWTConfigHeaderNameCol = "header_name" + JWTConfigEndpointCol = "endpoint" ) type IDPProjection struct { crdb.StatementHandler } -const ( - IDPTable = "zitadel.projections.idps" - IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix - IDPJWTTable = IDPTable + "_" + IDPJWTSuffix -) - func NewIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPProjection { p := new(IDPProjection) config.ProjectionName = IDPTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(IDPIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(IDPResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(IDPNameCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPStylingTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(IDPOwnerTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(IDPAutoRegisterCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(IDPTypeCol, crdb.ColumnTypeEnum), + }, + crdb.NewPrimaryKey(IDPInstanceIDCol, IDPIDCol), + crdb.NewIndex("ro_idx", []string{IDPResourceOwnerCol}), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(OIDCConfigIDPIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(IDPIDCol)), + crdb.NewColumn(OIDCConfigClientIDCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(OIDCConfigClientSecretCol, crdb.ColumnTypeJSONB, crdb.Nullable()), + crdb.NewColumn(OIDCConfigIssuerCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(OIDCConfigScopesCol, crdb.ColumnTypeTextArray, crdb.Nullable()), + crdb.NewColumn(OIDCConfigDisplayNameMappingCol, crdb.ColumnTypeEnum, crdb.Nullable()), + crdb.NewColumn(OIDCConfigUsernameMappingCol, crdb.ColumnTypeEnum, crdb.Nullable()), + crdb.NewColumn(OIDCConfigAuthorizationEndpointCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(OIDCConfigTokenEndpointCol, crdb.ColumnTypeEnum, crdb.Nullable()), + }, + crdb.NewPrimaryKey(OIDCConfigIDPIDCol), + IDPOIDCSuffix, + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(JWTConfigIDPIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(IDPIDCol)), + crdb.NewColumn(JWTConfigIssuerCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(JWTConfigKeysEndpointCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(JWTConfigHeaderNameCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(JWTConfigEndpointCol, crdb.ColumnTypeText, crdb.Nullable()), + }, + crdb.NewPrimaryKey(JWTConfigIDPIDCol), + IDPJWTSuffix, + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -120,39 +195,6 @@ func (p *IDPProjection) reducers() []handler.AggregateReducer { } } -const ( - IDPOIDCSuffix = "oidc_config" - IDPJWTSuffix = "jwt_config" - - IDPIDCol = "id" - IDPCreationDateCol = "creation_date" - IDPChangeDateCol = "change_date" - IDPSequenceCol = "sequence" - IDPResourceOwnerCol = "resource_owner" - IDPStateCol = "state" - IDPNameCol = "name" - IDPStylingTypeCol = "styling_type" - IDPOwnerTypeCol = "owner_type" - IDPAutoRegisterCol = "auto_register" - IDPTypeCol = "type" - - OIDCConfigIDPIDCol = "idp_id" - OIDCConfigClientIDCol = "client_id" - OIDCConfigClientSecretCol = "client_secret" - OIDCConfigIssuerCol = "issuer" - OIDCConfigScopesCol = "scopes" - OIDCConfigDisplayNameMappingCol = "display_name_mapping" - OIDCConfigUsernameMappingCol = "username_mapping" - OIDCConfigAuthorizationEndpointCol = "authorization_endpoint" - OIDCConfigTokenEndpointCol = "token_endpoint" - - JWTConfigIDPIDCol = "idp_id" - JWTConfigIssuerCol = "issuer" - JWTConfigKeysEndpointCol = "keys_endpoint" - JWTConfigHeaderNameCol = "header_name" - JWTConfigEndpointCol = "endpoint" -) - func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Statement, error) { var idpEvent idpconfig.IDPConfigAddedEvent var idpOwnerType domain.IdentityProviderType @@ -164,8 +206,7 @@ func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Stateme idpEvent = e.IDPConfigAddedEvent idpOwnerType = domain.IdentityProviderTypeSystem default: - logging.LogWithFields("HANDL-hBriG", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigAddedEventType, iam.IDPConfigAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-fcUdQ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fcUdQ", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigAddedEventType, iam.IDPConfigAddedEventType}) } return crdb.NewCreateStatement( @@ -176,6 +217,7 @@ func (p *IDPProjection) reduceIDPAdded(event eventstore.Event) (*handler.Stateme handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()), handler.NewCol(IDPSequenceCol, idpEvent.Sequence()), handler.NewCol(IDPResourceOwnerCol, idpEvent.Aggregate().ResourceOwner), + handler.NewCol(IDPInstanceIDCol, idpEvent.Aggregate().InstanceID), handler.NewCol(IDPStateCol, domain.IDPConfigStateActive), handler.NewCol(IDPNameCol, idpEvent.Name), handler.NewCol(IDPStylingTypeCol, idpEvent.StylingType), @@ -193,8 +235,7 @@ func (p *IDPProjection) reduceIDPChanged(event eventstore.Event) (*handler.State case *iam.IDPConfigChangedEvent: idpEvent = e.IDPConfigChangedEvent default: - logging.LogWithFields("HANDL-FFrph", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigChangedEventType, iam.IDPConfigChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-NVvJD", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-NVvJD", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigChangedEventType, iam.IDPConfigChangedEventType}) } cols := make([]handler.Column, 0, 5) @@ -233,8 +274,7 @@ func (p *IDPProjection) reduceIDPDeactivated(event eventstore.Event) (*handler.S case *iam.IDPConfigDeactivatedEvent: idpEvent = e.IDPConfigDeactivatedEvent default: - logging.LogWithFields("HANDL-1s33a", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-94O5l", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-94O5l", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventType}) } return crdb.NewUpdateStatement( @@ -258,8 +298,7 @@ func (p *IDPProjection) reduceIDPReactivated(event eventstore.Event) (*handler.S case *iam.IDPConfigReactivatedEvent: idpEvent = e.IDPConfigReactivatedEvent default: - logging.LogWithFields("HANDL-Zgzpt", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-I8QyS", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-I8QyS", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventType}) } return crdb.NewUpdateStatement( @@ -283,8 +322,7 @@ func (p *IDPProjection) reduceIDPRemoved(event eventstore.Event) (*handler.State case *iam.IDPConfigRemovedEvent: idpEvent = e.IDPConfigRemovedEvent default: - logging.LogWithFields("HANDL-JJasT", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-B4zy8", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-B4zy8", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}) } return crdb.NewDeleteStatement( @@ -303,8 +341,7 @@ func (p *IDPProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler. case *iam.IDPOIDCConfigAddedEvent: idpEvent = e.OIDCConfigAddedEvent default: - logging.LogWithFields("HANDL-DCmeB", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-2FuAA", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2FuAA", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventType}) } return crdb.NewMultiStatement(&idpEvent, @@ -343,8 +380,7 @@ func (p *IDPProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle case *iam.IDPOIDCConfigChangedEvent: idpEvent = e.OIDCConfigChangedEvent default: - logging.LogWithFields("HANDL-VyBm2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-x2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventType}) } cols := make([]handler.Column, 0, 8) @@ -406,8 +442,7 @@ func (p *IDPProjection) reduceJWTConfigAdded(event eventstore.Event) (*handler.S case *iam.IDPJWTConfigAddedEvent: idpEvent = e.JWTConfigAddedEvent default: - logging.LogWithFields("HANDL-228q7", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigAddedEventType, iam.IDPJWTConfigAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-qvPdb", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-qvPdb", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigAddedEventType, iam.IDPJWTConfigAddedEventType}) } return crdb.NewMultiStatement(&idpEvent, @@ -443,8 +478,7 @@ func (p *IDPProjection) reduceJWTConfigChanged(event eventstore.Event) (*handler case *iam.IDPJWTConfigChangedEvent: idpEvent = e.JWTConfigChangedEvent default: - logging.LogWithFields("HANDL-VyBm2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigChangedEventType, iam.IDPJWTConfigChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-x2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigChangedEventType, iam.IDPJWTConfigChangedEventType}) } cols := make([]handler.Column, 0, 4) diff --git a/internal/query/projection/idp_login_policy_link.go b/internal/query/projection/idp_login_policy_link.go index 8dd2d1641f..388ff6ef11 100644 --- a/internal/query/projection/idp_login_policy_link.go +++ b/internal/query/projection/idp_login_policy_link.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,18 +13,41 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) +const ( + IDPLoginPolicyLinkTable = "projections.idp_login_policy_links" + + IDPLoginPolicyLinkIDPIDCol = "idp_id" + IDPLoginPolicyLinkAggregateIDCol = "aggregate_id" + IDPLoginPolicyLinkCreationDateCol = "creation_date" + IDPLoginPolicyLinkChangeDateCol = "change_date" + IDPLoginPolicyLinkSequenceCol = "sequence" + IDPLoginPolicyLinkResourceOwnerCol = "resource_owner" + IDPLoginPolicyLinkInstanceIDCol = "instance_id" + IDPLoginPolicyLinkProviderTypeCol = "provider_type" +) + type IDPLoginPolicyLinkProjection struct { crdb.StatementHandler } -const ( - IDPLoginPolicyLinkTable = "zitadel.projections.idp_login_policy_links" -) - func NewIDPLoginPolicyLinkProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPLoginPolicyLinkProjection { p := new(IDPLoginPolicyLinkProjection) config.ProjectionName = IDPLoginPolicyLinkTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(IDPLoginPolicyLinkIDPIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPLoginPolicyLinkAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPLoginPolicyLinkCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPLoginPolicyLinkChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPLoginPolicyLinkSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(IDPLoginPolicyLinkResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPLoginPolicyLinkInstanceIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(IDPLoginPolicyLinkInstanceIDCol, IDPLoginPolicyLinkAggregateIDCol, IDPLoginPolicyLinkIDPIDCol), + crdb.NewIndex("ro_idx", []string{IDPLoginPolicyLinkResourceOwnerCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -81,16 +103,6 @@ func (p *IDPLoginPolicyLinkProjection) reducers() []handler.AggregateReducer { } } -const ( - IDPLoginPolicyLinkIDPIDCol = "idp_id" - IDPLoginPolicyLinkAggregateIDCol = "aggregate_id" - IDPLoginPolicyLinkCreationDateCol = "creation_date" - IDPLoginPolicyLinkChangeDateCol = "change_date" - IDPLoginPolicyLinkSequenceCol = "sequence" - IDPLoginPolicyLinkResourceOwnerCol = "resource_owner" - IDPLoginPolicyLinkProviderTypeCol = "provider_type" -) - func (p *IDPLoginPolicyLinkProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { var ( idp policy.IdentityProviderAddedEvent @@ -105,8 +117,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceAdded(event eventstore.Event) (*han idp = e.IdentityProviderAddedEvent providerType = domain.IdentityProviderTypeSystem default: - logging.LogWithFields("HANDL-oce92", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyIDPProviderAddedEventType, iam.LoginPolicyIDPProviderAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Nlp55", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Nlp55", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyIDPProviderAddedEventType, iam.LoginPolicyIDPProviderAddedEventType}) } return crdb.NewCreateStatement(&idp, @@ -117,6 +128,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceAdded(event eventstore.Event) (*han handler.NewCol(IDPLoginPolicyLinkChangeDateCol, idp.CreationDate()), handler.NewCol(IDPLoginPolicyLinkSequenceCol, idp.Sequence()), handler.NewCol(IDPLoginPolicyLinkResourceOwnerCol, idp.Aggregate().ResourceOwner), + handler.NewCol(IDPLoginPolicyLinkInstanceIDCol, idp.Aggregate().InstanceID), handler.NewCol(IDPLoginPolicyLinkProviderTypeCol, providerType), }, ), nil @@ -131,8 +143,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceRemoved(event eventstore.Event) (*h case *iam.IdentityProviderRemovedEvent: idp = e.IdentityProviderRemovedEvent default: - logging.LogWithFields("HANDL-vAH3I", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyIDPProviderRemovedEventType, iam.LoginPolicyIDPProviderRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-tUMYY", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-tUMYY", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyIDPProviderRemovedEventType, iam.LoginPolicyIDPProviderRemovedEventType}) } return crdb.NewDeleteStatement(&idp, @@ -152,8 +163,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceCascadeRemoved(event eventstore.Eve case *iam.IdentityProviderCascadeRemovedEvent: idp = e.IdentityProviderCascadeRemovedEvent default: - logging.LogWithFields("HANDL-7lZaf", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyIDPProviderCascadeRemovedEventType, iam.LoginPolicyIDPProviderCascadeRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-iCKSj", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-iCKSj", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyIDPProviderCascadeRemovedEventType, iam.LoginPolicyIDPProviderCascadeRemovedEventType}) } return crdb.NewDeleteStatement(&idp, @@ -173,8 +183,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceIDPConfigRemoved(event eventstore.E case *iam.IDPConfigRemovedEvent: idpID = e.ConfigID default: - logging.LogWithFields("HANDL-aJvob", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-u6tze", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-u6tze", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}) } return crdb.NewDeleteStatement(event, @@ -188,8 +197,7 @@ func (p *IDPLoginPolicyLinkProjection) reduceIDPConfigRemoved(event eventstore.E func (p *IDPLoginPolicyLinkProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgRemovedEvent) if !ok { - logging.LogWithFields("HANDL-WTYC1", "seq", event.Sequence(), "expectedType", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-QSoSe", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-QSoSe", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } return crdb.NewDeleteStatement(e, []handler.Condition{ diff --git a/internal/query/projection/idp_login_policy_link_test.go b/internal/query/projection/idp_login_policy_link_test.go index 2237b681b0..4a80ef71fe 100644 --- a/internal/query/projection/idp_login_policy_link_test.go +++ b/internal/query/projection/idp_login_policy_link_test.go @@ -43,7 +43,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -51,6 +51,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", domain.IdentityProviderTypeSystem, }, }, @@ -79,7 +80,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -110,7 +111,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -141,7 +142,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.idp_login_policy_links (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -149,6 +150,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", domain.IdentityProviderTypeOrg, }, }, @@ -177,7 +179,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -208,7 +210,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (aggregate_id = $2)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -236,7 +238,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (resource_owner = $1)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (resource_owner = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -265,7 +267,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ "idp-config-id", "ro-id", @@ -295,7 +297,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)", + expectedStmt: "DELETE FROM projections.idp_login_policy_links WHERE (idp_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ "idp-config-id", "ro-id", diff --git a/internal/query/projection/idp_test.go b/internal/query/projection/idp_test.go index eb039b6dc5..2d96e74e1e 100644 --- a/internal/query/projection/idp_test.go +++ b/internal/query/projection/idp_test.go @@ -3,6 +3,8 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -10,7 +12,6 @@ import ( "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/repository/org" - "github.com/lib/pq" ) func TestIDPProjection_reduces(t *testing.T) { @@ -47,13 +48,14 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.idps (id, creation_date, change_date, sequence, resource_owner, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.idps (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "idp-config-id", anyArg{}, anyArg{}, uint64(15), "ro-id", + "instance-id", domain.IDPConfigStateActive, "custom-zitadel-instance", domain.IDPConfigStylingTypeUnspecified, @@ -88,7 +90,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)", + expectedStmt: "UPDATE projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)", expectedArgs: []interface{}{ "custom-zitadel-instance", domain.IDPConfigStylingTypeGoogle, @@ -122,7 +124,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.IDPConfigStateInactive, anyArg{}, @@ -154,7 +156,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.IDPConfigStateActive, anyArg{}, @@ -186,7 +188,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idps WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.idps WHERE (id = $1)", expectedArgs: []interface{}{ "idp-config-id", }, @@ -227,7 +229,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -236,7 +238,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "idp-config-id", "client-id", @@ -285,7 +287,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -293,7 +295,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)", + expectedStmt: "UPDATE projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)", expectedArgs: []interface{}{ "client-id", anyArg{}, @@ -354,7 +356,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -363,7 +365,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)", + expectedStmt: "INSERT INTO projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)", expectedArgs: []interface{}{ "idp-config-id", "https://api.zitadel.ch/jwt", @@ -400,7 +402,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -408,7 +410,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)", + expectedStmt: "UPDATE projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)", expectedArgs: []interface{}{ "https://api.zitadel.ch/jwt", "issuer", @@ -465,13 +467,14 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.idps (id, creation_date, change_date, sequence, resource_owner, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.idps (id, creation_date, change_date, sequence, resource_owner, instance_id, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "idp-config-id", anyArg{}, anyArg{}, uint64(15), "ro-id", + "instance-id", domain.IDPConfigStateActive, "custom-zitadel-instance", domain.IDPConfigStylingTypeUnspecified, @@ -506,7 +509,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)", + expectedStmt: "UPDATE projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)", expectedArgs: []interface{}{ "custom-zitadel-instance", domain.IDPConfigStylingTypeGoogle, @@ -540,7 +543,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.IDPConfigStateInactive, anyArg{}, @@ -572,7 +575,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.IDPConfigStateActive, anyArg{}, @@ -604,7 +607,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idps WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.idps WHERE (id = $1)", expectedArgs: []interface{}{ "idp-config-id", }, @@ -645,7 +648,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -654,7 +657,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "idp-config-id", "client-id", @@ -703,7 +706,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -711,7 +714,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)", + expectedStmt: "UPDATE projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)", expectedArgs: []interface{}{ "client-id", anyArg{}, @@ -772,7 +775,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -781,7 +784,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)", + expectedStmt: "INSERT INTO projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)", expectedArgs: []interface{}{ "idp-config-id", "https://api.zitadel.ch/jwt", @@ -818,7 +821,7 @@ func TestIDPProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -826,7 +829,7 @@ func TestIDPProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)", + expectedStmt: "UPDATE projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)", expectedArgs: []interface{}{ "https://api.zitadel.ch/jwt", "issuer", diff --git a/internal/query/projection/idp_user_link.go b/internal/query/projection/idp_user_link.go index 121c35fe68..462b05eee7 100644 --- a/internal/query/projection/idp_user_link.go +++ b/internal/query/projection/idp_user_link.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -13,6 +12,19 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + IDPUserLinkTable = "projections.idp_user_links" + IDPUserLinkIDPIDCol = "idp_id" + IDPUserLinkUserIDCol = "user_id" + IDPUserLinkExternalUserIDCol = "external_user_id" + IDPUserLinkCreationDateCol = "creation_date" + IDPUserLinkChangeDateCol = "change_date" + IDPUserLinkSequenceCol = "sequence" + IDPUserLinkResourceOwnerCol = "resource_owner" + IDPUserLinkInstanceIDCol = "instance_id" + IDPUserLinkDisplayNameCol = "display_name" +) + type IDPUserLinkProjection struct { crdb.StatementHandler } @@ -21,6 +33,22 @@ func NewIDPUserLinkProjection(ctx context.Context, config crdb.StatementHandlerC p := new(IDPUserLinkProjection) config.ProjectionName = IDPUserLinkTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(IDPUserLinkIDPIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPUserLinkUserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPUserLinkExternalUserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPUserLinkCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPUserLinkChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(IDPUserLinkSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(IDPUserLinkResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPUserLinkInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(IDPUserLinkDisplayNameCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(IDPUserLinkInstanceIDCol, IDPUserLinkIDPIDCol, IDPUserLinkExternalUserIDCol), + crdb.NewIndex("user_idx", []string{IDPUserLinkUserIDCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -73,23 +101,10 @@ func (p *IDPUserLinkProjection) reducers() []handler.AggregateReducer { } } -const ( - IDPUserLinkTable = "zitadel.projections.idp_user_links" - IDPUserLinkIDPIDCol = "idp_id" - IDPUserLinkUserIDCol = "user_id" - IDPUserLinkExternalUserIDCol = "external_user_id" - IDPUserLinkCreationDateCol = "creation_date" - IDPUserLinkChangeDateCol = "change_date" - IDPUserLinkSequenceCol = "sequence" - IDPUserLinkResourceOwnerCol = "resource_owner" - IDPUserLinkDisplayNameCol = "display_name" -) - func (p *IDPUserLinkProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserIDPLinkAddedEvent) if !ok { - logging.LogWithFields("HANDL-v2qC3", "seq", event.Sequence(), "expectedType", user.UserIDPLinkAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-DpmXq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-DpmXq", "reduce.wrong.event.type %s", user.UserIDPLinkAddedType) } return crdb.NewCreateStatement(e, @@ -101,6 +116,7 @@ func (p *IDPUserLinkProjection) reduceAdded(event eventstore.Event) (*handler.St handler.NewCol(IDPUserLinkChangeDateCol, e.CreationDate()), handler.NewCol(IDPUserLinkSequenceCol, e.Sequence()), handler.NewCol(IDPUserLinkResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(IDPUserLinkInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(IDPUserLinkDisplayNameCol, e.DisplayName), }, ), nil @@ -109,8 +125,7 @@ func (p *IDPUserLinkProjection) reduceAdded(event eventstore.Event) (*handler.St func (p *IDPUserLinkProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserIDPLinkRemovedEvent) if !ok { - logging.LogWithFields("HANDL-zX5m9", "seq", event.Sequence(), "expectedType", user.UserIDPLinkRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-AZmfJ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-AZmfJ", "reduce.wrong.event.type %s", user.UserIDPLinkRemovedType) } return crdb.NewDeleteStatement(e, @@ -125,8 +140,7 @@ func (p *IDPUserLinkProjection) reduceRemoved(event eventstore.Event) (*handler. func (p *IDPUserLinkProjection) reduceCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserIDPLinkCascadeRemovedEvent) if !ok { - logging.LogWithFields("HANDL-I0s2H", "seq", event.Sequence(), "expectedType", user.UserIDPLinkCascadeRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-jQpv9", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-jQpv9", "reduce.wrong.event.type %s", user.UserIDPLinkCascadeRemovedType) } return crdb.NewDeleteStatement(e, @@ -141,8 +155,7 @@ func (p *IDPUserLinkProjection) reduceCascadeRemoved(event eventstore.Event) (*h func (p *IDPUserLinkProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgRemovedEvent) if !ok { - logging.LogWithFields("HANDL-zX5m9", "seq", event.Sequence(), "expectedType", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-AZmfJ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-AZmfJ", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } return crdb.NewDeleteStatement(e, @@ -155,8 +168,7 @@ func (p *IDPUserLinkProjection) reduceOrgRemoved(event eventstore.Event) (*handl func (p *IDPUserLinkProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-yM6u6", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uwlWE", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uwlWE", "reduce.wrong.event.type %s", user.UserRemovedType) } return crdb.NewDeleteStatement(e, @@ -175,8 +187,7 @@ func (p *IDPUserLinkProjection) reduceIDPConfigRemoved(event eventstore.Event) ( case *iam.IDPConfigRemovedEvent: idpID = e.ConfigID default: - logging.LogWithFields("HANDL-7lZaf", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-iCKSj", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-iCKSj", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}) } return crdb.NewDeleteStatement(event, diff --git a/internal/query/projection/idp_user_link_test.go b/internal/query/projection/idp_user_link_test.go index 99b081f9cb..892b4c4cc9 100644 --- a/internal/query/projection/idp_user_link_test.go +++ b/internal/query/projection/idp_user_link_test.go @@ -44,7 +44,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.idp_user_links (idp_id, user_id, external_user_id, creation_date, change_date, sequence, resource_owner, display_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.idp_user_links (idp_id, user_id, external_user_id, creation_date, change_date, sequence, resource_owner, instance_id, display_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -53,6 +53,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", "gigi@caos.ch", }, }, @@ -81,7 +82,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -113,7 +114,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3)", expectedArgs: []interface{}{ "idp-config-id", "agg-id", @@ -142,7 +143,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (resource_owner = $1)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (resource_owner = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -169,7 +170,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -198,7 +199,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ "idp-config-id", "ro-id", @@ -228,7 +229,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)", + expectedStmt: "DELETE FROM projections.idp_user_links WHERE (idp_id = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ "idp-config-id", "ro-id", diff --git a/internal/query/projection/key.go b/internal/query/projection/key.go index 0aaa756ddf..c9173825a1 100644 --- a/internal/query/projection/key.go +++ b/internal/query/projection/key.go @@ -4,8 +4,6 @@ import ( "context" "time" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,22 +12,71 @@ import ( "github.com/caos/zitadel/internal/repository/keypair" ) +const ( + KeyProjectionTable = "projections.keys" + KeyPrivateTable = KeyProjectionTable + "_" + privateKeyTableSuffix + KeyPublicTable = KeyProjectionTable + "_" + publicKeyTableSuffix + + KeyColumnID = "id" + KeyColumnCreationDate = "creation_date" + KeyColumnChangeDate = "change_date" + KeyColumnResourceOwner = "resource_owner" + KeyColumnInstanceID = "instance_id" + KeyColumnSequence = "sequence" + KeyColumnAlgorithm = "algorithm" + KeyColumnUse = "use" + + privateKeyTableSuffix = "private" + KeyPrivateColumnID = "id" + KeyPrivateColumnExpiry = "expiry" + KeyPrivateColumnKey = "key" + + publicKeyTableSuffix = "public" + KeyPublicColumnID = "id" + KeyPublicColumnExpiry = "expiry" + KeyPublicColumnKey = "key" +) + type KeyProjection struct { crdb.StatementHandler encryptionAlgorithm crypto.EncryptionAlgorithm keyChan chan<- interface{} } -const ( - KeyProjectionTable = "zitadel.projections.keys" - KeyPrivateTable = KeyProjectionTable + "_" + privateKeyTableSuffix - KeyPublicTable = KeyProjectionTable + "_" + publicKeyTableSuffix -) - func NewKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, keyEncryptionAlgorithm crypto.EncryptionAlgorithm, keyChan chan<- interface{}) *KeyProjection { p := new(KeyProjection) config.ProjectionName = KeyProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(KeyColumnID, crdb.ColumnTypeText), + crdb.NewColumn(KeyColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(KeyColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(KeyColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(KeyColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(KeyColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(KeyColumnAlgorithm, crdb.ColumnTypeText, crdb.Default("")), + crdb.NewColumn(KeyColumnUse, crdb.ColumnTypeText, crdb.Default("")), + }, + crdb.NewPrimaryKey(KeyColumnInstanceID, KeyColumnID), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(KeyPrivateColumnID, crdb.ColumnTypeText, crdb.DeleteCascade(KeyColumnID)), + crdb.NewColumn(KeyPrivateColumnExpiry, crdb.ColumnTypeTimestamp), + crdb.NewColumn(KeyPrivateColumnKey, crdb.ColumnTypeJSONB), + }, + crdb.NewPrimaryKey(KeyPrivateColumnID), + privateKeyTableSuffix, + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(KeyPublicColumnID, crdb.ColumnTypeText, crdb.DeleteCascade(KeyColumnID)), + crdb.NewColumn(KeyPublicColumnExpiry, crdb.ColumnTypeTimestamp), + crdb.NewColumn(KeyPublicColumnKey, crdb.ColumnTypeBytes), + }, + crdb.NewPrimaryKey(KeyPublicColumnID), + publicKeyTableSuffix, + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) p.keyChan = keyChan p.encryptionAlgorithm = keyEncryptionAlgorithm @@ -51,31 +98,10 @@ func (p *KeyProjection) reducers() []handler.AggregateReducer { } } -const ( - KeyColumnID = "id" - KeyColumnCreationDate = "creation_date" - KeyColumnChangeDate = "change_date" - KeyColumnResourceOwner = "resource_owner" - KeyColumnSequence = "sequence" - KeyColumnAlgorithm = "algorithm" - KeyColumnUse = "use" - - privateKeyTableSuffix = "private" - KeyPrivateColumnID = "id" - KeyPrivateColumnExpiry = "expiry" - KeyPrivateColumnKey = "key" - - publicKeyTableSuffix = "public" - KeyPublicColumnID = "id" - KeyPublicColumnExpiry = "expiry" - KeyPublicColumnKey = "key" -) - func (p *KeyProjection) reduceKeyPairAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*keypair.AddedEvent) if !ok { - logging.LogWithFields("HANDL-GEdg3", "seq", event.Sequence(), "expectedType", keypair.AddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-SAbr2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-SAbr2", "reduce.wrong.event.type %s", keypair.AddedEventType) } if e.PrivateKey.Expiry.Before(time.Now()) && e.PublicKey.Expiry.Before(time.Now()) { return crdb.NewNoOpStatement(e), nil @@ -87,6 +113,7 @@ func (p *KeyProjection) reduceKeyPairAdded(event eventstore.Event) (*handler.Sta handler.NewCol(KeyColumnCreationDate, e.CreationDate()), handler.NewCol(KeyColumnChangeDate, e.CreationDate()), handler.NewCol(KeyColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(KeyColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(KeyColumnSequence, e.Sequence()), handler.NewCol(KeyColumnAlgorithm, e.Algorithm), handler.NewCol(KeyColumnUse, e.Usage), @@ -109,7 +136,6 @@ func (p *KeyProjection) reduceKeyPairAdded(event eventstore.Event) (*handler.Sta if e.PublicKey.Expiry.After(time.Now()) { publicKey, err := crypto.Decrypt(e.PublicKey.Key, p.encryptionAlgorithm) if err != nil { - logging.LogWithFields("HANDL-SDfw2", "seq", event.Sequence()).Error("cannot decrypt public key") return nil, errors.ThrowInternal(err, "HANDL-DAg2f", "cannot decrypt public key") } creates = append(creates, crdb.AddCreateStatement( diff --git a/internal/query/projection/key_test.go b/internal/query/projection/key_test.go index b1f981ff8a..3d215e10a6 100644 --- a/internal/query/projection/key_test.go +++ b/internal/query/projection/key_test.go @@ -43,19 +43,20 @@ func TestKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.keys (id, creation_date, change_date, resource_owner, sequence, algorithm, use) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.keys (id, creation_date, change_date, resource_owner, instance_id, sequence, algorithm, use) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "algorithm", domain.KeyUsageSigning, }, }, { - expectedStmt: "INSERT INTO zitadel.projections.keys_private (id, expiry, key) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.keys_private (id, expiry, key) VALUES ($1, $2, $3)", expectedArgs: []interface{}{ "agg-id", anyArg{}, @@ -68,7 +69,7 @@ func TestKeyProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.keys_public (id, expiry, key) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.keys_public (id, expiry, key) VALUES ($1, $2, $3)", expectedArgs: []interface{}{ "agg-id", anyArg{}, diff --git a/internal/query/projection/label_policy.go b/internal/query/projection/label_policy.go index 9bad47e24a..7f6bafad0c 100644 --- a/internal/query/projection/label_policy.go +++ b/internal/query/projection/label_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,18 +13,75 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) +const ( + LabelPolicyTable = "projections.label_policies" + + LabelPolicyIDCol = "id" + LabelPolicyCreationDateCol = "creation_date" + LabelPolicyChangeDateCol = "change_date" + LabelPolicySequenceCol = "sequence" + LabelPolicyStateCol = "state" + LabelPolicyIsDefaultCol = "is_default" + LabelPolicyResourceOwnerCol = "resource_owner" + LabelPolicyInstanceIDCol = "instance_id" + LabelPolicyHideLoginNameSuffixCol = "hide_login_name_suffix" + LabelPolicyWatermarkDisabledCol = "watermark_disabled" + LabelPolicyShouldErrorPopupCol = "should_error_popup" + LabelPolicyFontURLCol = "font_url" + + LabelPolicyLightPrimaryColorCol = "light_primary_color" + LabelPolicyLightWarnColorCol = "light_warn_color" + LabelPolicyLightBackgroundColorCol = "light_background_color" + LabelPolicyLightFontColorCol = "light_font_color" + LabelPolicyLightLogoURLCol = "light_logo_url" + LabelPolicyLightIconURLCol = "light_icon_url" + + LabelPolicyDarkPrimaryColorCol = "dark_primary_color" + LabelPolicyDarkWarnColorCol = "dark_warn_color" + LabelPolicyDarkBackgroundColorCol = "dark_background_color" + LabelPolicyDarkFontColorCol = "dark_font_color" + LabelPolicyDarkLogoURLCol = "dark_logo_url" + LabelPolicyDarkIconURLCol = "dark_icon_url" +) + type LabelPolicyProjection struct { crdb.StatementHandler } -const ( - LabelPolicyTable = "zitadel.projections.label_policies" -) - func NewLabelPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LabelPolicyProjection { p := new(LabelPolicyProjection) config.ProjectionName = LabelPolicyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(LabelPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LabelPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LabelPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LabelPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(LabelPolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(LabelPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LabelPolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(LabelPolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LabelPolicyHideLoginNameSuffixCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LabelPolicyWatermarkDisabledCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LabelPolicyShouldErrorPopupCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LabelPolicyFontURLCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightPrimaryColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightWarnColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightBackgroundColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightFontColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightLogoURLCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyLightIconURLCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkPrimaryColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkWarnColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkBackgroundColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkFontColorCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkLogoURLCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(LabelPolicyDarkIconURLCol, crdb.ColumnTypeText, crdb.Nullable()), + }, + crdb.NewPrimaryKey(LabelPolicyInstanceIDCol, LabelPolicyIDCol, LabelPolicyStateCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -172,8 +228,7 @@ func (p *LabelPolicyProjection) reduceAdded(event eventstore.Event) (*handler.St policyEvent = e.LabelPolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-zR6h0", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyAddedEventType, iam.LabelPolicyAddedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-CSE7A", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-CSE7A", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyAddedEventType, iam.LabelPolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -185,6 +240,7 @@ func (p *LabelPolicyProjection) reduceAdded(event eventstore.Event) (*handler.St handler.NewCol(LabelPolicyStateCol, domain.LabelPolicyStatePreview), handler.NewCol(LabelPolicyIsDefaultCol, isDefault), handler.NewCol(LabelPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(LabelPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), handler.NewCol(LabelPolicyLightPrimaryColorCol, policyEvent.PrimaryColor), handler.NewCol(LabelPolicyLightBackgroundColorCol, policyEvent.BackgroundColor), handler.NewCol(LabelPolicyLightWarnColorCol, policyEvent.WarnColor), @@ -207,8 +263,7 @@ func (p *LabelPolicyProjection) reduceChanged(event eventstore.Event) (*handler. case *iam.LabelPolicyChangedEvent: policyEvent = e.LabelPolicyChangedEvent default: - logging.LogWithFields("PROJE-2VrlG", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyChangedEventType, iam.LabelPolicyChangedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-qgVug", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-qgVug", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyChangedEventType, iam.LabelPolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(LabelPolicyChangeDateCol, policyEvent.CreationDate()), @@ -259,8 +314,7 @@ func (p *LabelPolicyProjection) reduceChanged(event eventstore.Event) (*handler. func (p *LabelPolicyProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.LabelPolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-izDbs", "seq", event.Sequence(), "expectedType", org.LabelPolicyRemovedEventType).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-ATMBz", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-ATMBz", "reduce.wrong.event.type %s", org.LabelPolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, @@ -274,8 +328,7 @@ func (p *LabelPolicyProjection) reduceActivated(event eventstore.Event) (*handle case *org.LabelPolicyActivatedEvent, *iam.LabelPolicyActivatedEvent: // everything ok default: - logging.LogWithFields("PROJE-ZQO7J", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyActivatedEventType, iam.LabelPolicyActivatedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-dldEU", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dldEU", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyActivatedEventType, iam.LabelPolicyActivatedEventType}) } return crdb.NewCopyStatement( event, @@ -322,8 +375,7 @@ func (p *LabelPolicyProjection) reduceLogoAdded(event eventstore.Event) (*handle case *iam.LabelPolicyLogoDarkAddedEvent: storeKey = handler.NewCol(LabelPolicyDarkLogoURLCol, e.StoreKey) default: - logging.LogWithFields("PROJE-NHrbi", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyLogoAddedEventType, iam.LabelPolicyLogoAddedEventType, org.LabelPolicyLogoDarkAddedEventType, iam.LabelPolicyLogoDarkAddedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-4wbOI", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-4wbOI", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyLogoAddedEventType, iam.LabelPolicyLogoAddedEventType, org.LabelPolicyLogoDarkAddedEventType, iam.LabelPolicyLogoDarkAddedEventType}) } return crdb.NewUpdateStatement( @@ -351,8 +403,7 @@ func (p *LabelPolicyProjection) reduceLogoRemoved(event eventstore.Event) (*hand case *iam.LabelPolicyLogoDarkRemovedEvent: col = LabelPolicyDarkLogoURLCol default: - logging.LogWithFields("PROJE-oUmnS", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyLogoRemovedEventType, iam.LabelPolicyLogoRemovedEventType, org.LabelPolicyLogoDarkRemovedEventType, iam.LabelPolicyLogoDarkRemovedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-kg8H4", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-kg8H4", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyLogoRemovedEventType, iam.LabelPolicyLogoRemovedEventType, org.LabelPolicyLogoDarkRemovedEventType, iam.LabelPolicyLogoDarkRemovedEventType}) } return crdb.NewUpdateStatement( @@ -380,8 +431,7 @@ func (p *LabelPolicyProjection) reduceIconAdded(event eventstore.Event) (*handle case *iam.LabelPolicyIconDarkAddedEvent: storeKey = handler.NewCol(LabelPolicyDarkIconURLCol, e.StoreKey) default: - logging.LogWithFields("PROJE-6efFw", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyIconAddedEventType, iam.LabelPolicyIconAddedEventType, org.LabelPolicyIconDarkAddedEventType, iam.LabelPolicyIconDarkAddedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-e2JFz", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-e2JFz", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyIconAddedEventType, iam.LabelPolicyIconAddedEventType, org.LabelPolicyIconDarkAddedEventType, iam.LabelPolicyIconDarkAddedEventType}) } return crdb.NewUpdateStatement( @@ -409,8 +459,7 @@ func (p *LabelPolicyProjection) reduceIconRemoved(event eventstore.Event) (*hand case *iam.LabelPolicyIconDarkRemovedEvent: col = LabelPolicyDarkIconURLCol default: - logging.LogWithFields("PROJE-0BiAZ", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyIconRemovedEventType, iam.LabelPolicyIconRemovedEventType, org.LabelPolicyIconDarkRemovedEventType, iam.LabelPolicyIconDarkRemovedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-gfgbY", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-gfgbY", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyIconRemovedEventType, iam.LabelPolicyIconRemovedEventType, org.LabelPolicyIconDarkRemovedEventType, iam.LabelPolicyIconDarkRemovedEventType}) } return crdb.NewUpdateStatement( @@ -434,8 +483,7 @@ func (p *LabelPolicyProjection) reduceFontAdded(event eventstore.Event) (*handle case *iam.LabelPolicyFontAddedEvent: storeKey = handler.NewCol(LabelPolicyFontURLCol, e.StoreKey) default: - logging.LogWithFields("PROJE-DCzfX", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyFontAddedEventType, iam.LabelPolicyFontAddedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-65i9W", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-65i9W", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyFontAddedEventType, iam.LabelPolicyFontAddedEventType}) } return crdb.NewUpdateStatement( @@ -459,8 +507,7 @@ func (p *LabelPolicyProjection) reduceFontRemoved(event eventstore.Event) (*hand case *iam.LabelPolicyFontRemovedEvent: col = LabelPolicyFontURLCol default: - logging.LogWithFields("PROJE-YKwG4", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyFontRemovedEventType, iam.LabelPolicyFontRemovedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-xf32J", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-xf32J", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyFontRemovedEventType, iam.LabelPolicyFontRemovedEventType}) } return crdb.NewUpdateStatement( @@ -481,8 +528,7 @@ func (p *LabelPolicyProjection) reduceAssetsRemoved(event eventstore.Event) (*ha case *org.LabelPolicyAssetsRemovedEvent, *iam.LabelPolicyAssetsRemovedEvent: //ok default: - logging.LogWithFields("PROJE-YKwG4", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LabelPolicyAssetsRemovedEventType, iam.LabelPolicyAssetsRemovedEventType}).Error("was not an event") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-qi39A", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-qi39A", "reduce.wrong.event.type %v", []eventstore.EventType{org.LabelPolicyAssetsRemovedEventType, iam.LabelPolicyAssetsRemovedEventType}) } return crdb.NewUpdateStatement( @@ -501,31 +547,3 @@ func (p *LabelPolicyProjection) reduceAssetsRemoved(event eventstore.Event) (*ha handler.NewCond(LabelPolicyStateCol, domain.LabelPolicyStatePreview), }), nil } - -const ( - LabelPolicyCreationDateCol = "creation_date" - LabelPolicyChangeDateCol = "change_date" - LabelPolicySequenceCol = "sequence" - LabelPolicyIDCol = "id" - LabelPolicyStateCol = "state" - LabelPolicyIsDefaultCol = "is_default" - LabelPolicyResourceOwnerCol = "resource_owner" - LabelPolicyHideLoginNameSuffixCol = "hide_login_name_suffix" - LabelPolicyFontURLCol = "font_url" - LabelPolicyWatermarkDisabledCol = "watermark_disabled" - LabelPolicyShouldErrorPopupCol = "should_error_popup" - - LabelPolicyLightPrimaryColorCol = "light_primary_color" - LabelPolicyLightWarnColorCol = "light_warn_color" - LabelPolicyLightBackgroundColorCol = "light_background_color" - LabelPolicyLightFontColorCol = "light_font_color" - LabelPolicyLightLogoURLCol = "light_logo_url" - LabelPolicyLightIconURLCol = "light_icon_url" - - LabelPolicyDarkPrimaryColorCol = "dark_primary_color" - LabelPolicyDarkWarnColorCol = "dark_warn_color" - LabelPolicyDarkBackgroundColorCol = "dark_background_color" - LabelPolicyDarkFontColorCol = "dark_font_color" - LabelPolicyDarkLogoURLCol = "dark_logo_url" - LabelPolicyDarkIconURLCol = "dark_icon_url" -) diff --git a/internal/query/projection/label_policy_test.go b/internal/query/projection/label_policy_test.go index 4fa4f145ba..589d0dfca9 100644 --- a/internal/query/projection/label_policy_test.go +++ b/internal/query/projection/label_policy_test.go @@ -40,7 +40,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.label_policies (creation_date, change_date, sequence, id, state, is_default, resource_owner, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)", + expectedStmt: "INSERT INTO projections.label_policies (creation_date, change_date, sequence, id, state, is_default, resource_owner, instance_id, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -49,6 +49,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { domain.LabelPolicyStatePreview, false, "ro-id", + "instance-id", "#5282c1", "#141735", "#ff3b5b", @@ -84,7 +85,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_primary_color, light_background_color, light_warn_color, light_font_color) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (state = $8)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_primary_color, light_background_color, light_warn_color, light_font_color) = ($1, $2, $3, $4, $5, $6) WHERE (id = $7) AND (state = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -118,7 +119,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.label_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.label_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -145,7 +146,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.label_policies (change_date, sequence, state, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM zitadel.projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5", + expectedStmt: "UPSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -176,7 +177,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -207,7 +208,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -238,7 +239,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -269,7 +270,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -300,7 +301,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -331,7 +332,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -362,7 +363,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -393,7 +394,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -424,7 +425,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -455,7 +456,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -486,7 +487,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url, light_icon_url, dark_logo_url, dark_icon_url, font_url) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (state = $9)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url, light_icon_url, dark_logo_url, dark_icon_url, font_url) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (state = $9)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -521,7 +522,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.label_policies (creation_date, change_date, sequence, id, state, is_default, resource_owner, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)", + expectedStmt: "INSERT INTO projections.label_policies (creation_date, change_date, sequence, id, state, is_default, resource_owner, instance_id, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -530,6 +531,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { domain.LabelPolicyStatePreview, true, "ro-id", + "instance-id", "#5282c1", "#141735", "#ff3b5b", @@ -565,7 +567,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (id = $14) AND (state = $15)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_primary_color, light_background_color, light_warn_color, light_font_color, dark_primary_color, dark_background_color, dark_warn_color, dark_font_color, hide_login_name_suffix, should_error_popup, watermark_disabled) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (id = $14) AND (state = $15)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -606,7 +608,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.label_policies (change_date, sequence, state, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM zitadel.projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5", + expectedStmt: "UPSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url) SELECT $1, $2, $3, creation_date, resource_owner, id, is_default, hide_login_name_suffix, font_url, watermark_disabled, should_error_popup, light_primary_color, light_warn_color, light_background_color, light_font_color, light_logo_url, light_icon_url, dark_primary_color, dark_warn_color, dark_background_color, dark_font_color, dark_logo_url, dark_icon_url FROM projections.label_policies AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -637,7 +639,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -668,7 +670,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -699,7 +701,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -730,7 +732,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -761,7 +763,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -792,7 +794,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -823,7 +825,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -854,7 +856,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -885,7 +887,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -916,7 +918,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -947,7 +949,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.label_policies SET (change_date, sequence, light_logo_url, light_icon_url, dark_logo_url, dark_icon_url, font_url) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (state = $9)", + expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url, light_icon_url, dark_logo_url, dark_icon_url, font_url) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (state = $9)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/lockout_policy.go b/internal/query/projection/lockout_policy.go index 9805542f64..cec10b89c9 100644 --- a/internal/query/projection/lockout_policy.go +++ b/internal/query/projection/lockout_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,28 +13,45 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type LockoutPolicyProjection struct { - crdb.StatementHandler -} - const ( - LockoutPolicyTable = "zitadel.projections.lockout_policies" + LockoutPolicyTable = "projections.lockout_policies" + LockoutPolicyIDCol = "id" LockoutPolicyCreationDateCol = "creation_date" LockoutPolicyChangeDateCol = "change_date" LockoutPolicySequenceCol = "sequence" - LockoutPolicyIDCol = "id" LockoutPolicyStateCol = "state" - LockoutPolicyMaxPasswordAttemptsCol = "max_password_attempts" - LockoutPolicyShowLockOutFailuresCol = "show_failure" LockoutPolicyIsDefaultCol = "is_default" LockoutPolicyResourceOwnerCol = "resource_owner" + LockoutPolicyInstanceIDCol = "instance_id" + LockoutPolicyMaxPasswordAttemptsCol = "max_password_attempts" + LockoutPolicyShowLockOutFailuresCol = "show_failure" ) +type LockoutPolicyProjection struct { + crdb.StatementHandler +} + func NewLockoutPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LockoutPolicyProjection { p := new(LockoutPolicyProjection) config.ProjectionName = LockoutPolicyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(LockoutPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LockoutPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LockoutPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LockoutPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(LockoutPolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(LockoutPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LockoutPolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(LockoutPolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LockoutPolicyMaxPasswordAttemptsCol, crdb.ColumnTypeInt64), + crdb.NewColumn(LockoutPolicyShowLockOutFailuresCol, crdb.ColumnTypeBool), + }, + crdb.NewPrimaryKey(LockoutPolicyInstanceIDCol, LockoutPolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -86,8 +102,7 @@ func (p *LockoutPolicyProjection) reduceAdded(event eventstore.Event) (*handler. policyEvent = e.LockoutPolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-uFqFM", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LockoutPolicyAddedEventType, iam.LockoutPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-d8mZO", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-d8mZO", "reduce.wrong.event.type, %v", []eventstore.EventType{org.LockoutPolicyAddedEventType, iam.LockoutPolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -101,6 +116,7 @@ func (p *LockoutPolicyProjection) reduceAdded(event eventstore.Event) (*handler. handler.NewCol(LockoutPolicyShowLockOutFailuresCol, policyEvent.ShowLockOutFailures), handler.NewCol(LockoutPolicyIsDefaultCol, isDefault), handler.NewCol(LockoutPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(LockoutPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), }), nil } @@ -112,8 +128,7 @@ func (p *LockoutPolicyProjection) reduceChanged(event eventstore.Event) (*handle case *iam.LockoutPolicyChangedEvent: policyEvent = e.LockoutPolicyChangedEvent default: - logging.LogWithFields("PROJE-iIkej", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LockoutPolicyChangedEventType, iam.LockoutPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-pT3mQ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-pT3mQ", "reduce.wrong.event.type, %v", []eventstore.EventType{org.LockoutPolicyChangedEventType, iam.LockoutPolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(LockoutPolicyChangeDateCol, policyEvent.CreationDate()), @@ -136,8 +151,7 @@ func (p *LockoutPolicyProjection) reduceChanged(event eventstore.Event) (*handle func (p *LockoutPolicyProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.LockoutPolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-U5cys", "seq", event.Sequence(), "expectedType", org.LockoutPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Bqut9", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Bqut9", "reduce.wrong.event.type %s", org.LockoutPolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, diff --git a/internal/query/projection/lockout_policy_test.go b/internal/query/projection/lockout_policy_test.go index c9e015e514..d2b470708c 100644 --- a/internal/query/projection/lockout_policy_test.go +++ b/internal/query/projection/lockout_policy_test.go @@ -43,7 +43,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.lockout_policies (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.lockout_policies (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -54,6 +54,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { true, false, "ro-id", + "instance-id", }, }, }, @@ -81,7 +82,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -112,7 +113,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.lockout_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.lockout_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -142,7 +143,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.lockout_policies (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.lockout_policies (creation_date, change_date, sequence, id, state, max_password_attempts, show_failure, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -153,6 +154,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { true, true, "ro-id", + "instance-id", }, }, }, @@ -180,7 +182,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/login_name.go b/internal/query/projection/login_name.go index c7b1420e75..b53f275e39 100644 --- a/internal/query/projection/login_name.go +++ b/internal/query/projection/login_name.go @@ -2,8 +2,8 @@ package projection import ( "context" + "fmt" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -14,21 +14,117 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) -type LoginNameProjection struct { - crdb.StatementHandler -} - const ( - LoginNameProjectionTable = "zitadel.projections.login_names" + LoginNameProjectionTable = "projections.login_names" LoginNameUserProjectionTable = LoginNameProjectionTable + "_" + loginNameUserSuffix LoginNamePolicyProjectionTable = LoginNameProjectionTable + "_" + loginNamePolicySuffix LoginNameDomainProjectionTable = LoginNameProjectionTable + "_" + loginNameDomainSuffix + + LoginNameCol = "login_name" + + loginNameUserSuffix = "users" + LoginNameUserIDCol = "id" + LoginNameUserUserNameCol = "user_name" + LoginNameUserResourceOwnerCol = "resource_owner" + LoginNameUserInstanceIDCol = "instance_id" + + loginNameDomainSuffix = "domains" + LoginNameDomainNameCol = "name" + LoginNameDomainIsPrimaryCol = "is_primary" + LoginNameDomainResourceOwnerCol = "resource_owner" + LoginNameDomainInstanceIDCol = "instance_id" + + loginNamePolicySuffix = "policies" + LoginNamePoliciesMustBeDomainCol = "must_be_domain" + LoginNamePoliciesIsDefaultCol = "is_default" + LoginNamePoliciesResourceOwnerCol = "resource_owner" + LoginNamePoliciesInstanceIDCol = "instance_id" ) +var ( + viewStmt = fmt.Sprintf("SELECT"+ + " user_id"+ + " , IF(%[1]s, CONCAT(%[2]s, '@', domain), %[2]s) AS login_name"+ + " , IFNULL(%[3]s, true) AS %[3]s"+ + " , %[4]s"+ + " FROM ("+ + " SELECT"+ + " policy_users.user_id"+ + " , policy_users.%[2]s"+ + " , policy_users.%[5]s"+ + " , policy_users.%[4]s"+ + " , policy_users.%[1]s"+ + " , domains.%[6]s AS domain"+ + " , domains.%[3]s"+ + " FROM ("+ + " SELECT"+ + " users.id as user_id"+ + " , users.%[2]s"+ + " , users.%[4]s"+ + " , users.%[5]s"+ + " , IFNULL(policy_custom.%[1]s, policy_default.%[1]s) AS %[1]s"+ + " FROM %[7]s users"+ + " LEFT JOIN %[8]s policy_custom on policy_custom.%[9]s = users.%[5]s AND policy_custom.%[10]s = users.%[4]s"+ + " LEFT JOIN %[8]s policy_default on policy_default.%[11]s = true) policy_users"+ + " LEFT JOIN %[12]s domains ON policy_users.%[1]s AND policy_users.%[5]s = domains.%[13]s AND policy_users.%[10]s = domains.%[14]s"+ + ");", + LoginNamePoliciesMustBeDomainCol, + LoginNameUserUserNameCol, + LoginNameDomainIsPrimaryCol, + LoginNameUserInstanceIDCol, + LoginNameUserResourceOwnerCol, + LoginNameDomainNameCol, + LoginNameUserProjectionTable, + LoginNamePolicyProjectionTable, + LoginNamePoliciesResourceOwnerCol, + LoginNamePoliciesInstanceIDCol, + LoginNamePoliciesIsDefaultCol, + LoginNameDomainProjectionTable, + LoginNameDomainResourceOwnerCol, + LoginNameDomainInstanceIDCol, + ) +) + +type LoginNameProjection struct { + crdb.StatementHandler +} + func NewLoginNameProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginNameProjection { p := new(LoginNameProjection) config.ProjectionName = LoginNameProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewViewCheck( + viewStmt, + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(LoginNameUserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNameUserUserNameCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNameUserResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNameUserInstanceIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(LoginNameUserInstanceIDCol, LoginNameUserIDCol), + loginNameUserSuffix, + crdb.NewIndex("ro_idx", []string{LoginNameUserResourceOwnerCol}), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(LoginNameDomainNameCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNameDomainIsPrimaryCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginNameDomainResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNameDomainInstanceIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(LoginNameDomainInstanceIDCol, LoginNameDomainResourceOwnerCol, LoginNameDomainNameCol), + loginNameDomainSuffix, + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(LoginNamePoliciesMustBeDomainCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginNamePoliciesIsDefaultCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginNamePoliciesResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginNamePoliciesInstanceIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(LoginNamePoliciesInstanceIDCol, LoginNamePoliciesResourceOwnerCol), + loginNamePolicySuffix, + crdb.NewIndex("is_default_idx", []string{LoginNamePoliciesResourceOwnerCol, LoginNamePoliciesIsDefaultCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -120,25 +216,6 @@ func (p *LoginNameProjection) reducers() []handler.AggregateReducer { } } -const ( - LoginNameCol = "login_name" - - loginNameUserSuffix = "users" - LoginNameUserIDCol = "id" - LoginNameUserUserNameCol = "user_name" - LoginNameUserResourceOwnerCol = "resource_owner" - - loginNameDomainSuffix = "domains" - LoginNameDomainNameCol = "name" - LoginNameDomainIsPrimaryCol = "is_primary" - LoginNameDomainResourceOwnerCol = "resource_owner" - - loginNamePolicySuffix = "policies" - LoginNamePoliciesMustBeDomainCol = "must_be_domain" - LoginNamePoliciesIsDefaultCol = "is_default" - LoginNamePoliciesResourceOwnerCol = "resource_owner" -) - func (p *LoginNameProjection) reduceUserCreated(event eventstore.Event) (*handler.Statement, error) { var userName string @@ -150,8 +227,7 @@ func (p *LoginNameProjection) reduceUserCreated(event eventstore.Event) (*handle case *user.MachineAddedEvent: userName = e.UserName default: - logging.LogWithFields("HANDL-tDUx3", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{user.UserV1AddedType, user.HumanAddedType, user.UserV1RegisteredType, user.HumanRegisteredType, user.MachineAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ayo69", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ayo69", "reduce.wrong.event.type %v", []eventstore.EventType{user.UserV1AddedType, user.HumanAddedType, user.UserV1RegisteredType, user.HumanRegisteredType, user.MachineAddedEventType}) } return crdb.NewCreateStatement( @@ -160,6 +236,7 @@ func (p *LoginNameProjection) reduceUserCreated(event eventstore.Event) (*handle handler.NewCol(LoginNameUserIDCol, event.Aggregate().ID), handler.NewCol(LoginNameUserUserNameCol, userName), handler.NewCol(LoginNameUserResourceOwnerCol, event.Aggregate().ResourceOwner), + handler.NewCol(LoginNameUserInstanceIDCol, event.Aggregate().InstanceID), }, crdb.WithTableSuffix(loginNameUserSuffix), ), nil @@ -168,8 +245,7 @@ func (p *LoginNameProjection) reduceUserCreated(event eventstore.Event) (*handle func (p *LoginNameProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-8XEdC", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-QIe3C", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-QIe3C", "reduce.wrong.event.type %s", user.UserRemovedType) } return crdb.NewDeleteStatement( @@ -184,8 +260,7 @@ func (p *LoginNameProjection) reduceUserRemoved(event eventstore.Event) (*handle func (p *LoginNameProjection) reduceUserNameChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UsernameChangedEvent) if !ok { - logging.LogWithFields("HANDL-UGo7U", "seq", event.Sequence(), "expectedType", user.UserUserNameChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-QlwjC", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-QlwjC", "reduce.wrong.event.type %s", user.UserUserNameChangedType) } return crdb.NewUpdateStatement( @@ -203,8 +278,7 @@ func (p *LoginNameProjection) reduceUserNameChanged(event eventstore.Event) (*ha func (p *LoginNameProjection) reduceUserDomainClaimed(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.DomainClaimedEvent) if !ok { - logging.LogWithFields("HANDL-zIbyU", "seq", event.Sequence(), "expectedType", user.UserDomainClaimedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-AQMBY", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-AQMBY", "reduce.wrong.event.type %s", user.UserDomainClaimedType) } return crdb.NewUpdateStatement( @@ -233,8 +307,7 @@ func (p *LoginNameProjection) reduceOrgIAMPolicyAdded(event eventstore.Event) (* policyEvent = &e.OrgIAMPolicyAddedEvent isDefault = true default: - logging.LogWithFields("HANDL-PQluH", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.OrgIAMPolicyAddedEventType, iam.OrgIAMPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-yCV6S", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-yCV6S", "reduce.wrong.event.type %v", []eventstore.EventType{org.OrgIAMPolicyAddedEventType, iam.OrgIAMPolicyAddedEventType}) } return crdb.NewCreateStatement( @@ -243,6 +316,7 @@ func (p *LoginNameProjection) reduceOrgIAMPolicyAdded(event eventstore.Event) (* handler.NewCol(LoginNamePoliciesMustBeDomainCol, policyEvent.UserLoginMustBeDomain), handler.NewCol(LoginNamePoliciesIsDefaultCol, isDefault), handler.NewCol(LoginNamePoliciesResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(LoginNamePoliciesInstanceIDCol, policyEvent.Aggregate().InstanceID), }, crdb.WithTableSuffix(loginNamePolicySuffix), ), nil @@ -257,8 +331,7 @@ func (p *LoginNameProjection) reduceOrgIAMPolicyChanged(event eventstore.Event) case *iam.OrgIAMPolicyChangedEvent: policyEvent = &e.OrgIAMPolicyChangedEvent default: - logging.LogWithFields("HANDL-Z27QN", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.OrgIAMPolicyChangedEventType, iam.OrgIAMPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ArFDd", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ArFDd", "reduce.wrong.event.type %v", []eventstore.EventType{org.OrgIAMPolicyChangedEventType, iam.OrgIAMPolicyChangedEventType}) } if policyEvent.UserLoginMustBeDomain == nil { @@ -280,8 +353,7 @@ func (p *LoginNameProjection) reduceOrgIAMPolicyChanged(event eventstore.Event) func (p *LoginNameProjection) reduceOrgIAMPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgIAMPolicyRemovedEvent) if !ok { - logging.LogWithFields("HANDL-1ZFHL", "seq", event.Sequence(), "expectedType", org.OrgIAMPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ysEeB", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ysEeB", "reduce.wrong.event.type %s", org.OrgIAMPolicyRemovedEventType) } return crdb.NewDeleteStatement( @@ -296,8 +368,7 @@ func (p *LoginNameProjection) reduceOrgIAMPolicyRemoved(event eventstore.Event) func (p *LoginNameProjection) reduceDomainVerified(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainVerifiedEvent) if !ok { - logging.LogWithFields("HANDL-Rr7Tq", "seq", event.Sequence(), "expectedType", org.OrgDomainVerifiedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-weGAh", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-weGAh", "reduce.wrong.event.type %s", org.OrgDomainVerifiedEventType) } return crdb.NewCreateStatement( @@ -305,6 +376,7 @@ func (p *LoginNameProjection) reduceDomainVerified(event eventstore.Event) (*han []handler.Column{ handler.NewCol(LoginNameDomainNameCol, e.Domain), handler.NewCol(LoginNameDomainResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(LoginNameDomainInstanceIDCol, e.Aggregate().InstanceID), }, crdb.WithTableSuffix(loginNameDomainSuffix), ), nil @@ -313,8 +385,7 @@ func (p *LoginNameProjection) reduceDomainVerified(event eventstore.Event) (*han func (p *LoginNameProjection) reducePrimaryDomainSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainPrimarySetEvent) if !ok { - logging.LogWithFields("HANDL-0L5tW", "seq", event.Sequence(), "expectedType", org.OrgDomainPrimarySetEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-eOXPN", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-eOXPN", "reduce.wrong.event.type %s", org.OrgDomainPrimarySetEventType) } return crdb.NewMultiStatement( @@ -345,8 +416,7 @@ func (p *LoginNameProjection) reducePrimaryDomainSet(event eventstore.Event) (*h func (p *LoginNameProjection) reduceDomainRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainRemovedEvent) if !ok { - logging.LogWithFields("HANDL-reP2u", "seq", event.Sequence(), "expectedType", org.OrgDomainRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-4RHYq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-4RHYq", "reduce.wrong.event.type %s", org.OrgDomainRemovedEventType) } return crdb.NewDeleteStatement( diff --git a/internal/query/projection/login_name_test.go b/internal/query/projection/login_name_test.go index ef68eee29d..5c83ea36f4 100644 --- a/internal/query/projection/login_name_test.go +++ b/internal/query/projection/login_name_test.go @@ -42,11 +42,12 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_users (id, user_name, resource_owner) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ "agg-id", "human-added", "ro-id", + "instance-id", }, }, }, @@ -73,11 +74,12 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_users (id, user_name, resource_owner) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ "agg-id", "human-registered", "ro-id", + "instance-id", }, }, }, @@ -104,11 +106,12 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_users (id, user_name, resource_owner) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ "agg-id", "machine-added", "ro-id", + "instance-id", }, }, }, @@ -133,7 +136,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.login_names_users WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.login_names_users WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -162,7 +165,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ "changed", "agg-id", @@ -192,7 +195,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ "claimed", "agg-id", @@ -222,11 +225,12 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_policies (must_be_domain, is_default, resource_owner) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.login_names_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ true, false, "ro-id", + "instance-id", }, }, }, @@ -253,7 +257,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", + expectedStmt: "UPDATE projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", expectedArgs: []interface{}{ false, "ro-id", @@ -301,7 +305,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.login_names_policies WHERE (resource_owner = $1)", + expectedStmt: "DELETE FROM projections.login_names_policies WHERE (resource_owner = $1)", expectedArgs: []interface{}{ "ro-id", }, @@ -330,10 +334,11 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_domains (name, resource_owner) VALUES ($1, $2)", + expectedStmt: "INSERT INTO projections.login_names_domains (name, resource_owner, instance_id) VALUES ($1, $2, $3)", expectedArgs: []interface{}{ "verified", "ro-id", + "instance-id", }, }, }, @@ -360,7 +365,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.login_names_domains WHERE (name = $1) AND (resource_owner = $2)", + expectedStmt: "DELETE FROM projections.login_names_domains WHERE (name = $1) AND (resource_owner = $2)", expectedArgs: []interface{}{ "remove", "ro-id", @@ -390,7 +395,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_names_domains SET (is_primary) = ($1) WHERE (resource_owner = $2) AND (is_primary = $3)", + expectedStmt: "UPDATE projections.login_names_domains SET (is_primary) = ($1) WHERE (resource_owner = $2) AND (is_primary = $3)", expectedArgs: []interface{}{ false, "ro-id", @@ -398,7 +403,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.login_names_domains SET (is_primary) = ($1) WHERE (name = $2) AND (resource_owner = $3)", + expectedStmt: "UPDATE projections.login_names_domains SET (is_primary) = ($1) WHERE (name = $2) AND (resource_owner = $3)", expectedArgs: []interface{}{ true, "primary", @@ -429,11 +434,12 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_names_policies (must_be_domain, is_default, resource_owner) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.login_names_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ true, true, "ro-id", + "instance-id", }, }, }, @@ -460,7 +466,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", + expectedStmt: "UPDATE projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", expectedArgs: []interface{}{ false, "ro-id", diff --git a/internal/query/projection/login_policy.go b/internal/query/projection/login_policy.go index 43ba9b4eb3..43460f9997 100644 --- a/internal/query/projection/login_policy.go +++ b/internal/query/projection/login_policy.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -14,18 +12,63 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) +const ( + LoginPolicyTable = "projections.login_policies" + + LoginPolicyIDCol = "aggregate_id" + LoginPolicyInstanceIDCol = "instance_id" + LoginPolicyCreationDateCol = "creation_date" + LoginPolicyChangeDateCol = "change_date" + LoginPolicySequenceCol = "sequence" + LoginPolicyIsDefaultCol = "is_default" + LoginPolicyAllowRegisterCol = "allow_register" + LoginPolicyAllowUsernamePasswordCol = "allow_username_password" + LoginPolicyAllowExternalIDPsCol = "allow_external_idps" + LoginPolicyForceMFACol = "force_mfa" + LoginPolicy2FAsCol = "second_factors" + LoginPolicyMFAsCol = "multi_factors" + LoginPolicyPasswordlessTypeCol = "passwordless_type" + LoginPolicyHidePWResetCol = "hide_password_reset" + PasswordCheckLifetimeCol = "password_check_lifetime" + ExternalLoginCheckLifetimeCol = "external_login_check_lifetime" + MFAInitSkipLifetimeCol = "mfa_init_skip_lifetime" + SecondFactorCheckLifetimeCol = "second_factor_check_lifetime" + MultiFactorCheckLifetimeCol = "multi_factor_check_lifetime" +) + type LoginPolicyProjection struct { crdb.StatementHandler } -const ( - LoginPolicyTable = "zitadel.projections.login_policies" -) - func NewLoginPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginPolicyProjection { p := new(LoginPolicyProjection) config.ProjectionName = LoginPolicyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(LoginPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginPolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(LoginPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LoginPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(LoginPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(LoginPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(LoginPolicyAllowRegisterCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginPolicyAllowUsernamePasswordCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginPolicyAllowExternalIDPsCol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginPolicyForceMFACol, crdb.ColumnTypeBool), + crdb.NewColumn(LoginPolicy2FAsCol, crdb.ColumnTypeEnumArray), + crdb.NewColumn(LoginPolicyMFAsCol, crdb.ColumnTypeEnumArray), + crdb.NewColumn(LoginPolicyPasswordlessTypeCol, crdb.ColumnTypeEnum), + crdb.NewColumn(LoginPolicyHidePWResetCol, crdb.ColumnTypeBool), + crdb.NewColumn(PasswordCheckLifetimeCol, crdb.ColumnTypeInt64), + crdb.NewColumn(ExternalLoginCheckLifetimeCol, crdb.ColumnTypeInt64), + crdb.NewColumn(MFAInitSkipLifetimeCol, crdb.ColumnTypeInt64), + crdb.NewColumn(SecondFactorCheckLifetimeCol, crdb.ColumnTypeInt64), + crdb.NewColumn(MultiFactorCheckLifetimeCol, crdb.ColumnTypeInt64), + }, + crdb.NewPrimaryKey(LoginPolicyInstanceIDCol, LoginPolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -97,27 +140,6 @@ func (p *LoginPolicyProjection) reducers() []handler.AggregateReducer { } } -const ( - LoginPolicyIDCol = "aggregate_id" - LoginPolicyCreationDateCol = "creation_date" - LoginPolicyChangeDateCol = "change_date" - LoginPolicySequenceCol = "sequence" - LoginPolicyAllowRegisterCol = "allow_register" - LoginPolicyAllowUsernamePasswordCol = "allow_username_password" - LoginPolicyAllowExternalIDPsCol = "allow_external_idps" - LoginPolicyForceMFACol = "force_mfa" - LoginPolicy2FAsCol = "second_factors" - LoginPolicyMFAsCol = "multi_factors" - LoginPolicyPasswordlessTypeCol = "passwordless_type" - LoginPolicyIsDefaultCol = "is_default" - LoginPolicyHidePWResetCol = "hide_password_reset" - PasswordCheckLifetimeCol = "password_check_lifetime" - ExternalLoginCheckLifetimeCol = "external_login_check_lifetime" - MFAInitSkipLifetimeCol = "mfa_init_skip_lifetime" - SecondFactorCheckLifetimeCol = "second_factor_check_lifetime" - MultiFactorCheckLifetimeCol = "multi_factor_check_lifetime" -) - func (p *LoginPolicyProjection) reduceLoginPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var policyEvent policy.LoginPolicyAddedEvent var isDefault bool @@ -129,12 +151,12 @@ func (p *LoginPolicyProjection) reduceLoginPolicyAdded(event eventstore.Event) ( policyEvent = e.LoginPolicyAddedEvent isDefault = false default: - logging.LogWithFields("HANDL-IW6So", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyAddedEventType, iam.LoginPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-pYPxS", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-pYPxS", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyAddedEventType, iam.LoginPolicyAddedEventType}) } return crdb.NewCreateStatement(&policyEvent, []handler.Column{ handler.NewCol(LoginPolicyIDCol, policyEvent.Aggregate().ID), + handler.NewCol(LoginPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), handler.NewCol(LoginPolicyCreationDateCol, policyEvent.CreationDate()), handler.NewCol(LoginPolicyChangeDateCol, policyEvent.CreationDate()), handler.NewCol(LoginPolicySequenceCol, policyEvent.Sequence()), @@ -161,8 +183,7 @@ func (p *LoginPolicyProjection) reduceLoginPolicyChanged(event eventstore.Event) case *org.LoginPolicyChangedEvent: policyEvent = e.LoginPolicyChangedEvent default: - logging.LogWithFields("HANDL-NIvFo", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyChangedEventType, iam.LoginPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-BpaO6", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-BpaO6", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyChangedEventType, iam.LoginPolicyChangedEventType}) } cols := []handler.Column{ @@ -220,8 +241,7 @@ func (p *LoginPolicyProjection) reduceMFAAdded(event eventstore.Event) (*handler case *org.LoginPolicyMultiFactorAddedEvent: policyEvent = e.MultiFactorAddedEvent default: - logging.LogWithFields("HANDL-fYAHO", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyMultiFactorAddedEventType, iam.LoginPolicyMultiFactorAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-WMhAV", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-WMhAV", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyMultiFactorAddedEventType, iam.LoginPolicyMultiFactorAddedEventType}) } return crdb.NewUpdateStatement( @@ -245,8 +265,7 @@ func (p *LoginPolicyProjection) reduceMFARemoved(event eventstore.Event) (*handl case *org.LoginPolicyMultiFactorRemovedEvent: policyEvent = e.MultiFactorRemovedEvent default: - logging.LogWithFields("HANDL-vtC31", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicyMultiFactorRemovedEventType, iam.LoginPolicyMultiFactorRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-czU7n", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-czU7n", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicyMultiFactorRemovedEventType, iam.LoginPolicyMultiFactorRemovedEventType}) } return crdb.NewUpdateStatement( @@ -265,8 +284,7 @@ func (p *LoginPolicyProjection) reduceMFARemoved(event eventstore.Event) (*handl func (p *LoginPolicyProjection) reduceLoginPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.LoginPolicyRemovedEvent) if !ok { - logging.LogWithFields("HANDL-gF5q6", "seq", event.Sequence(), "expectedType", org.LoginPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-oRSvD", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-oRSvD", "reduce.wrong.event.type %s", org.LoginPolicyRemovedEventType) } return crdb.NewDeleteStatement( e, @@ -284,8 +302,7 @@ func (p *LoginPolicyProjection) reduce2FAAdded(event eventstore.Event) (*handler case *org.LoginPolicySecondFactorAddedEvent: policyEvent = e.SecondFactorAddedEvent default: - logging.LogWithFields("HANDL-dwadQ", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicySecondFactorAddedEventType, iam.LoginPolicySecondFactorAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-agB2E", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-agB2E", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicySecondFactorAddedEventType, iam.LoginPolicySecondFactorAddedEventType}) } return crdb.NewUpdateStatement( @@ -309,8 +326,7 @@ func (p *LoginPolicyProjection) reduce2FARemoved(event eventstore.Event) (*handl case *org.LoginPolicySecondFactorRemovedEvent: policyEvent = e.SecondFactorRemovedEvent default: - logging.LogWithFields("HANDL-2IE8Y", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.LoginPolicySecondFactorRemovedEventType, iam.LoginPolicySecondFactorRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-KYJvA", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-KYJvA", "reduce.wrong.event.type %v", []eventstore.EventType{org.LoginPolicySecondFactorRemovedEventType, iam.LoginPolicySecondFactorRemovedEventType}) } return crdb.NewUpdateStatement( diff --git a/internal/query/projection/login_policy_test.go b/internal/query/projection/login_policy_test.go index 928766521a..d89084d811 100644 --- a/internal/query/projection/login_policy_test.go +++ b/internal/query/projection/login_policy_test.go @@ -53,9 +53,10 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_policies (aggregate_id, creation_date, change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, is_default, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)", + expectedStmt: "INSERT INTO projections.login_policies (aggregate_id, instance_id, creation_date, change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, is_default, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -107,7 +108,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (aggregate_id = $14)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (aggregate_id = $14)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -149,7 +150,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -181,7 +182,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -211,7 +212,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.login_policies WHERE (aggregate_id = $1)", + expectedStmt: "DELETE FROM projections.login_policies WHERE (aggregate_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -240,7 +241,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -272,7 +273,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -314,9 +315,10 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.login_policies (aggregate_id, creation_date, change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, is_default, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)", + expectedStmt: "INSERT INTO projections.login_policies (aggregate_id, instance_id, creation_date, change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, is_default, hide_password_reset, password_check_lifetime, external_login_check_lifetime, mfa_init_skip_lifetime, second_factor_check_lifetime, multi_factor_check_lifetime) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -363,7 +365,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -400,7 +402,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -432,7 +434,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -464,7 +466,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -496,7 +498,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.login_policies SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/mail_template.go b/internal/query/projection/mail_template.go index 1251dcb4a5..3094cfe3ae 100644 --- a/internal/query/projection/mail_template.go +++ b/internal/query/projection/mail_template.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,26 +13,41 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type MailTemplateProjection struct { - crdb.StatementHandler -} - const ( - MailTemplateTable = "zitadel.projections.mail_templates" + MailTemplateTable = "projections.mail_templates" MailTemplateAggregateIDCol = "aggregate_id" + MailTemplateInstanceIDCol = "instance_id" MailTemplateCreationDateCol = "creation_date" MailTemplateChangeDateCol = "change_date" MailTemplateSequenceCol = "sequence" MailTemplateStateCol = "state" - MailTemplateTemplateCol = "template" MailTemplateIsDefaultCol = "is_default" + MailTemplateTemplateCol = "template" ) +type MailTemplateProjection struct { + crdb.StatementHandler +} + func NewMailTemplateProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MailTemplateProjection { p := new(MailTemplateProjection) config.ProjectionName = MailTemplateTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(MailTemplateAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(MailTemplateInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(MailTemplateCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MailTemplateChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MailTemplateSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(MailTemplateStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(MailTemplateIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(MailTemplateTemplateCol, crdb.ColumnTypeBytes), + }, + crdb.NewPrimaryKey(MailTemplateInstanceIDCol, MailTemplateAggregateIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -84,13 +98,13 @@ func (p *MailTemplateProjection) reduceAdded(event eventstore.Event) (*handler.S templateEvent = e.MailTemplateAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-94jfG", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.MailTemplateAddedEventType, iam.MailTemplateAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-0pJ3f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-0pJ3f", "reduce.wrong.event.type, %v", []eventstore.EventType{org.MailTemplateAddedEventType, iam.MailTemplateAddedEventType}) } return crdb.NewCreateStatement( &templateEvent, []handler.Column{ handler.NewCol(MailTemplateAggregateIDCol, templateEvent.Aggregate().ID), + handler.NewCol(MailTemplateInstanceIDCol, templateEvent.Aggregate().InstanceID), handler.NewCol(MailTemplateCreationDateCol, templateEvent.CreationDate()), handler.NewCol(MailTemplateChangeDateCol, templateEvent.CreationDate()), handler.NewCol(MailTemplateSequenceCol, templateEvent.Sequence()), @@ -108,8 +122,7 @@ func (p *MailTemplateProjection) reduceChanged(event eventstore.Event) (*handler case *iam.MailTemplateChangedEvent: policyEvent = e.MailTemplateChangedEvent default: - logging.LogWithFields("PROJE-02J9f", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.MailTemplateChangedEventType, iam.MailTemplateChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-gJ03f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-gJ03f", "reduce.wrong.event.type, %v", []eventstore.EventType{org.MailTemplateChangedEventType, iam.MailTemplateChangedEventType}) } cols := []handler.Column{ handler.NewCol(MailTemplateChangeDateCol, policyEvent.CreationDate()), @@ -129,8 +142,7 @@ func (p *MailTemplateProjection) reduceChanged(event eventstore.Event) (*handler func (p *MailTemplateProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.MailTemplateRemovedEvent) if !ok { - logging.LogWithFields("PROJE-2m0fp", "seq", event.Sequence(), "expectedType", org.MailTemplateRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-3jJGs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-3jJGs", "reduce.wrong.event.type %s", org.MailTemplateRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, diff --git a/internal/query/projection/mail_template_test.go b/internal/query/projection/mail_template_test.go index 8e14c97f23..dc35c82798 100644 --- a/internal/query/projection/mail_template_test.go +++ b/internal/query/projection/mail_template_test.go @@ -42,9 +42,10 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.mail_templates (aggregate_id, creation_date, change_date, sequence, state, is_default, template) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.mail_templates (aggregate_id, instance_id, creation_date, change_date, sequence, state, is_default, template) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -77,7 +78,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -107,7 +108,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.mail_templates WHERE (aggregate_id = $1)", + expectedStmt: "DELETE FROM projections.mail_templates WHERE (aggregate_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -136,9 +137,10 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.mail_templates (aggregate_id, creation_date, change_date, sequence, state, is_default, template) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.mail_templates (aggregate_id, instance_id, creation_date, change_date, sequence, state, is_default, template) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -171,7 +173,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/member.go b/internal/query/projection/member.go index c0c3961bae..40a69072cc 100644 --- a/internal/query/projection/member.go +++ b/internal/query/projection/member.go @@ -1,11 +1,12 @@ package projection import ( + "github.com/lib/pq" + "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/handler/crdb" "github.com/caos/zitadel/internal/repository/member" - "github.com/lib/pq" ) const ( @@ -16,6 +17,19 @@ const ( MemberChangeDate = "change_date" MemberSequence = "sequence" MemberResourceOwner = "resource_owner" + MemberInstanceID = "instance_id" +) + +var ( + memberColumns = []*crdb.Column{ + crdb.NewColumn(MemberCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MemberChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MemberUserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(MemberRolesCol, crdb.ColumnTypeTextArray, crdb.Nullable()), + crdb.NewColumn(MemberSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(MemberResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(MemberInstanceID, crdb.ColumnTypeText), + } ) type reduceMemberConfig struct { @@ -48,6 +62,7 @@ func reduceMemberAdded(e member.MemberAddedEvent, opts ...reduceMemberOpt) (*han handler.NewCol(MemberChangeDate, e.CreationDate()), handler.NewCol(MemberSequence, e.Sequence()), handler.NewCol(MemberResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(MemberInstanceID, e.Aggregate().InstanceID), }} for _, opt := range opts { diff --git a/internal/query/projection/message_text_test.go b/internal/query/projection/message_text_test.go index 8476a7cef5..8307bd260a 100644 --- a/internal/query/projection/message_text_test.go +++ b/internal/query/projection/message_text_test.go @@ -45,9 +45,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -84,9 +85,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, pre_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, pre_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -123,9 +125,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, subject) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, subject) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -162,9 +165,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, greeting) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, greeting) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -201,9 +205,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -240,9 +245,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, button_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, button_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -279,9 +285,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, footer_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, footer_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -317,7 +324,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -353,7 +360,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, pre_header) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, pre_header) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -389,7 +396,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, subject) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, subject) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -425,7 +432,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, greeting) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, greeting) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -461,7 +468,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -497,7 +504,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, button_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, button_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -533,7 +540,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, footer_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, footer_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -569,7 +576,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.message_texts WHERE (aggregate_id = $1) AND (type = $2) AND (language = $3)", + expectedStmt: "DELETE FROM projections.message_texts WHERE (aggregate_id = $1) AND (type = $2) AND (language = $3)", expectedArgs: []interface{}{ "agg-id", "InitCode", @@ -603,9 +610,10 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.message_texts (aggregate_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "UPSERT INTO projections.message_texts (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -641,7 +649,7 @@ func TestMessageTextProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", + expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/message_texts.go b/internal/query/projection/message_texts.go index 1d7e437bc2..b9cd735ce9 100644 --- a/internal/query/projection/message_texts.go +++ b/internal/query/projection/message_texts.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -15,14 +13,11 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type MessageTextProjection struct { - crdb.StatementHandler -} - const ( - MessageTextTable = "zitadel.projections.message_texts" + MessageTextTable = "projections.message_texts" MessageTextAggregateIDCol = "aggregate_id" + MessageTextInstanceIDCol = "instance_id" MessageTextCreationDateCol = "creation_date" MessageTextChangeDateCol = "change_date" MessageTextSequenceCol = "sequence" @@ -38,10 +33,35 @@ const ( MessageTextFooterCol = "footer_text" ) +type MessageTextProjection struct { + crdb.StatementHandler +} + func NewMessageTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MessageTextProjection { p := new(MessageTextProjection) config.ProjectionName = MessageTextTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(MessageTextAggregateIDCol, crdb.ColumnTypeText), + crdb.NewColumn(MessageTextInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(MessageTextCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MessageTextChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(MessageTextSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(MessageTextStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(MessageTextTypeCol, crdb.ColumnTypeText), + crdb.NewColumn(MessageTextLanguageCol, crdb.ColumnTypeText), + crdb.NewColumn(MessageTextTitleCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextPreHeaderCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextSubjectCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextGreetingCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextTextCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextButtonTextCol, crdb.ColumnTypeBool), + crdb.NewColumn(MessageTextFooterCol, crdb.ColumnTypeBool), + }, + crdb.NewPrimaryKey(MessageTextInstanceIDCol, MessageTextAggregateIDCol, MessageTextTypeCol, MessageTextLanguageCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -93,8 +113,7 @@ func (p *MessageTextProjection) reduceAdded(event eventstore.Event) (*handler.St case *iam.CustomTextSetEvent: templateEvent = e.CustomTextSetEvent default: - logging.LogWithFields("PROJE-2N9fg", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-2n90r", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-2n90r", "reduce.wrong.event.type %v", []eventstore.EventType{org.CustomTextSetEventType, iam.CustomTextSetEventType}) } if !isMessageTemplate(templateEvent.Template) { return crdb.NewNoOpStatement(event), nil @@ -102,6 +121,7 @@ func (p *MessageTextProjection) reduceAdded(event eventstore.Event) (*handler.St cols := []handler.Column{ handler.NewCol(MessageTextAggregateIDCol, templateEvent.Aggregate().ID), + handler.NewCol(MessageTextInstanceIDCol, templateEvent.Aggregate().InstanceID), handler.NewCol(MessageTextCreationDateCol, templateEvent.CreationDate()), handler.NewCol(MessageTextChangeDateCol, templateEvent.CreationDate()), handler.NewCol(MessageTextSequenceCol, templateEvent.Sequence()), @@ -143,8 +163,7 @@ func (p *MessageTextProjection) reduceRemoved(event eventstore.Event) (*handler. case *iam.CustomTextRemovedEvent: templateEvent = e.CustomTextRemovedEvent default: - logging.LogWithFields("PROJE-3m022", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.CustomTextRemovedEventType, iam.CustomTextRemovedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-fm0ge", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-fm0ge", "reduce.wrong.event.type %v", []eventstore.EventType{org.CustomTextRemovedEventType, iam.CustomTextRemovedEventType}) } if !isMessageTemplate(templateEvent.Template) { return crdb.NewNoOpStatement(event), nil @@ -193,8 +212,7 @@ func (p *MessageTextProjection) reduceTemplateRemoved(event eventstore.Event) (* case *iam.CustomTextTemplateRemovedEvent: templateEvent = e.CustomTextTemplateRemovedEvent default: - logging.LogWithFields("PROJE-m03ng", "seq", event.Sequence(), "expectedType", org.CustomTextTemplateRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-2n9rs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-2n9rs", "reduce.wrong.event.type %s", org.CustomTextTemplateRemovedEventType) } if !isMessageTemplate(templateEvent.Template) { return crdb.NewNoOpStatement(event), nil diff --git a/internal/query/projection/oidc_settings.go b/internal/query/projection/oidc_settings.go index 14417db29d..8e3eba422a 100644 --- a/internal/query/projection/oidc_settings.go +++ b/internal/query/projection/oidc_settings.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -12,18 +11,46 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + OIDCSettingsProjectionTable = "projections.oidc_settings" + + OIDCSettingsColumnAggregateID = "aggregate_id" + OIDCSettingsColumnCreationDate = "creation_date" + OIDCSettingsColumnChangeDate = "change_date" + OIDCSettingsColumnResourceOwner = "resource_owner" + OIDCSettingsColumnInstanceID = "instance_id" + OIDCSettingsColumnSequence = "sequence" + OIDCSettingsColumnAccessTokenLifetime = "access_token_lifetime" + OIDCSettingsColumnIdTokenLifetime = "id_token_lifetime" + OIDCSettingsColumnRefreshTokenIdleExpiration = "refresh_token_idle_expiration" + OIDCSettingsColumnRefreshTokenExpiration = "refresh_token_expiration" +) + type OIDCSettingsProjection struct { crdb.StatementHandler } -const ( - OIDCSettingsProjectionTable = "zitadel.projections.oidc_settings" -) - func NewOIDCSettingsProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OIDCSettingsProjection { p := new(OIDCSettingsProjection) config.ProjectionName = OIDCSettingsProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(OIDCSettingsColumnAggregateID, crdb.ColumnTypeText), + crdb.NewColumn(OIDCSettingsColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OIDCSettingsColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OIDCSettingsColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(OIDCSettingsColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(OIDCSettingsColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(OIDCSettingsColumnAccessTokenLifetime, crdb.ColumnTypeInt64), + crdb.NewColumn(ExternalLoginCheckLifetimeCol, crdb.ColumnTypeInt64), + crdb.NewColumn(OIDCSettingsColumnIdTokenLifetime, crdb.ColumnTypeInt64), + crdb.NewColumn(OIDCSettingsColumnRefreshTokenIdleExpiration, crdb.ColumnTypeInt64), + crdb.NewColumn(OIDCSettingsColumnRefreshTokenExpiration, crdb.ColumnTypeInt64), + }, + crdb.NewPrimaryKey(OIDCSettingsColumnInstanceID, OIDCSettingsColumnAggregateID), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -46,23 +73,10 @@ func (p *OIDCSettingsProjection) reducers() []handler.AggregateReducer { } } -const ( - OIDCSettingsColumnAggregateID = "aggregate_id" - OIDCSettingsColumnCreationDate = "creation_date" - OIDCSettingsColumnChangeDate = "change_date" - OIDCSettingsColumnResourceOwner = "resource_owner" - OIDCSettingsColumnSequence = "sequence" - OIDCSettingsColumnAccessTokenLifetime = "access_token_lifetime" - OIDCSettingsColumnIdTokenLifetime = "id_token_lifetime" - OIDCSettingsColumnRefreshTokenIdleExpiration = "refresh_token_idle_expiration" - OIDCSettingsColumnRefreshTokenExpiration = "refresh_token_expiration" -) - func (p *OIDCSettingsProjection) reduceOIDCSettingsAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.OIDCSettingsAddedEvent) if !ok { - logging.WithFields("seq", event.Sequence(), "expectedType", iam.OIDCSettingsAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-f9nwf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-f9nwf", "reduce.wrong.event.type %s", iam.OIDCSettingsAddedEventType) } return crdb.NewCreateStatement( e, @@ -71,6 +85,7 @@ func (p *OIDCSettingsProjection) reduceOIDCSettingsAdded(event eventstore.Event) handler.NewCol(OIDCSettingsColumnCreationDate, e.CreationDate()), handler.NewCol(OIDCSettingsColumnChangeDate, e.CreationDate()), handler.NewCol(OIDCSettingsColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(OIDCSettingsColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(OIDCSettingsColumnSequence, e.Sequence()), handler.NewCol(OIDCSettingsColumnAccessTokenLifetime, e.AccessTokenLifetime), handler.NewCol(OIDCSettingsColumnIdTokenLifetime, e.IdTokenLifetime), @@ -83,8 +98,7 @@ func (p *OIDCSettingsProjection) reduceOIDCSettingsAdded(event eventstore.Event) func (p *OIDCSettingsProjection) reduceOIDCSettingsChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.OIDCSettingsChangedEvent) if !ok { - logging.WithFields("seq", event.Sequence(), "expected", iam.OIDCSettingsChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-8JJ2d", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-8JJ2d", "reduce.wrong.event.type %s", iam.OIDCSettingsChangedEventType) } columns := make([]handler.Column, 0, 6) diff --git a/internal/query/projection/oidc_settings_test.go b/internal/query/projection/oidc_settings_test.go index 729859fa59..23dfe98fb2 100644 --- a/internal/query/projection/oidc_settings_test.go +++ b/internal/query/projection/oidc_settings_test.go @@ -39,7 +39,7 @@ func TestOIDCSettingsProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.oidc_settings SET (change_date, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) = ($1, $2, $3, $4, $5, $6) WHERE (aggregate_id = $7)", + expectedStmt: "UPDATE projections.oidc_settings SET (change_date, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) = ($1, $2, $3, $4, $5, $6) WHERE (aggregate_id = $7)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -72,12 +72,13 @@ func TestOIDCSettingsProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.oidc_settings (aggregate_id, creation_date, change_date, resource_owner, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.oidc_settings (aggregate_id, creation_date, change_date, resource_owner, instance_id, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), time.Millisecond * 10, time.Millisecond * 10, diff --git a/internal/query/projection/org.go b/internal/query/projection/org.go index 27956ccd7c..535ed357c1 100644 --- a/internal/query/projection/org.go +++ b/internal/query/projection/org.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -13,18 +11,45 @@ import ( "github.com/caos/zitadel/internal/repository/org" ) +const ( + OrgProjectionTable = "projections.orgs" + + OrgColumnID = "id" + OrgColumnCreationDate = "creation_date" + OrgColumnChangeDate = "change_date" + OrgColumnResourceOwner = "resource_owner" + OrgColumnInstanceID = "instance_id" + OrgColumnState = "org_state" + OrgColumnSequence = "sequence" + OrgColumnName = "name" + OrgColumnDomain = "primary_domain" +) + type OrgProjection struct { crdb.StatementHandler } -const ( - OrgProjectionTable = "zitadel.projections.orgs" -) - func NewOrgProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgProjection { p := new(OrgProjection) config.ProjectionName = OrgProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(OrgColumnID, crdb.ColumnTypeText), + crdb.NewColumn(OrgColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(OrgColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(OrgColumnState, crdb.ColumnTypeEnum), + crdb.NewColumn(OrgColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(OrgColumnName, crdb.ColumnTypeText), + crdb.NewColumn(OrgColumnDomain, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(OrgColumnInstanceID, OrgColumnID), + crdb.NewIndex("domain_idx", []string{OrgColumnDomain}), + crdb.NewIndex("name_idx", []string{OrgColumnName}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -59,24 +84,10 @@ func (p *OrgProjection) reducers() []handler.AggregateReducer { } } -type OrgColumn string - -const ( - OrgColumnID = "id" - OrgColumnCreationDate = "creation_date" - OrgColumnChangeDate = "change_date" - OrgColumnResourceOwner = "resource_owner" - OrgColumnState = "org_state" - OrgColumnSequence = "sequence" - OrgColumnName = "name" - OrgColumnDomain = "primary_domain" -) - func (p *OrgProjection) reduceOrgAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgAddedEvent) if !ok { - logging.LogWithFields("HANDL-zWCk3", "seq", event.Sequence(), "expectedType", org.OrgAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uYq4r", "reduce.wrong.event.type %s", org.OrgAddedEventType) } return crdb.NewCreateStatement( e, @@ -85,6 +96,7 @@ func (p *OrgProjection) reduceOrgAdded(event eventstore.Event) (*handler.Stateme handler.NewCol(OrgColumnCreationDate, e.CreationDate()), handler.NewCol(OrgColumnChangeDate, e.CreationDate()), handler.NewCol(OrgColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(OrgColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(OrgColumnSequence, e.Sequence()), handler.NewCol(OrgColumnName, e.Name), handler.NewCol(OrgColumnState, domain.OrgStateActive), @@ -95,8 +107,7 @@ func (p *OrgProjection) reduceOrgAdded(event eventstore.Event) (*handler.Stateme func (p *OrgProjection) reduceOrgChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgChangedEvent) if !ok { - logging.LogWithFields("HANDL-q4oq8", "seq", event.Sequence(), "expected", org.OrgChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Bg8oM", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Bg8oM", "reduce.wrong.event.type %s", org.OrgChangedEventType) } if e.Name == "" { return crdb.NewNoOpStatement(e), nil @@ -117,8 +128,7 @@ func (p *OrgProjection) reduceOrgChanged(event eventstore.Event) (*handler.State func (p *OrgProjection) reduceOrgDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgDeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-1gwdc", "seq", event.Sequence(), "expectedType", org.OrgDeactivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-BApK4", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-BApK4", "reduce.wrong.event.type %s", org.OrgDeactivatedEventType) } return crdb.NewUpdateStatement( e, @@ -136,8 +146,7 @@ func (p *OrgProjection) reduceOrgDeactivated(event eventstore.Event) (*handler.S func (p *OrgProjection) reduceOrgReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.OrgReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-Vjwiy", "seq", event.Sequence(), "expectedType", org.OrgReactivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-o37De", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-o37De", "reduce.wrong.event.type %s", org.OrgReactivatedEventType) } return crdb.NewUpdateStatement( e, @@ -155,8 +164,7 @@ func (p *OrgProjection) reduceOrgReactivated(event eventstore.Event) (*handler.S func (p *OrgProjection) reducePrimaryDomainSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainPrimarySetEvent) if !ok { - logging.LogWithFields("HANDL-79OhB", "seq", event.Sequence(), "expectedType", org.OrgDomainPrimarySetEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-4TbKT", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-4TbKT", "reduce.wrong.event.type %s", org.OrgDomainPrimarySetEventType) } return crdb.NewUpdateStatement( e, diff --git a/internal/query/projection/org/owner/projection.go b/internal/query/projection/org/owner/projection.go deleted file mode 100644 index 6f87efbf4d..0000000000 --- a/internal/query/projection/org/owner/projection.go +++ /dev/null @@ -1,401 +0,0 @@ -package owner - -import ( - "context" - "time" - - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/handler" - "github.com/caos/zitadel/internal/eventstore/handler/crdb" - "github.com/caos/zitadel/internal/repository/org" - "github.com/caos/zitadel/internal/repository/user" - "golang.org/x/text/language" -) - -type OrgOwner struct { - OrgID string - OrgName string - OrgCreationDate time.Time - OwnerID string - OwnerLanguage *language.Tag - OwnerEmailAddress string - OwnerFirstName string - OwnerLastName string - OwnerGender domain.Gender -} - -type OrgOwnerProjection struct { - crdb.StatementHandler -} - -const ( - orgTableSuffix = "orgs" - orgIDCol = "id" - orgNameCol = "name" - orgCreationDateCol = "creation_date" - - userTableSuffix = "users" - userOrgIDCol = "org_id" - userIDCol = "owner_id" - userLanguageCol = "language" - userEmailCol = "email" - userFirstNameCol = "first_name" - userLastNameCol = "last_name" - userGenderCol = "gender" -) - -func NewOrgOwnerProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgOwnerProjection { - p := &OrgOwnerProjection{} - config.ProjectionName = "zitadel.projections.org_owners" - config.Reducers = p.reducers() - p.StatementHandler = crdb.NewStatementHandler(ctx, config) - return p -} - -func (p *OrgOwnerProjection) reducers() []handler.AggregateReducer { - return []handler.AggregateReducer{ - { - Aggregate: org.AggregateType, - EventRedusers: []handler.EventReducer{ - { - Event: org.OrgAddedEventType, - Reduce: p.reduceOrgAdded, - }, - { - Event: org.OrgChangedEventType, - Reduce: p.reduceOrgChanged, - }, - { - Event: org.OrgRemovedEventType, - Reduce: p.reduceOrgRemoved, - }, - { - Event: org.MemberAddedEventType, - Reduce: p.reduceMemberAdded, - }, - { - Event: org.MemberChangedEventType, - Reduce: p.reduceMemberChanged, - }, - { - Event: org.MemberRemovedEventType, - Reduce: p.reduceMemberRemoved, - }, - }, - }, - { - Aggregate: user.AggregateType, - EventRedusers: []handler.EventReducer{ - { - Event: user.HumanEmailChangedType, - Reduce: p.reduceHumanEmailChanged, - }, - { - Event: user.UserV1EmailChangedType, - Reduce: p.reduceHumanEmailChanged, - }, - { - Event: user.HumanProfileChangedType, - Reduce: p.reduceHumanProfileChanged, - }, - { - Event: user.UserV1ProfileChangedType, - Reduce: p.reduceHumanProfileChanged, - }, - }, - }, - } -} - -func (p *OrgOwnerProjection) reduceMemberAdded(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.MemberAddedEvent) - if !ok { - logging.LogWithFields("PROJE-kL530", "seq", event.Sequence, "expected", org.MemberAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-OkiBV", "reduce.wrong.event.type") - } - - if !isOrgOwner(e.Roles) { - return crdb.NewNoOpStatement(e), nil - } - - stmt, err := p.addOwner(e, e.Aggregate().ResourceOwner, e.UserID) - if err != nil { - return nil, err - } - - return stmt, nil -} - -func (p *OrgOwnerProjection) reduceMemberChanged(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.MemberChangedEvent) - if !ok { - logging.LogWithFields("PROJE-kL530", "seq", event.Sequence, "expected", org.MemberAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-OkiBV", "reduce.wrong.event.type") - } - - if !isOrgOwner(e.Roles) { - return p.deleteOwner(e, e.Aggregate().ID, e.UserID), nil - } - - stmt, err := p.addOwner(e, e.Aggregate().ResourceOwner, e.UserID) - if err != nil { - return nil, err - } - - return stmt, nil -} - -func (p *OrgOwnerProjection) reduceMemberRemoved(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.MemberRemovedEvent) - if !ok { - logging.LogWithFields("PROJE-boIbP", "seq", event.Sequence, "expected", org.MemberRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-pk6TS", "reduce.wrong.event.type") - } - - return p.deleteOwner(e, e.Aggregate().ID, e.UserID), nil -} - -func (p *OrgOwnerProjection) reduceHumanEmailChanged(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*user.HumanEmailChangedEvent) - if !ok { - logging.LogWithFields("PROJE-IHFwh", "seq", event.Sequence, "expected", user.HumanEmailChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-jMlwT", "reduce.wrong.event.type") - } - - return crdb.NewUpdateStatement( - e, - []handler.Column{ - handler.NewCol(userEmailCol, e.EmailAddress), - }, - []handler.Condition{ - handler.NewCond(userIDCol, e.Aggregate().ID), - }, - crdb.WithTableSuffix(userTableSuffix), - ), nil -} - -func (p *OrgOwnerProjection) reduceHumanProfileChanged(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*user.HumanProfileChangedEvent) - if !ok { - logging.LogWithFields("PROJE-WqgUS", "seq", event.Sequence, "expected", user.HumanProfileChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Cdkkf", "reduce.wrong.event.type") - } - - values := []handler.Column{} - if e.FirstName != "" { - values = append(values, handler.NewCol(userFirstNameCol, e.FirstName)) - } - if e.LastName != "" { - values = append(values, handler.NewCol(userLastNameCol, e.LastName)) - } - if e.PreferredLanguage != nil { - values = append(values, handler.NewCol(userLanguageCol, e.PreferredLanguage.String())) - } - if e.Gender != nil { - values = append(values, handler.NewCol(userGenderCol, *e.Gender)) - } - - if len(values) == 0 { - return crdb.NewNoOpStatement(e), nil - } - - return crdb.NewUpdateStatement( - e, - values, - []handler.Condition{ - handler.NewCond(userIDCol, e.Aggregate().ID), - }, - crdb.WithTableSuffix(userTableSuffix), - ), nil -} - -func (p *OrgOwnerProjection) reduceOrgAdded(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.OrgAddedEvent) - if !ok { - logging.LogWithFields("PROJE-wbOrL", "seq", event.Sequence, "expected", org.OrgAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-pk6TS", "reduce.wrong.event.type") - } - return crdb.NewCreateStatement( - e, - []handler.Column{ - handler.NewCol(orgIDCol, e.Aggregate().ResourceOwner), - handler.NewCol(orgNameCol, e.Name), - handler.NewCol(orgCreationDateCol, e.CreationDate()), - }, - crdb.WithTableSuffix(orgTableSuffix), - ), nil -} - -func (p *OrgOwnerProjection) reduceOrgChanged(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.OrgChangedEvent) - if !ok { - logging.LogWithFields("PROJE-piy2b", "seq", event.Sequence, "expected", org.OrgChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-MGbru", "reduce.wrong.event.type") - } - - values := []handler.Column{} - if e.Name != "" { - values = append(values, handler.NewCol(orgNameCol, e.Name)) - } - - if len(values) == 0 { - return crdb.NewNoOpStatement(e), nil - } - - return crdb.NewUpdateStatement( - e, - values, - []handler.Condition{ - handler.NewCond(orgIDCol, e.Aggregate().ResourceOwner), - }, - crdb.WithTableSuffix(orgTableSuffix), - ), nil -} - -func (p *OrgOwnerProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) { - e, ok := event.(*org.OrgRemovedEvent) - if !ok { - logging.LogWithFields("PROJE-F1mHQ", "seq", event.Sequence, "expected", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-9ZR2w", "reduce.wrong.event.type") - } - - return crdb.NewMultiStatement(e, - //delete org in org table - crdb.AddDeleteStatement( - []handler.Condition{ - handler.NewCond(orgIDCol, e.Aggregate().ResourceOwner), - }, - crdb.WithTableSuffix(orgTableSuffix), - ), - // delete users of the org - crdb.AddDeleteStatement( - []handler.Condition{ - handler.NewCond(userOrgIDCol, e.Aggregate().ResourceOwner), - }, - crdb.WithTableSuffix(userTableSuffix), - ), - ), nil -} - -func isOrgOwner(roles []string) bool { - for _, role := range roles { - if role == "ORG_OWNER" { - return true - } - } - return false -} - -func (p *OrgOwnerProjection) deleteOwner(event eventstore.Event, orgID, ownerID string) *handler.Statement { - return crdb.NewDeleteStatement( - event, - []handler.Condition{ - handler.NewCond(userOrgIDCol, orgID), - handler.NewCond(userIDCol, ownerID), - }, - crdb.WithTableSuffix(userTableSuffix), - ) -} - -func (p *OrgOwnerProjection) addOwner(event eventstore.Event, orgID, userID string) (*handler.Statement, error) { - events, err := p.Eventstore.Filter(context.Background(), - eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). - AddQuery(). - AggregateTypes(user.AggregateType). - EventTypes( - user.HumanAddedType, - user.UserV1AddedType, - user.HumanRegisteredType, - user.UserV1RegisteredType, - user.HumanEmailChangedType, - user.UserV1EmailChangedType, - user.HumanProfileChangedType, - user.UserV1ProfileChangedType, - user.MachineAddedEventType, - user.MachineChangedEventType). - AggregateIDs(userID). - SequenceLess(event.Sequence()). - Builder()) - if err != nil { - return nil, err - } - - if len(events) == 0 { - logging.LogWithFields("mqd3w", "user", userID, "org", orgID, "seq", event.Sequence()).Warn("no events for user found") - return nil, errors.ThrowInternal(nil, "PROJE-Qk7Tv", "unable to find user events") - } - - owner := &OrgOwner{ - OrgID: orgID, - OwnerID: userID, - } - - p.reduce(owner, events) - - values := []handler.Column{ - handler.NewCol(userOrgIDCol, owner.OrgID), - handler.NewCol(userIDCol, owner.OwnerID), - handler.NewCol(userEmailCol, owner.OwnerEmailAddress), - handler.NewCol(userFirstNameCol, owner.OwnerFirstName), - handler.NewCol(userLastNameCol, owner.OwnerLastName), - handler.NewCol(userGenderCol, owner.OwnerGender), - } - - if owner.OwnerLanguage != nil { - values = append(values, handler.NewCol(userLanguageCol, owner.OwnerLanguage.String())) - } - - return crdb.NewUpsertStatement( - event, - values, - crdb.WithTableSuffix(userTableSuffix), - ), nil -} - -func (p *OrgOwnerProjection) reduce(owner *OrgOwner, events []eventstore.Event) { - for _, event := range events { - switch e := event.(type) { - case *user.HumanAddedEvent: - owner.OwnerLanguage = &e.PreferredLanguage - owner.OwnerEmailAddress = e.EmailAddress - owner.OwnerFirstName = e.FirstName - owner.OwnerLastName = e.LastName - owner.OwnerGender = e.Gender - case *user.HumanRegisteredEvent: - owner.OwnerLanguage = &e.PreferredLanguage - owner.OwnerEmailAddress = e.EmailAddress - owner.OwnerFirstName = e.FirstName - owner.OwnerLastName = e.LastName - owner.OwnerGender = e.Gender - case *user.HumanEmailChangedEvent: - owner.OwnerEmailAddress = e.EmailAddress - case *user.HumanProfileChangedEvent: - if e.PreferredLanguage != nil { - owner.OwnerLanguage = e.PreferredLanguage - } - if e.FirstName != "" { - owner.OwnerFirstName = e.FirstName - } - if e.LastName != "" { - owner.OwnerLastName = e.LastName - } - if e.Gender != nil { - owner.OwnerGender = *e.Gender - } - case *user.MachineAddedEvent: - owner.OwnerFirstName = "machine" - owner.OwnerLastName = e.Name - owner.OwnerEmailAddress = e.UserName - case *user.MachineChangedEvent: - if e.Name != nil { - owner.OwnerLastName = *e.Name - } - default: - // This happens only on implementation errors - logging.LogWithFields("PROJE-sKNsR", "eventType", event.Type()).Panic("unexpected event type") - } - } -} diff --git a/internal/query/projection/org_domain.go b/internal/query/projection/org_domain.go index eb60c654da..e8be611047 100644 --- a/internal/query/projection/org_domain.go +++ b/internal/query/projection/org_domain.go @@ -2,9 +2,7 @@ package projection import ( "context" - "fmt" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -13,18 +11,43 @@ import ( "github.com/caos/zitadel/internal/repository/org" ) +const ( + OrgDomainTable = "projections.org_domains" + + OrgDomainOrgIDCol = "org_id" + OrgDomainInstanceIDCol = "instance_id" + OrgDomainCreationDateCol = "creation_date" + OrgDomainChangeDateCol = "change_date" + OrgDomainSequenceCol = "sequence" + OrgDomainDomainCol = "domain" + OrgDomainIsVerifiedCol = "is_verified" + OrgDomainIsPrimaryCol = "is_primary" + OrgDomainValidationTypeCol = "validation_type" +) + type OrgDomainProjection struct { crdb.StatementHandler } -const ( - OrgDomainTable = "zitadel.projections.org_domains" -) - func NewOrgDomainProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgDomainProjection { p := new(OrgDomainProjection) config.ProjectionName = OrgDomainTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(OrgDomainOrgIDCol, crdb.ColumnTypeText), + crdb.NewColumn(OrgDomainInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(OrgDomainCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgDomainChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgDomainSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(OrgDomainDomainCol, crdb.ColumnTypeText), + crdb.NewColumn(OrgDomainIsVerifiedCol, crdb.ColumnTypeBool), + crdb.NewColumn(OrgDomainIsPrimaryCol, crdb.ColumnTypeBool), + crdb.NewColumn(OrgDomainValidationTypeCol, crdb.ColumnTypeEnum), + }, + crdb.NewPrimaryKey(OrgDomainInstanceIDCol, OrgDomainOrgIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -59,22 +82,10 @@ func (p *OrgDomainProjection) reducers() []handler.AggregateReducer { } } -const ( - OrgDomainCreationDateCol = "creation_date" - OrgDomainChangeDateCol = "change_date" - OrgDomainSequenceCol = "sequence" - OrgDomainDomainCol = "domain" - OrgDomainOrgIDCol = "org_id" - OrgDomainIsVerifiedCol = "is_verified" - OrgDomainIsPrimaryCol = "is_primary" - OrgDomainValidationTypeCol = "validation_type" -) - func (p *OrgDomainProjection) reduceDomainAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainAddedEvent) if !ok { - logging.LogWithFields("PROJE-6fXKf", "seq", event.Sequence(), "expectedType", org.OrgDomainAddedEventType, "gottenType", fmt.Sprintf("%T", event)).Error("unexpected event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-DM2DI", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-DM2DI", "reduce.wrong.event.type %s", org.OrgDomainAddedEventType) } return crdb.NewCreateStatement( e, @@ -84,6 +95,7 @@ func (p *OrgDomainProjection) reduceDomainAdded(event eventstore.Event) (*handle handler.NewCol(OrgDomainSequenceCol, e.Sequence()), handler.NewCol(OrgDomainDomainCol, e.Domain), handler.NewCol(OrgDomainOrgIDCol, e.Aggregate().ID), + handler.NewCol(OrgDomainInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(OrgDomainIsVerifiedCol, false), handler.NewCol(OrgDomainIsPrimaryCol, false), handler.NewCol(OrgDomainValidationTypeCol, domain.OrgDomainValidationTypeUnspecified), @@ -94,8 +106,7 @@ func (p *OrgDomainProjection) reduceDomainAdded(event eventstore.Event) (*handle func (p *OrgDomainProjection) reduceDomainVerificationAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainVerificationAddedEvent) if !ok { - logging.LogWithFields("PROJE-2gGSs", "seq", event.Sequence(), "expectedType", org.OrgDomainVerificationAddedEventType, "gottenType", fmt.Sprintf("%T", event)).Error("unexpected event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-EBzyu", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-EBzyu", "reduce.wrong.event.type %s", org.OrgDomainVerificationAddedEventType) } return crdb.NewUpdateStatement( e, @@ -114,8 +125,7 @@ func (p *OrgDomainProjection) reduceDomainVerificationAdded(event eventstore.Eve func (p *OrgDomainProjection) reduceDomainVerified(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainVerifiedEvent) if !ok { - logging.LogWithFields("PROJE-aeGCA", "seq", event.Sequence(), "expectedType", org.OrgDomainVerifiedEventType, "gottenType", fmt.Sprintf("%T", event)).Error("unexpected event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-3Rvkr", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-3Rvkr", "reduce.wrong.event.type %s", org.OrgDomainVerifiedEventType) } return crdb.NewUpdateStatement( e, @@ -134,8 +144,7 @@ func (p *OrgDomainProjection) reduceDomainVerified(event eventstore.Event) (*han func (p *OrgDomainProjection) reducePrimaryDomainSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainPrimarySetEvent) if !ok { - logging.LogWithFields("PROJE-6YjHo", "seq", event.Sequence(), "expectedType", org.OrgDomainPrimarySetEventType, "gottenType", fmt.Sprintf("%T", event)).Error("unexpected event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-aIuei", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-aIuei", "reduce.wrong.event.type %s", org.OrgDomainPrimarySetEventType) } return crdb.NewMultiStatement( e, @@ -167,8 +176,7 @@ func (p *OrgDomainProjection) reducePrimaryDomainSet(event eventstore.Event) (*h func (p *OrgDomainProjection) reduceDomainRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.DomainRemovedEvent) if !ok { - logging.LogWithFields("PROJE-dDnps", "seq", event.Sequence(), "expectedType", org.OrgDomainRemovedEventType, "gottenType", fmt.Sprintf("%T", event)).Error("unexpected event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-gh1Mx", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-gh1Mx", "reduce.wrong.event.type %s", org.OrgDomainRemovedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/org_domain_test.go b/internal/query/projection/org_domain_test.go index d4d8e4a881..e50bf10463 100644 --- a/internal/query/projection/org_domain_test.go +++ b/internal/query/projection/org_domain_test.go @@ -39,13 +39,14 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.org_domains (creation_date, change_date, sequence, domain, org_id, is_verified, is_primary, validation_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.org_domains (creation_date, change_date, sequence, domain, org_id, instance_id, is_verified, is_primary, validation_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, uint64(15), "domain.new", "agg-id", + "instance-id", false, false, domain.OrgDomainValidationTypeUnspecified, @@ -73,7 +74,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_domains SET (change_date, sequence, validation_type) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", + expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, validation_type) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -104,7 +105,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_domains SET (change_date, sequence, is_verified) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", + expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_verified) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -135,7 +136,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (org_id = $4) AND (is_primary = $5)", + expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (org_id = $4) AND (is_primary = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -145,7 +146,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", + expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -176,7 +177,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_domains WHERE (domain = $1) AND (org_id = $2)", + expectedStmt: "DELETE FROM projections.org_domains WHERE (domain = $1) AND (org_id = $2)", expectedArgs: []interface{}{ "domain.new", "agg-id", diff --git a/internal/query/projection/org_iam_policy.go b/internal/query/projection/org_iam_policy.go index 50e8cd5c4e..904afdee7d 100644 --- a/internal/query/projection/org_iam_policy.go +++ b/internal/query/projection/org_iam_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,27 +13,43 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type OrgIAMPolicyProjection struct { - crdb.StatementHandler -} - const ( - OrgIAMPolicyTable = "zitadel.projections.org_iam_policies" + OrgIAMPolicyTable = "projections.org_iam_policies" + OrgIAMPolicyIDCol = "id" OrgIAMPolicyCreationDateCol = "creation_date" OrgIAMPolicyChangeDateCol = "change_date" OrgIAMPolicySequenceCol = "sequence" - OrgIAMPolicyIDCol = "id" OrgIAMPolicyStateCol = "state" OrgIAMPolicyUserLoginMustBeDomainCol = "user_login_must_be_domain" OrgIAMPolicyIsDefaultCol = "is_default" OrgIAMPolicyResourceOwnerCol = "resource_owner" + OrgIAMPolicyInstanceIDCol = "instance_id" ) +type OrgIAMPolicyProjection struct { + crdb.StatementHandler +} + func NewOrgIAMPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgIAMPolicyProjection { p := new(OrgIAMPolicyProjection) config.ProjectionName = OrgIAMPolicyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(OrgIAMPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(OrgIAMPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgIAMPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(OrgIAMPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(OrgIAMPolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(OrgIAMPolicyUserLoginMustBeDomainCol, crdb.ColumnTypeBool), + crdb.NewColumn(OrgIAMPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(OrgIAMPolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(OrgIAMPolicyInstanceIDCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(OrgIAMPolicyInstanceIDCol, OrgIAMPolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -85,8 +100,7 @@ func (p *OrgIAMPolicyProjection) reduceAdded(event eventstore.Event) (*handler.S policyEvent = e.OrgIAMPolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-XakxJ", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.OrgIAMPolicyAddedEventType, iam.OrgIAMPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-CSE7A", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-CSE7A", "reduce.wrong.event.type %v", []eventstore.EventType{org.OrgIAMPolicyAddedEventType, iam.OrgIAMPolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -99,6 +113,7 @@ func (p *OrgIAMPolicyProjection) reduceAdded(event eventstore.Event) (*handler.S handler.NewCol(OrgIAMPolicyUserLoginMustBeDomainCol, policyEvent.UserLoginMustBeDomain), handler.NewCol(OrgIAMPolicyIsDefaultCol, isDefault), handler.NewCol(OrgIAMPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(OrgIAMPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), }), nil } @@ -110,8 +125,7 @@ func (p *OrgIAMPolicyProjection) reduceChanged(event eventstore.Event) (*handler case *iam.OrgIAMPolicyChangedEvent: policyEvent = e.OrgIAMPolicyChangedEvent default: - logging.LogWithFields("PROJE-SvTK0", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.OrgIAMPolicyChangedEventType, iam.OrgIAMPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-qgVug", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-qgVug", "reduce.wrong.event.type %v", []eventstore.EventType{org.OrgIAMPolicyChangedEventType, iam.OrgIAMPolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(OrgIAMPolicyChangeDateCol, policyEvent.CreationDate()), @@ -131,8 +145,7 @@ func (p *OrgIAMPolicyProjection) reduceChanged(event eventstore.Event) (*handler func (p *OrgIAMPolicyProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.OrgIAMPolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-ovQya", "seq", event.Sequence(), "expectedType", org.OrgIAMPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-JAENd", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-JAENd", "reduce.wrong.event.type %s", org.OrgIAMPolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, diff --git a/internal/query/projection/org_iam_policy_test.go b/internal/query/projection/org_iam_policy_test.go index c31838e6ee..3d769922b3 100644 --- a/internal/query/projection/org_iam_policy_test.go +++ b/internal/query/projection/org_iam_policy_test.go @@ -42,7 +42,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.org_iam_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.org_iam_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -52,6 +52,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { true, false, "ro-id", + "instance-id", }, }, }, @@ -78,7 +79,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_iam_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.org_iam_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -108,7 +109,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_iam_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.org_iam_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -137,7 +138,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.org_iam_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.org_iam_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -147,6 +148,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { true, true, "ro-id", + "instance-id", }, }, }, @@ -173,7 +175,7 @@ func TestOrgIAMPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_iam_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.org_iam_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/org_member.go b/internal/query/projection/org_member.go index 6628dca7ff..27a4764af9 100644 --- a/internal/query/projection/org_member.go +++ b/internal/query/projection/org_member.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -13,18 +11,26 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + OrgMemberProjectionTable = "projections.org_members" + OrgMemberOrgIDCol = "org_id" +) + type OrgMemberProjection struct { crdb.StatementHandler } -const ( - OrgMemberProjectionTable = "zitadel.projections.org_members" -) - func NewOrgMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgMemberProjection { p := new(OrgMemberProjection) config.ProjectionName = OrgMemberProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable( + append(memberColumns, crdb.NewColumn(OrgMemberOrgIDCol, crdb.ColumnTypeText)), + crdb.NewPrimaryKey(MemberInstanceID, OrgMemberOrgIDCol, MemberUserIDCol), + crdb.NewIndex("user_idx", []string{MemberUserIDCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -68,17 +74,10 @@ func (p *OrgMemberProjection) reducers() []handler.AggregateReducer { } } -type OrgMemberColumn string - -const ( - OrgMemberOrgIDCol = "org_id" -) - func (p *OrgMemberProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.MemberAddedEvent) if !ok { - logging.LogWithFields("HANDL-BoKBr", "seq", event.Sequence(), "expectedType", org.MemberAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-uYq4r", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uYq4r", "reduce.wrong.event.type %s", org.MemberAddedEventType) } return reduceMemberAdded(e.MemberAddedEvent, withMemberCol(OrgMemberOrgIDCol, e.Aggregate().ID)) } @@ -86,8 +85,7 @@ func (p *OrgMemberProjection) reduceAdded(event eventstore.Event) (*handler.Stat func (p *OrgMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.MemberChangedEvent) if !ok { - logging.LogWithFields("HANDL-bfqNl", "seq", event.Sequence(), "expected", org.MemberChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Bg8oM", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Bg8oM", "reduce.wrong.event.type %s", org.MemberChangedEventType) } return reduceMemberChanged(e.MemberChangedEvent, withMemberCond(OrgMemberOrgIDCol, e.Aggregate().ID)) } @@ -95,8 +93,7 @@ func (p *OrgMemberProjection) reduceChanged(event eventstore.Event) (*handler.St func (p *OrgMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.MemberCascadeRemovedEvent) if !ok { - logging.LogWithFields("HANDL-zgb6w", "seq", event.Sequence(), "expected", org.MemberCascadeRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-4twP2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-4twP2", "reduce.wrong.event.type %s", org.MemberCascadeRemovedEventType) } return reduceMemberCascadeRemoved(e.MemberCascadeRemovedEvent, withMemberCond(OrgMemberOrgIDCol, e.Aggregate().ID)) } @@ -104,8 +101,7 @@ func (p *OrgMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*han func (p *OrgMemberProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*org.MemberRemovedEvent) if !ok { - logging.LogWithFields("HANDL-KPyxE", "seq", event.Sequence(), "expected", org.MemberRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-avatH", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-avatH", "reduce.wrong.event.type %s", org.MemberRemovedEventType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.UserID), @@ -116,8 +112,7 @@ func (p *OrgMemberProjection) reduceRemoved(event eventstore.Event) (*handler.St func (p *OrgMemberProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-f5pgn", "seq", event.Sequence(), "expected", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-eBMqH", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-eBMqH", "reduce.wrong.event.type %s", user.UserRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.Aggregate().ID)) } @@ -129,8 +124,7 @@ func (p *OrgMemberProjection) reduceOrgRemoved(event eventstore.Event) (*handler // if org A is deleted, the membership wouldn't be deleted e, ok := event.(*org.OrgRemovedEvent) if !ok { - logging.LogWithFields("HANDL-E5lDs", "seq", event.Sequence(), "expected", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-jnGAV", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-jnGAV", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } return reduceMemberRemoved(e, withMemberCond(OrgMemberOrgIDCol, e.Aggregate().ID)) } diff --git a/internal/query/projection/org_member_test.go b/internal/query/projection/org_member_test.go index 9f0a3ed4e0..012bccd738 100644 --- a/internal/query/projection/org_member_test.go +++ b/internal/query/projection/org_member_test.go @@ -3,13 +3,14 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/repository/org" "github.com/caos/zitadel/internal/repository/user" - "github.com/lib/pq" ) func TestOrgMemberProjection_reduces(t *testing.T) { @@ -43,7 +44,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.org_members (user_id, roles, creation_date, change_date, sequence, resource_owner, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.org_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "user-id", pq.StringArray{"role"}, @@ -51,6 +52,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", "agg-id", }, }, @@ -79,7 +81,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.org_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (org_id = $5)", + expectedStmt: "UPDATE projections.org_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (org_id = $5)", expectedArgs: []interface{}{ pq.StringArray{"role", "changed"}, anyArg{}, @@ -112,7 +114,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_members WHERE (user_id = $1) AND (org_id = $2)", + expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1) AND (org_id = $2)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -142,7 +144,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_members WHERE (user_id = $1) AND (org_id = $2)", + expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1) AND (org_id = $2)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -170,7 +172,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.org_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -197,7 +199,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.org_members WHERE (org_id = $1)", + expectedStmt: "DELETE FROM projections.org_members WHERE (org_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/org_test.go b/internal/query/projection/org_test.go index 565e8b6a7b..054087a57e 100644 --- a/internal/query/projection/org_test.go +++ b/internal/query/projection/org_test.go @@ -39,7 +39,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.orgs SET (change_date, sequence, primary_domain) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, primary_domain) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -69,7 +69,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -99,7 +99,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -129,7 +129,7 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.orgs SET (change_date, sequence, name) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, name) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -177,12 +177,13 @@ func TestOrgProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.orgs (id, creation_date, change_date, resource_owner, sequence, name, org_state) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.orgs (id, creation_date, change_date, resource_owner, instance_id, sequence, name, org_state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "name", domain.OrgStateActive, diff --git a/internal/query/projection/password_age_policy.go b/internal/query/projection/password_age_policy.go index 348b8ec03f..71ec3117a0 100644 --- a/internal/query/projection/password_age_policy.go +++ b/internal/query/projection/password_age_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,18 +13,45 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) +const ( + PasswordAgeTable = "projections.password_age_policies" + + AgePolicyIDCol = "id" + AgePolicyCreationDateCol = "creation_date" + AgePolicyChangeDateCol = "change_date" + AgePolicySequenceCol = "sequence" + AgePolicyStateCol = "state" + AgePolicyIsDefaultCol = "is_default" + AgePolicyResourceOwnerCol = "resource_owner" + AgePolicyInstanceIDCol = "instance_id" + AgePolicyExpireWarnDaysCol = "expire_warn_days" + AgePolicyMaxAgeDaysCol = "max_age_days" +) + type PasswordAgeProjection struct { crdb.StatementHandler } -const ( - PasswordAgeTable = "zitadel.projections.password_age_policies" -) - func NewPasswordAgeProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordAgeProjection { p := new(PasswordAgeProjection) config.ProjectionName = PasswordAgeTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(AgePolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AgePolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AgePolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(AgePolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(AgePolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(AgePolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(AgePolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(AgePolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(AgePolicyExpireWarnDaysCol, crdb.ColumnTypeInt64), + crdb.NewColumn(AgePolicyMaxAgeDaysCol, crdb.ColumnTypeInt64), + }, + crdb.NewPrimaryKey(AgePolicyInstanceIDCol, AgePolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -76,8 +102,7 @@ func (p *PasswordAgeProjection) reduceAdded(event eventstore.Event) (*handler.St policyEvent = e.PasswordAgePolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-stxcL", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PasswordAgePolicyAddedEventType, iam.PasswordAgePolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-CJqF0", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-CJqF0", "reduce.wrong.event.type %v", []eventstore.EventType{org.PasswordAgePolicyAddedEventType, iam.PasswordAgePolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -91,6 +116,7 @@ func (p *PasswordAgeProjection) reduceAdded(event eventstore.Event) (*handler.St handler.NewCol(AgePolicyMaxAgeDaysCol, policyEvent.MaxAgeDays), handler.NewCol(AgePolicyIsDefaultCol, isDefault), handler.NewCol(AgePolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(AgePolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), }), nil } @@ -102,8 +128,7 @@ func (p *PasswordAgeProjection) reduceChanged(event eventstore.Event) (*handler. case *iam.PasswordAgePolicyChangedEvent: policyEvent = e.PasswordAgePolicyChangedEvent default: - logging.LogWithFields("PROJE-EZ53p", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PasswordAgePolicyChangedEventType, iam.PasswordAgePolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-i7FZt", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-i7FZt", "reduce.wrong.event.type %v", []eventstore.EventType{org.PasswordAgePolicyChangedEventType, iam.PasswordAgePolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(AgePolicyChangeDateCol, policyEvent.CreationDate()), @@ -126,8 +151,7 @@ func (p *PasswordAgeProjection) reduceChanged(event eventstore.Event) (*handler. func (p *PasswordAgeProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.PasswordAgePolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-iwqfN", "seq", event.Sequence(), "expectedType", org.PasswordAgePolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-EtHWB", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-EtHWB", "reduce.wrong.event.type %s", org.PasswordAgePolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, @@ -135,15 +159,3 @@ func (p *PasswordAgeProjection) reduceRemoved(event eventstore.Event) (*handler. handler.NewCond(AgePolicyIDCol, policyEvent.Aggregate().ID), }), nil } - -const ( - AgePolicyCreationDateCol = "creation_date" - AgePolicyChangeDateCol = "change_date" - AgePolicySequenceCol = "sequence" - AgePolicyIDCol = "id" - AgePolicyStateCol = "state" - AgePolicyExpireWarnDaysCol = "expire_warn_days" - AgePolicyMaxAgeDaysCol = "max_age_days" - AgePolicyIsDefaultCol = "is_default" - AgePolicyResourceOwnerCol = "resource_owner" -) diff --git a/internal/query/projection/password_age_policy_test.go b/internal/query/projection/password_age_policy_test.go index 3ce9877a8f..df3d60e185 100644 --- a/internal/query/projection/password_age_policy_test.go +++ b/internal/query/projection/password_age_policy_test.go @@ -43,7 +43,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.password_age_policies (creation_date, change_date, sequence, id, state, expire_warn_days, max_age_days, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.password_age_policies (creation_date, change_date, sequence, id, state, expire_warn_days, max_age_days, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -54,6 +54,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { uint64(13), false, "ro-id", + "instance-id", }, }, }, @@ -81,7 +82,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -112,7 +113,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.password_age_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.password_age_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -142,7 +143,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.password_age_policies (creation_date, change_date, sequence, id, state, expire_warn_days, max_age_days, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.password_age_policies (creation_date, change_date, sequence, id, state, expire_warn_days, max_age_days, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -153,6 +154,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { uint64(13), true, "ro-id", + "instance-id", }, }, }, @@ -180,7 +182,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/password_complexity_policy.go b/internal/query/projection/password_complexity_policy.go index 0a5660b571..e2beaba973 100644 --- a/internal/query/projection/password_complexity_policy.go +++ b/internal/query/projection/password_complexity_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,18 +13,51 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) +const ( + PasswordComplexityTable = "projections.password_complexity_policies" + + ComplexityPolicyIDCol = "id" + ComplexityPolicyCreationDateCol = "creation_date" + ComplexityPolicyChangeDateCol = "change_date" + ComplexityPolicySequenceCol = "sequence" + ComplexityPolicyStateCol = "state" + ComplexityPolicyIsDefaultCol = "is_default" + ComplexityPolicyResourceOwnerCol = "resource_owner" + ComplexityPolicyInstanceIDCol = "instance_id" + ComplexityPolicyMinLengthCol = "min_length" + ComplexityPolicyHasLowercaseCol = "has_lowercase" + ComplexityPolicyHasUppercaseCol = "has_uppercase" + ComplexityPolicyHasSymbolCol = "has_symbol" + ComplexityPolicyHasNumberCol = "has_number" +) + type PasswordComplexityProjection struct { crdb.StatementHandler } -const ( - PasswordComplexityTable = "zitadel.projections.password_complexity_policies" -) - func NewPasswordComplexityProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordComplexityProjection { p := new(PasswordComplexityProjection) config.ProjectionName = PasswordComplexityTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(ComplexityPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(ComplexityPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ComplexityPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ComplexityPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(ComplexityPolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(ComplexityPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(ComplexityPolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(ComplexityPolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(ComplexityPolicyMinLengthCol, crdb.ColumnTypeInt64), + crdb.NewColumn(ComplexityPolicyHasLowercaseCol, crdb.ColumnTypeBool), + crdb.NewColumn(ComplexityPolicyHasUppercaseCol, crdb.ColumnTypeBool), + crdb.NewColumn(ComplexityPolicyHasSymbolCol, crdb.ColumnTypeBool), + crdb.NewColumn(ComplexityPolicyHasNumberCol, crdb.ColumnTypeBool), + }, + crdb.NewPrimaryKey(ComplexityPolicyInstanceIDCol, ComplexityPolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -76,8 +108,7 @@ func (p *PasswordComplexityProjection) reduceAdded(event eventstore.Event) (*han policyEvent = e.PasswordComplexityPolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-mP8AR", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PasswordComplexityPolicyAddedEventType, iam.PasswordComplexityPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-KTHmJ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-KTHmJ", "reduce.wrong.event.type %v", []eventstore.EventType{org.PasswordComplexityPolicyAddedEventType, iam.PasswordComplexityPolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -93,6 +124,7 @@ func (p *PasswordComplexityProjection) reduceAdded(event eventstore.Event) (*han handler.NewCol(ComplexityPolicyHasSymbolCol, policyEvent.HasSymbol), handler.NewCol(ComplexityPolicyHasNumberCol, policyEvent.HasNumber), handler.NewCol(ComplexityPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(ComplexityPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), handler.NewCol(ComplexityPolicyIsDefaultCol, isDefault), }), nil } @@ -105,8 +137,7 @@ func (p *PasswordComplexityProjection) reduceChanged(event eventstore.Event) (*h case *iam.PasswordComplexityPolicyChangedEvent: policyEvent = e.PasswordComplexityPolicyChangedEvent default: - logging.LogWithFields("PROJE-L4UHn", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PasswordComplexityPolicyChangedEventType, iam.PasswordComplexityPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-cf3Xb", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-cf3Xb", "reduce.wrong.event.type %v", []eventstore.EventType{org.PasswordComplexityPolicyChangedEventType, iam.PasswordComplexityPolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(ComplexityPolicyChangeDateCol, policyEvent.CreationDate()), @@ -138,8 +169,7 @@ func (p *PasswordComplexityProjection) reduceChanged(event eventstore.Event) (*h func (p *PasswordComplexityProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.PasswordComplexityPolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-ibd0c", "seq", event.Sequence(), "expectedType", org.PasswordComplexityPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-wttCd", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-wttCd", "reduce.wrong.event.type %s", org.PasswordComplexityPolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, @@ -147,18 +177,3 @@ func (p *PasswordComplexityProjection) reduceRemoved(event eventstore.Event) (*h handler.NewCond(ComplexityPolicyIDCol, policyEvent.Aggregate().ID), }), nil } - -const ( - ComplexityPolicyCreationDateCol = "creation_date" - ComplexityPolicyChangeDateCol = "change_date" - ComplexityPolicySequenceCol = "sequence" - ComplexityPolicyIDCol = "id" - ComplexityPolicyStateCol = "state" - ComplexityPolicyMinLengthCol = "min_length" - ComplexityPolicyHasLowercaseCol = "has_lowercase" - ComplexityPolicyHasUppercaseCol = "has_uppercase" - ComplexityPolicyHasSymbolCol = "has_symbol" - ComplexityPolicyHasNumberCol = "has_number" - ComplexityPolicyIsDefaultCol = "is_default" - ComplexityPolicyResourceOwnerCol = "resource_owner" -) diff --git a/internal/query/projection/password_complexity_policy_test.go b/internal/query/projection/password_complexity_policy_test.go index 20ce330120..559a108454 100644 --- a/internal/query/projection/password_complexity_policy_test.go +++ b/internal/query/projection/password_complexity_policy_test.go @@ -46,7 +46,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.password_complexity_policies (creation_date, change_date, sequence, id, state, min_length, has_lowercase, has_uppercase, has_symbol, has_number, resource_owner, is_default) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", + expectedStmt: "INSERT INTO projections.password_complexity_policies (creation_date, change_date, sequence, id, state, min_length, has_lowercase, has_uppercase, has_symbol, has_number, resource_owner, instance_id, is_default) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -59,6 +59,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { true, true, "ro-id", + "instance-id", false, }, }, @@ -90,7 +91,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.password_complexity_policies SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", + expectedStmt: "UPDATE projections.password_complexity_policies SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -124,7 +125,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.password_complexity_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.password_complexity_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -157,7 +158,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.password_complexity_policies (creation_date, change_date, sequence, id, state, min_length, has_lowercase, has_uppercase, has_symbol, has_number, resource_owner, is_default) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", + expectedStmt: "INSERT INTO projections.password_complexity_policies (creation_date, change_date, sequence, id, state, min_length, has_lowercase, has_uppercase, has_symbol, has_number, resource_owner, instance_id, is_default) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -170,6 +171,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { true, true, "ro-id", + "instance-id", true, }, }, @@ -201,7 +203,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.password_complexity_policies SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", + expectedStmt: "UPDATE projections.password_complexity_policies SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/privacy_policy.go b/internal/query/projection/privacy_policy.go index 552c8d031f..2a36ac2cc8 100644 --- a/internal/query/projection/privacy_policy.go +++ b/internal/query/projection/privacy_policy.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -14,28 +13,45 @@ import ( "github.com/caos/zitadel/internal/repository/policy" ) -type PrivacyPolicyProjection struct { - crdb.StatementHandler -} - const ( - PrivacyPolicyTable = "zitadel.projections.privacy_policies" + PrivacyPolicyTable = "projections.privacy_policies" + PrivacyPolicyIDCol = "id" PrivacyPolicyCreationDateCol = "creation_date" PrivacyPolicyChangeDateCol = "change_date" PrivacyPolicySequenceCol = "sequence" - PrivacyPolicyIDCol = "id" PrivacyPolicyStateCol = "state" - PrivacyPolicyPrivacyLinkCol = "privacy_link" - PrivacyPolicyTOSLinkCol = "tos_link" PrivacyPolicyIsDefaultCol = "is_default" PrivacyPolicyResourceOwnerCol = "resource_owner" + PrivacyPolicyInstanceIDCol = "instance_id" + PrivacyPolicyPrivacyLinkCol = "privacy_link" + PrivacyPolicyTOSLinkCol = "tos_link" ) +type PrivacyPolicyProjection struct { + crdb.StatementHandler +} + func NewPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PrivacyPolicyProjection { p := new(PrivacyPolicyProjection) config.ProjectionName = PrivacyPolicyTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(PrivacyPolicyIDCol, crdb.ColumnTypeText), + crdb.NewColumn(PrivacyPolicyCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(PrivacyPolicyChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(PrivacyPolicySequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(PrivacyPolicyStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(PrivacyPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(PrivacyPolicyResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(PrivacyPolicyInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText), + crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -86,8 +102,7 @@ func (p *PrivacyPolicyProjection) reduceAdded(event eventstore.Event) (*handler. policyEvent = e.PrivacyPolicyAddedEvent isDefault = true default: - logging.LogWithFields("PROJE-BrdLn", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PrivacyPolicyAddedEventType, iam.PrivacyPolicyAddedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-kRNh8", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-kRNh8", "reduce.wrong.event.type %v", []eventstore.EventType{org.PrivacyPolicyAddedEventType, iam.PrivacyPolicyAddedEventType}) } return crdb.NewCreateStatement( &policyEvent, @@ -101,6 +116,7 @@ func (p *PrivacyPolicyProjection) reduceAdded(event eventstore.Event) (*handler. handler.NewCol(PrivacyPolicyTOSLinkCol, policyEvent.TOSLink), handler.NewCol(PrivacyPolicyIsDefaultCol, isDefault), handler.NewCol(PrivacyPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), + handler.NewCol(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), }), nil } @@ -112,8 +128,7 @@ func (p *PrivacyPolicyProjection) reduceChanged(event eventstore.Event) (*handle case *iam.PrivacyPolicyChangedEvent: policyEvent = e.PrivacyPolicyChangedEvent default: - logging.LogWithFields("PROJE-1nQWm", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{org.PrivacyPolicyChangedEventType, iam.PrivacyPolicyChangedEventType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-91weZ", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-91weZ", "reduce.wrong.event.type %v", []eventstore.EventType{org.PrivacyPolicyChangedEventType, iam.PrivacyPolicyChangedEventType}) } cols := []handler.Column{ handler.NewCol(PrivacyPolicyChangeDateCol, policyEvent.CreationDate()), @@ -136,8 +151,7 @@ func (p *PrivacyPolicyProjection) reduceChanged(event eventstore.Event) (*handle func (p *PrivacyPolicyProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.PrivacyPolicyRemovedEvent) if !ok { - logging.LogWithFields("PROJE-hN5Ip", "seq", event.Sequence(), "expectedType", org.PrivacyPolicyRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-FvtGO", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-FvtGO", "reduce.wrong.event.type %s", org.PrivacyPolicyRemovedEventType) } return crdb.NewDeleteStatement( policyEvent, diff --git a/internal/query/projection/privacy_policy_test.go b/internal/query/projection/privacy_policy_test.go index c94fc9735a..9748f6a3d8 100644 --- a/internal/query/projection/privacy_policy_test.go +++ b/internal/query/projection/privacy_policy_test.go @@ -43,7 +43,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -54,6 +54,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { "http://tos.link", false, "ro-id", + "instance-id", }, }, }, @@ -81,7 +82,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -112,7 +113,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.privacy_policies WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.privacy_policies WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -142,7 +143,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -153,6 +154,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { "http://tos.link", true, "ro-id", + "instance-id", }, }, }, @@ -180,7 +182,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)", + expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/project.go b/internal/query/projection/project.go index fe552f4f62..de97b35be4 100644 --- a/internal/query/projection/project.go +++ b/internal/query/projection/project.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -12,18 +11,52 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + ProjectProjectionTable = "projections.projects" + + ProjectColumnID = "id" + ProjectColumnCreationDate = "creation_date" + ProjectColumnChangeDate = "change_date" + ProjectColumnSequence = "sequence" + ProjectColumnState = "state" + ProjectColumnResourceOwner = "resource_owner" + ProjectColumnInstanceID = "instance_id" + ProjectColumnName = "name" + ProjectColumnProjectRoleAssertion = "project_role_assertion" + ProjectColumnProjectRoleCheck = "project_role_check" + ProjectColumnHasProjectCheck = "has_project_check" + ProjectColumnPrivateLabelingSetting = "private_labeling_setting" + ProjectColumnCreator = "creator_id" //TODO: necessary? +) + type ProjectProjection struct { crdb.StatementHandler } -const ( - ProjectProjectionTable = "zitadel.projections.projects" -) - func NewProjectProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectProjection { p := new(ProjectProjection) config.ProjectionName = ProjectProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(ProjectColumnID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(ProjectColumnState, crdb.ColumnTypeEnum), + crdb.NewColumn(ProjectColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(ProjectColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectColumnName, crdb.ColumnTypeText), + crdb.NewColumn(ProjectColumnProjectRoleAssertion, crdb.ColumnTypeBool), + crdb.NewColumn(ProjectColumnProjectRoleCheck, crdb.ColumnTypeBool), + crdb.NewColumn(ProjectColumnHasProjectCheck, crdb.ColumnTypeBool), + crdb.NewColumn(ProjectColumnPrivateLabelingSetting, crdb.ColumnTypeEnum), + crdb.NewColumn(ProjectColumnCreator, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(ProjectColumnInstanceID, ProjectColumnID), + crdb.NewIndex("ro_idx", []string{ProjectColumnResourceOwner}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -58,26 +91,10 @@ func (p *ProjectProjection) reducers() []handler.AggregateReducer { } } -const ( - ProjectColumnID = "id" - ProjectColumnName = "name" - ProjectColumnProjectRoleAssertion = "project_role_assertion" - ProjectColumnProjectRoleCheck = "project_role_check" - ProjectColumnHasProjectCheck = "has_project_check" - ProjectColumnPrivateLabelingSetting = "private_labeling_setting" - ProjectColumnCreationDate = "creation_date" - ProjectColumnChangeDate = "change_date" - ProjectColumnResourceOwner = "resource_owner" - ProjectColumnCreator = "creator_id" - ProjectColumnState = "state" - ProjectColumnSequence = "sequence" -) - func (p *ProjectProjection) reduceProjectAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectAddedEvent) if !ok { - logging.LogWithFields("HANDL-MFOsd", "seq", event.Sequence(), "expectedType", project.ProjectAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-l000S", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-l000S", "reduce.wrong.event.type %s", project.ProjectAddedType) } return crdb.NewCreateStatement( e, @@ -86,6 +103,7 @@ func (p *ProjectProjection) reduceProjectAdded(event eventstore.Event) (*handler handler.NewCol(ProjectColumnCreationDate, e.CreationDate()), handler.NewCol(ProjectColumnChangeDate, e.CreationDate()), handler.NewCol(ProjectColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(ProjectColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(ProjectColumnSequence, e.Sequence()), handler.NewCol(ProjectColumnName, e.Name), handler.NewCol(ProjectColumnProjectRoleAssertion, e.ProjectRoleAssertion), @@ -101,8 +119,7 @@ func (p *ProjectProjection) reduceProjectAdded(event eventstore.Event) (*handler func (p *ProjectProjection) reduceProjectChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectChangeEvent) if !ok { - logging.LogWithFields("HANDL-dk2iF", "seq", event.Sequence(), "expected", project.ProjectChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-s00Fs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-s00Fs", "reduce.wrong.event.type %s", project.ProjectChangedType) } if e.Name == nil && e.HasProjectCheck == nil && e.ProjectRoleAssertion == nil && e.ProjectRoleCheck == nil && e.PrivateLabelingSetting == nil { return crdb.NewNoOpStatement(e), nil @@ -138,8 +155,7 @@ func (p *ProjectProjection) reduceProjectChanged(event eventstore.Event) (*handl func (p *ProjectProjection) reduceProjectDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectDeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-8Nf2s", "seq", event.Sequence(), "expectedType", project.ProjectDeactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-LLp0f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-LLp0f", "reduce.wrong.event.type %s", project.ProjectDeactivatedType) } return crdb.NewUpdateStatement( e, @@ -157,8 +173,7 @@ func (p *ProjectProjection) reduceProjectDeactivated(event eventstore.Event) (*h func (p *ProjectProjection) reduceProjectReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-sm99f", "seq", event.Sequence(), "expectedType", project.ProjectReactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-9J98f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-9J98f", "reduce.wrong.event.type %s", project.ProjectReactivatedType) } return crdb.NewUpdateStatement( e, @@ -176,8 +191,7 @@ func (p *ProjectProjection) reduceProjectReactivated(event eventstore.Event) (*h func (p *ProjectProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-mL0sf", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-5N9fs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-5N9fs", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/project_grant.go b/internal/query/projection/project_grant.go index adaddcb27e..2bcd202efe 100644 --- a/internal/query/projection/project_grant.go +++ b/internal/query/projection/project_grant.go @@ -3,26 +3,59 @@ package projection import ( "context" - "github.com/caos/logging" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/handler/crdb" "github.com/caos/zitadel/internal/repository/project" - "github.com/lib/pq" +) + +const ( + ProjectGrantProjectionTable = "projections.project_grants" + + ProjectGrantColumnGrantID = "grant_id" + ProjectGrantColumnCreationDate = "creation_date" + ProjectGrantColumnChangeDate = "change_date" + ProjectGrantColumnSequence = "sequence" + ProjectGrantColumnState = "state" + ProjectGrantColumnResourceOwner = "resource_owner" + ProjectGrantColumnInstanceID = "instance_id" + ProjectGrantColumnProjectID = "project_id" + ProjectGrantColumnGrantedOrgID = "granted_org_id" + ProjectGrantColumnRoleKeys = "granted_role_keys" + ProjectGrantColumnCreator = "creator_id" //TODO: necessary? ) type ProjectGrantProjection struct { crdb.StatementHandler } -const ProjectGrantProjectionTable = "zitadel.projections.project_grants" - func NewProjectGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantProjection { p := new(ProjectGrantProjection) config.ProjectionName = ProjectGrantProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(ProjectGrantColumnGrantID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectGrantColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectGrantColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(ProjectGrantColumnState, crdb.ColumnTypeEnum), + crdb.NewColumn(ProjectGrantColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantColumnProjectID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantColumnGrantedOrgID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantColumnRoleKeys, crdb.ColumnTypeTextArray), + crdb.NewColumn(ProjectGrantColumnCreator, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(ProjectGrantColumnInstanceID, ProjectGrantColumnGrantID), + crdb.NewIndex("ro_idx", []string{ProjectGrantColumnResourceOwner}), + crdb.NewIndex("granted_org_idx", []string{ProjectGrantColumnGrantedOrgID}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -65,24 +98,10 @@ func (p *ProjectGrantProjection) reducers() []handler.AggregateReducer { } } -const ( - ProjectGrantColumnProjectID = "project_id" - ProjectGrantColumnGrantID = "grant_id" - ProjectGrantColumnCreationDate = "creation_date" - ProjectGrantColumnChangeDate = "change_date" - ProjectGrantColumnResourceOwner = "resource_owner" - ProjectGrantColumnState = "state" - ProjectGrantColumnSequence = "sequence" - ProjectGrantColumnGrantedOrgID = "granted_org_id" - ProjectGrantColumnRoleKeys = "granted_role_keys" - ProjectGrantColumnCreator = "creator_id" -) - func (p *ProjectGrantProjection) reduceProjectGrantAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantAddedEvent) if !ok { - logging.LogWithFields("HANDL-Mi4g9", "seq", event.Sequence(), "expectedType", project.GrantAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-g92Fg", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-g92Fg", "reduce.wrong.event.type %s", project.GrantAddedType) } return crdb.NewCreateStatement( e, @@ -92,6 +111,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantAdded(event eventstore.Event) handler.NewCol(ProjectGrantColumnCreationDate, e.CreationDate()), handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()), handler.NewCol(ProjectGrantColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(ProjectGrantColumnState, domain.ProjectGrantStateActive), handler.NewCol(ProjectGrantColumnSequence, e.Sequence()), handler.NewCol(ProjectGrantColumnGrantedOrgID, e.GrantedOrgID), @@ -104,8 +124,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantAdded(event eventstore.Event) func (p *ProjectGrantProjection) reduceProjectGrantChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantChangedEvent) if !ok { - logging.LogWithFields("HANDL-M00fH", "seq", event.Sequence(), "expectedType", project.GrantChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-g0fg4", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-g0fg4", "reduce.wrong.event.type %s", project.GrantChangedType) } return crdb.NewUpdateStatement( e, @@ -124,8 +143,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantChanged(event eventstore.Even func (p *ProjectGrantProjection) reduceProjectGrantCascadeChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantCascadeChangedEvent) if !ok { - logging.LogWithFields("HANDL-K0fwR", "seq", event.Sequence(), "expectedType", project.GrantCascadeChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-ll9Ts", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-ll9Ts", "reduce.wrong.event.type %s", project.GrantCascadeChangedType) } return crdb.NewUpdateStatement( e, @@ -144,8 +162,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantCascadeChanged(event eventsto func (p *ProjectGrantProjection) reduceProjectGrantDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantDeactivateEvent) if !ok { - logging.LogWithFields("HANDL-Ple9f", "seq", event.Sequence(), "expectedType", project.GrantDeactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-0fj2f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-0fj2f", "reduce.wrong.event.type %s", project.GrantDeactivatedType) } return crdb.NewUpdateStatement( e, @@ -164,8 +181,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantDeactivated(event eventstore. func (p *ProjectGrantProjection) reduceProjectGrantReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-Ip0hr", "seq", event.Sequence(), "expectedType", project.GrantReactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-2M0ve", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-2M0ve", "reduce.wrong.event.type %s", project.GrantReactivatedType) } return crdb.NewUpdateStatement( e, @@ -184,8 +200,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantReactivated(event eventstore. func (p *ProjectGrantProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantRemovedEvent) if !ok { - logging.LogWithFields("HANDL-M0pfs", "seq", event.Sequence(), "expectedType", project.GrantRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-o0w4f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-o0w4f", "reduce.wrong.event.type %s", project.GrantRemovedType) } return crdb.NewDeleteStatement( e, @@ -199,8 +214,7 @@ func (p *ProjectGrantProjection) reduceProjectGrantRemoved(event eventstore.Even func (p *ProjectGrantProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-Ms0fe", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-gn9rw", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-gn9rw", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/project_grant_member.go b/internal/query/projection/project_grant_member.go index 07e7989d1b..dec7f37066 100644 --- a/internal/query/projection/project_grant_member.go +++ b/internal/query/projection/project_grant_member.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -15,18 +13,31 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + ProjectGrantMemberProjectionTable = "projections.project_grant_members" + ProjectGrantMemberProjectIDCol = "project_id" + ProjectGrantMemberGrantIDCol = "grant_id" +) + type ProjectGrantMemberProjection struct { crdb.StatementHandler } -const ( - ProjectGrantMemberProjectionTable = "zitadel.projections.project_grant_members" -) - func NewProjectGrantMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantMemberProjection { p := new(ProjectGrantMemberProjection) config.ProjectionName = ProjectGrantMemberProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable( + append(memberColumns, + crdb.NewColumn(ProjectGrantMemberProjectIDCol, crdb.ColumnTypeText), + crdb.NewColumn(ProjectGrantMemberGrantIDCol, crdb.ColumnTypeText), + ), + crdb.NewPrimaryKey(MemberInstanceID, ProjectGrantMemberProjectIDCol, ProjectGrantMemberGrantIDCol, MemberUserIDCol), + crdb.NewIndex("user_idx", []string{MemberUserIDCol}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -83,18 +94,10 @@ func (p *ProjectGrantMemberProjection) reducers() []handler.AggregateReducer { } } -type ProjectGrantMemberColumn string - -const ( - ProjectGrantMemberProjectIDCol = "project_id" - ProjectGrantMemberGrantIDCol = "grant_id" -) - func (p *ProjectGrantMemberProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantMemberAddedEvent) if !ok { - logging.LogWithFields("HANDL-csr8B", "seq", event.Sequence(), "expectedType", project.GrantMemberAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-0EBQf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-0EBQf", "reduce.wrong.event.type %s", project.GrantMemberAddedType) } return reduceMemberAdded( *member.NewMemberAddedEvent(&e.BaseEvent, e.UserID, e.Roles...), @@ -106,8 +109,7 @@ func (p *ProjectGrantMemberProjection) reduceAdded(event eventstore.Event) (*han func (p *ProjectGrantMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantMemberChangedEvent) if !ok { - logging.LogWithFields("HANDL-ZubbI", "seq", event.Sequence(), "expectedType", project.GrantMemberChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-YX5Tk", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-YX5Tk", "reduce.wrong.event.type %s", project.GrantMemberChangedType) } return reduceMemberChanged( *member.NewMemberChangedEvent(&e.BaseEvent, e.UserID, e.Roles...), @@ -119,8 +121,7 @@ func (p *ProjectGrantMemberProjection) reduceChanged(event eventstore.Event) (*h func (p *ProjectGrantMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantMemberCascadeRemovedEvent) if !ok { - logging.LogWithFields("HANDL-azx7K", "seq", event.Sequence(), "expectedType", project.GrantMemberCascadeRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-adnHG", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-adnHG", "reduce.wrong.event.type %s", project.GrantMemberCascadeRemovedType) } return reduceMemberCascadeRemoved( *member.NewCascadeRemovedEvent(&e.BaseEvent, e.UserID), @@ -132,8 +133,7 @@ func (p *ProjectGrantMemberProjection) reduceCascadeRemoved(event eventstore.Eve func (p *ProjectGrantMemberProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantMemberRemovedEvent) if !ok { - logging.LogWithFields("HANDL-6Z4dH", "seq", event.Sequence(), "expectedType", project.GrantMemberRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-MGNnA", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-MGNnA", "reduce.wrong.event.type %s", project.GrantMemberRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.UserID), @@ -145,8 +145,7 @@ func (p *ProjectGrantMemberProjection) reduceRemoved(event eventstore.Event) (*h func (p *ProjectGrantMemberProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-UVMmT", "seq", event.Sequence(), "expected", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-rufJr", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-rufJr", "reduce.wrong.event.type %s", user.UserRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.Aggregate().ID)) } @@ -158,8 +157,7 @@ func (p *ProjectGrantMemberProjection) reduceOrgRemoved(event eventstore.Event) // if org A is deleted, the membership wouldn't be deleted e, ok := event.(*org.OrgRemovedEvent) if !ok { - logging.LogWithFields("HANDL-Sq9FV", "seq", event.Sequence(), "expected", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Zzp6o", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Zzp6o", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } return reduceMemberRemoved(e, withMemberCond(MemberResourceOwner, e.Aggregate().ID)) } @@ -167,8 +165,7 @@ func (p *ProjectGrantMemberProjection) reduceOrgRemoved(event eventstore.Event) func (p *ProjectGrantMemberProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-sGmCA", "seq", event.Sequence(), "expected", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-JLODy", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-JLODy", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return reduceMemberRemoved(e, withMemberCond(ProjectGrantMemberProjectIDCol, e.Aggregate().ID)) } @@ -176,8 +173,7 @@ func (p *ProjectGrantMemberProjection) reduceProjectRemoved(event eventstore.Eve func (p *ProjectGrantMemberProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantRemovedEvent) if !ok { - logging.LogWithFields("HANDL-sHabO", "seq", event.Sequence(), "expected", project.GrantRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-D1J9R", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-D1J9R", "reduce.wrong.event.type %s", project.GrantRemovedType) } return reduceMemberRemoved(e, withMemberCond(ProjectGrantMemberGrantIDCol, e.GrantID), diff --git a/internal/query/projection/project_grant_member_test.go b/internal/query/projection/project_grant_member_test.go index 559c09ed9d..7fc34927a9 100644 --- a/internal/query/projection/project_grant_member_test.go +++ b/internal/query/projection/project_grant_member_test.go @@ -3,6 +3,8 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -10,7 +12,6 @@ import ( "github.com/caos/zitadel/internal/repository/org" "github.com/caos/zitadel/internal/repository/project" "github.com/caos/zitadel/internal/repository/user" - "github.com/lib/pq" ) func TestProjectGrantMemberProjection_reduces(t *testing.T) { @@ -45,7 +46,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.project_grant_members (user_id, roles, creation_date, change_date, sequence, resource_owner, project_id, grant_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.project_grant_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id, grant_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "user-id", pq.StringArray{"role"}, @@ -53,6 +54,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", "agg-id", "grant-id", }, @@ -83,7 +85,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_grant_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5) AND (grant_id = $6)", + expectedStmt: "UPDATE projections.project_grant_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5) AND (grant_id = $6)", expectedArgs: []interface{}{ pq.StringArray{"role", "changed"}, anyArg{}, @@ -118,7 +120,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -150,7 +152,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1) AND (project_id = $2) AND (grant_id = $3)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -179,7 +181,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -206,7 +208,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (resource_owner = $1)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (resource_owner = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -233,7 +235,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (project_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -260,7 +262,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grant_members WHERE (grant_id = $1) AND (project_id = $2)", + expectedStmt: "DELETE FROM projections.project_grant_members WHERE (grant_id = $1) AND (project_id = $2)", expectedArgs: []interface{}{ "grant-id", "agg-id", diff --git a/internal/query/projection/project_grant_test.go b/internal/query/projection/project_grant_test.go index 19a3ea586c..e6d188dcf9 100644 --- a/internal/query/projection/project_grant_test.go +++ b/internal/query/projection/project_grant_test.go @@ -3,13 +3,14 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/repository/project" - "github.com/lib/pq" ) func TestProjectGrantProjection_reduces(t *testing.T) { @@ -40,7 +41,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grants WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.project_grants WHERE (project_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -67,7 +68,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_grants WHERE (grant_id = $1) AND (project_id = $2)", + expectedStmt: "DELETE FROM projections.project_grants WHERE (grant_id = $1) AND (project_id = $2)", expectedArgs: []interface{}{ "grant-id", "agg-id", @@ -95,7 +96,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", + expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -126,7 +127,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", + expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -157,7 +158,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", + expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -188,7 +189,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", + expectedStmt: "UPDATE projections.project_grants SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -219,13 +220,14 @@ func TestProjectGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.project_grants (grant_id, project_id, creation_date, change_date, resource_owner, state, sequence, granted_org_id, granted_role_keys, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.project_grants (grant_id, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence, granted_org_id, granted_role_keys, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "grant-id", "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.ProjectGrantStateActive, uint64(15), "granted-org-id", diff --git a/internal/query/projection/project_member.go b/internal/query/projection/project_member.go index dd3dafb145..83431f018f 100644 --- a/internal/query/projection/project_member.go +++ b/internal/query/projection/project_member.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -15,18 +13,29 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + ProjectMemberProjectionTable = "projections.project_members" + ProjectMemberProjectIDCol = "project_id" +) + type ProjectMemberProjection struct { crdb.StatementHandler } -const ( - ProjectMemberProjectionTable = "zitadel.projections.project_members" -) - func NewProjectMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectMemberProjection { p := new(ProjectMemberProjection) config.ProjectionName = ProjectMemberProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable( + append(memberColumns, + crdb.NewColumn(ProjectMemberProjectIDCol, crdb.ColumnTypeText), + ), + crdb.NewPrimaryKey(MemberInstanceID, ProjectMemberProjectIDCol, MemberUserIDCol), + crdb.NewIndex("user_idx", []string{MemberUserIDCol}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -79,17 +88,10 @@ func (p *ProjectMemberProjection) reducers() []handler.AggregateReducer { } } -type ProjectMemberColumn string - -const ( - ProjectMemberProjectIDCol = "project_id" -) - func (p *ProjectMemberProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.MemberAddedEvent) if !ok { - logging.LogWithFields("HANDL-3FRys", "seq", event.Sequence(), "expectedType", project.MemberAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-bgx5Q", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-bgx5Q", "reduce.wrong.event.type %s", project.MemberAddedType) } return reduceMemberAdded( *member.NewMemberAddedEvent(&e.BaseEvent, e.UserID, e.Roles...), @@ -100,8 +102,7 @@ func (p *ProjectMemberProjection) reduceAdded(event eventstore.Event) (*handler. func (p *ProjectMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.MemberChangedEvent) if !ok { - logging.LogWithFields("HANDL-9hgMR", "seq", event.Sequence(), "expectedType", project.MemberChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-90WJ1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-90WJ1", "reduce.wrong.event.type %s", project.MemberChangedType) } return reduceMemberChanged( *member.NewMemberChangedEvent(&e.BaseEvent, e.UserID, e.Roles...), @@ -112,8 +113,7 @@ func (p *ProjectMemberProjection) reduceChanged(event eventstore.Event) (*handle func (p *ProjectMemberProjection) reduceCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.MemberCascadeRemovedEvent) if !ok { - logging.LogWithFields("HANDL-2kyYa", "seq", event.Sequence(), "expectedType", project.MemberCascadeRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-aGd43", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-aGd43", "reduce.wrong.event.type %s", project.MemberCascadeRemovedType) } return reduceMemberCascadeRemoved( *member.NewCascadeRemovedEvent(&e.BaseEvent, e.UserID), @@ -124,8 +124,7 @@ func (p *ProjectMemberProjection) reduceCascadeRemoved(event eventstore.Event) ( func (p *ProjectMemberProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.MemberRemovedEvent) if !ok { - logging.LogWithFields("HANDL-X0yvM", "seq", event.Sequence(), "expectedType", project.MemberRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-eJZPh", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-eJZPh", "reduce.wrong.event.type %s", project.MemberRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.UserID), @@ -136,8 +135,7 @@ func (p *ProjectMemberProjection) reduceRemoved(event eventstore.Event) (*handle func (p *ProjectMemberProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-g8eWd", "seq", event.Sequence(), "expected", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-aYA60", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-aYA60", "reduce.wrong.event.type %s", user.UserRemovedType) } return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.Aggregate().ID)) } @@ -149,8 +147,7 @@ func (p *ProjectMemberProjection) reduceOrgRemoved(event eventstore.Event) (*han // if org A is deleted, the membership wouldn't be deleted e, ok := event.(*org.OrgRemovedEvent) if !ok { - logging.LogWithFields("HANDL-q7H8D", "seq", event.Sequence(), "expected", org.OrgRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-NGUEL", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-NGUEL", "reduce.wrong.event.type %s", org.OrgRemovedEventType) } return reduceMemberRemoved(e, withMemberCond(MemberResourceOwner, e.Aggregate().ID)) } @@ -158,8 +155,7 @@ func (p *ProjectMemberProjection) reduceOrgRemoved(event eventstore.Event) (*han func (p *ProjectMemberProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-q7H8D", "seq", event.Sequence(), "expected", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-NGUEL", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-NGUEL", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return reduceMemberRemoved(e, withMemberCond(ProjectMemberProjectIDCol, e.Aggregate().ID)) } diff --git a/internal/query/projection/project_member_test.go b/internal/query/projection/project_member_test.go index 5bd0941667..312c6f17b9 100644 --- a/internal/query/projection/project_member_test.go +++ b/internal/query/projection/project_member_test.go @@ -3,6 +3,8 @@ package projection import ( "testing" + "github.com/lib/pq" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -10,7 +12,6 @@ import ( "github.com/caos/zitadel/internal/repository/org" "github.com/caos/zitadel/internal/repository/project" "github.com/caos/zitadel/internal/repository/user" - "github.com/lib/pq" ) func TestProjectMemberProjection_reduces(t *testing.T) { @@ -44,7 +45,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.project_members (user_id, roles, creation_date, change_date, sequence, resource_owner, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.project_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "user-id", pq.StringArray{"role"}, @@ -52,6 +53,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { anyArg{}, uint64(15), "ro-id", + "instance-id", "agg-id", }, }, @@ -80,7 +82,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5)", + expectedStmt: "UPDATE projections.project_members SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (user_id = $4) AND (project_id = $5)", expectedArgs: []interface{}{ pq.StringArray{"role", "changed"}, anyArg{}, @@ -113,7 +115,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_members WHERE (user_id = $1) AND (project_id = $2)", + expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1) AND (project_id = $2)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -143,7 +145,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_members WHERE (user_id = $1) AND (project_id = $2)", + expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1) AND (project_id = $2)", expectedArgs: []interface{}{ "user-id", "agg-id", @@ -171,7 +173,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_members WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.project_members WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -198,7 +200,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_members WHERE (resource_owner = $1)", + expectedStmt: "DELETE FROM projections.project_members WHERE (resource_owner = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -225,7 +227,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_members WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.project_members WHERE (project_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/project_role.go b/internal/query/projection/project_role.go index 3138625617..b3dfa575dd 100644 --- a/internal/query/projection/project_role.go +++ b/internal/query/projection/project_role.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -11,16 +10,45 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + ProjectRoleProjectionTable = "projections.project_roles" + + ProjectRoleColumnProjectID = "project_id" + ProjectRoleColumnKey = "role_key" + ProjectRoleColumnCreationDate = "creation_date" + ProjectRoleColumnChangeDate = "change_date" + ProjectRoleColumnSequence = "sequence" + ProjectRoleColumnResourceOwner = "resource_owner" + ProjectRoleColumnInstanceID = "instance_id" + ProjectRoleColumnDisplayName = "display_name" + ProjectRoleColumnGroupName = "group_name" + ProjectRoleColumnCreator = "creator_id" //TODO: necessary? +) + type ProjectRoleProjection struct { crdb.StatementHandler } -const ProjectRoleProjectionTable = "zitadel.projections.project_roles" - func NewProjectRoleProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectRoleProjection { p := new(ProjectRoleProjection) config.ProjectionName = ProjectRoleProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(ProjectRoleColumnProjectID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnKey, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectRoleColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(ProjectRoleColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(ProjectRoleColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnDisplayName, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnGroupName, crdb.ColumnTypeText), + crdb.NewColumn(ProjectRoleColumnCreator, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(ProjectRoleColumnInstanceID, ProjectRoleColumnProjectID, ProjectRoleColumnKey), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -51,23 +79,10 @@ func (p *ProjectRoleProjection) reducers() []handler.AggregateReducer { } } -const ( - ProjectRoleColumnProjectID = "project_id" - ProjectRoleColumnKey = "role_key" - ProjectRoleColumnCreationDate = "creation_date" - ProjectRoleColumnChangeDate = "change_date" - ProjectRoleColumnResourceOwner = "resource_owner" - ProjectRoleColumnSequence = "sequence" - ProjectRoleColumnDisplayName = "display_name" - ProjectRoleColumnGroupName = "group_name" - ProjectRoleColumnCreator = "creator_id" -) - func (p *ProjectRoleProjection) reduceProjectRoleAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.RoleAddedEvent) if !ok { - logging.LogWithFields("HANDL-Fmre5", "seq", event.Sequence(), "expectedType", project.RoleAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-g92Fg", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-g92Fg", "reduce.wrong.event.type %s", project.RoleAddedType) } return crdb.NewCreateStatement( e, @@ -77,6 +92,7 @@ func (p *ProjectRoleProjection) reduceProjectRoleAdded(event eventstore.Event) ( handler.NewCol(ProjectRoleColumnCreationDate, e.CreationDate()), handler.NewCol(ProjectRoleColumnChangeDate, e.CreationDate()), handler.NewCol(ProjectRoleColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(ProjectRoleColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(ProjectRoleColumnSequence, e.Sequence()), handler.NewCol(ProjectRoleColumnDisplayName, e.DisplayName), handler.NewCol(ProjectRoleColumnGroupName, e.Group), @@ -88,8 +104,7 @@ func (p *ProjectRoleProjection) reduceProjectRoleAdded(event eventstore.Event) ( func (p *ProjectRoleProjection) reduceProjectRoleChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.RoleChangedEvent) if !ok { - logging.LogWithFields("HANDL-M0fwg", "seq", event.Sequence(), "expectedType", project.GrantChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-sM0f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-sM0f", "reduce.wrong.event.type %s", project.GrantChangedType) } if e.DisplayName == nil && e.Group == nil { return crdb.NewNoOpStatement(e), nil @@ -116,8 +131,7 @@ func (p *ProjectRoleProjection) reduceProjectRoleChanged(event eventstore.Event) func (p *ProjectRoleProjection) reduceProjectRoleRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.RoleRemovedEvent) if !ok { - logging.LogWithFields("HANDL-MlokF", "seq", event.Sequence(), "expectedType", project.GrantRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-L0fJf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-L0fJf", "reduce.wrong.event.type %s", project.GrantRemovedType) } return crdb.NewDeleteStatement( e, @@ -131,8 +145,7 @@ func (p *ProjectRoleProjection) reduceProjectRoleRemoved(event eventstore.Event) func (p *ProjectRoleProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.ProjectRemovedEvent) if !ok { - logging.LogWithFields("HANDL-hm90R", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-l0geG", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-l0geG", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/project_role_test.go b/internal/query/projection/project_role_test.go index 647f4a3fcb..7f11231cb2 100644 --- a/internal/query/projection/project_role_test.go +++ b/internal/query/projection/project_role_test.go @@ -38,7 +38,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_roles WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.project_roles WHERE (project_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -65,7 +65,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.project_roles WHERE (role_key = $1) AND (project_id = $2)", + expectedStmt: "DELETE FROM projections.project_roles WHERE (role_key = $1) AND (project_id = $2)", expectedArgs: []interface{}{ "key", "agg-id", @@ -93,7 +93,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.project_roles SET (change_date, sequence, display_name, group_name) = ($1, $2, $3, $4) WHERE (role_key = $5) AND (project_id = $6)", + expectedStmt: "UPDATE projections.project_roles SET (change_date, sequence, display_name, group_name) = ($1, $2, $3, $4) WHERE (role_key = $5) AND (project_id = $6)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -143,13 +143,14 @@ func TestProjectRoleProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.project_roles (role_key, project_id, creation_date, change_date, resource_owner, sequence, display_name, group_name, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.project_roles (role_key, project_id, creation_date, change_date, resource_owner, instance_id, sequence, display_name, group_name, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "key", "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "Key", "Group", diff --git a/internal/query/projection/project_test.go b/internal/query/projection/project_test.go index 15683c102b..4913706774 100644 --- a/internal/query/projection/project_test.go +++ b/internal/query/projection/project_test.go @@ -39,7 +39,7 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.projects WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.projects WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -66,7 +66,7 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -96,7 +96,7 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.projects SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -126,7 +126,7 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.projects SET (change_date, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", + expectedStmt: "UPDATE projections.projects SET (change_date, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -178,12 +178,13 @@ func TestProjectProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.projects (id, creation_date, change_date, resource_owner, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", + expectedStmt: "INSERT INTO projections.projects (id, creation_date, change_date, resource_owner, instance_id, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state, creator_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "name", true, diff --git a/internal/query/projection/projection.go b/internal/query/projection/projection.go index d87e2a2485..3f9950f882 100644 --- a/internal/query/projection/projection.go +++ b/internal/query/projection/projection.go @@ -3,6 +3,7 @@ package projection import ( "context" "database/sql" + "fmt" "time" "github.com/caos/zitadel/internal/crypto" @@ -34,6 +35,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co BulkLimit: config.BulkLimit, } + now := time.Now() NewOrgProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["orgs"])) NewActionProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["actions"])) NewFlowProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["flows"])) @@ -46,7 +48,6 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co NewLabelPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["label_policy"])) NewProjectGrantProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_grants"])) NewProjectRoleProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_roles"])) - // owner.NewOrgOwnerProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_owners"])) NewOrgDomainProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_domains"])) NewLoginPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["login_policies"])) NewIDPProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idps"])) @@ -75,6 +76,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co NewOIDCSettingsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["oidc_settings"])) NewDebugNotificationProviderProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["debug_notification_provider"])) NewKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), keyEncryptionAlgorithm, keyChan) + fmt.Println(time.Now().Sub(now)) return nil } diff --git a/internal/query/projection/secret_generator.go b/internal/query/projection/secret_generator.go index 934eecad2a..25118d3e8e 100644 --- a/internal/query/projection/secret_generator.go +++ b/internal/query/projection/secret_generator.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -12,18 +11,51 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + SecretGeneratorProjectionTable = "projections.secret_generators" + + SecretGeneratorColumnGeneratorType = "generator_type" + SecretGeneratorColumnAggregateID = "aggregate_id" + SecretGeneratorColumnCreationDate = "creation_date" + SecretGeneratorColumnChangeDate = "change_date" + SecretGeneratorColumnSequence = "sequence" + SecretGeneratorColumnResourceOwner = "resource_owner" + SecretGeneratorColumnInstanceID = "instance_id" + SecretGeneratorColumnLength = "length" + SecretGeneratorColumnExpiry = "expiry" + SecretGeneratorColumnIncludeLowerLetters = "include_lower_letters" + SecretGeneratorColumnIncludeUpperLetters = "include_upper_letters" + SecretGeneratorColumnIncludeDigits = "include_digits" + SecretGeneratorColumnIncludeSymbols = "include_symbols" +) + type SecretGeneratorProjection struct { crdb.StatementHandler } -const ( - SecretGeneratorProjectionTable = "zitadel.projections.secret_generators" -) - func NewSecretGeneratorProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SecretGeneratorProjection { p := new(SecretGeneratorProjection) config.ProjectionName = SecretGeneratorProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(SecretGeneratorColumnGeneratorType, crdb.ColumnTypeText), + crdb.NewColumn(SecretGeneratorColumnAggregateID, crdb.ColumnTypeText), + crdb.NewColumn(SecretGeneratorColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SecretGeneratorColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SecretGeneratorColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(SecretGeneratorColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(SecretGeneratorColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(SecretGeneratorColumnLength, crdb.ColumnTypeInt64), + crdb.NewColumn(SecretGeneratorColumnExpiry, crdb.ColumnTypeInt64), + crdb.NewColumn(SecretGeneratorColumnIncludeLowerLetters, crdb.ColumnTypeBool), + crdb.NewColumn(SecretGeneratorColumnIncludeUpperLetters, crdb.ColumnTypeBool), + crdb.NewColumn(SecretGeneratorColumnIncludeDigits, crdb.ColumnTypeBool), + crdb.NewColumn(SecretGeneratorColumnIncludeSymbols, crdb.ColumnTypeBool), + }, + crdb.NewPrimaryKey(SecretGeneratorColumnInstanceID, SecretGeneratorColumnGeneratorType, SecretGeneratorColumnAggregateID), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -50,26 +82,10 @@ func (p *SecretGeneratorProjection) reducers() []handler.AggregateReducer { } } -const ( - SecretGeneratorColumnGeneratorType = "generator_type" - SecretGeneratorColumnAggregateID = "aggregate_id" - SecretGeneratorColumnCreationDate = "creation_date" - SecretGeneratorColumnChangeDate = "change_date" - SecretGeneratorColumnResourceOwner = "resource_owner" - SecretGeneratorColumnSequence = "sequence" - SecretGeneratorColumnLength = "length" - SecretGeneratorColumnExpiry = "expiry" - SecretGeneratorColumnIncludeLowerLetters = "include_lower_letters" - SecretGeneratorColumnIncludeUpperLetters = "include_upper_letters" - SecretGeneratorColumnIncludeDigits = "include_digits" - SecretGeneratorColumnIncludeSymbols = "include_symbols" -) - func (p *SecretGeneratorProjection) reduceSecretGeneratorAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SecretGeneratorAddedEvent) if !ok { - logging.LogWithFields("HANDL-nf9sl", "seq", event.Sequence(), "expectedType", iam.SecretGeneratorAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-sk99F", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-sk99F", "reduce.wrong.event.type %s", iam.SecretGeneratorAddedEventType) } return crdb.NewCreateStatement( e, @@ -79,6 +95,7 @@ func (p *SecretGeneratorProjection) reduceSecretGeneratorAdded(event eventstore. handler.NewCol(SecretGeneratorColumnCreationDate, e.CreationDate()), handler.NewCol(SecretGeneratorColumnChangeDate, e.CreationDate()), handler.NewCol(SecretGeneratorColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(SecretGeneratorColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(SecretGeneratorColumnSequence, e.Sequence()), handler.NewCol(SecretGeneratorColumnLength, e.Length), handler.NewCol(SecretGeneratorColumnExpiry, e.Expiry), @@ -93,8 +110,7 @@ func (p *SecretGeneratorProjection) reduceSecretGeneratorAdded(event eventstore. func (p *SecretGeneratorProjection) reduceSecretGeneratorChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SecretGeneratorChangedEvent) if !ok { - logging.LogWithFields("HANDL-sn9jd", "seq", event.Sequence(), "expected", iam.SecretGeneratorChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-s00Fs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-s00Fs", "reduce.wrong.event.type %s", iam.SecretGeneratorChangedEventType) } columns := make([]handler.Column, 0, 7) @@ -131,8 +147,7 @@ func (p *SecretGeneratorProjection) reduceSecretGeneratorChanged(event eventstor func (p *SecretGeneratorProjection) reduceSecretGeneratorRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SecretGeneratorRemovedEvent) if !ok { - logging.LogWithFields("HANDL-30oEF", "seq", event.Sequence(), "expectedType", iam.SecretGeneratorRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-fmiIf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fmiIf", "reduce.wrong.event.type %s", iam.SecretGeneratorRemovedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/secret_generator_test.go b/internal/query/projection/secret_generator_test.go index 36c8217d3e..92bbb6cc61 100644 --- a/internal/query/projection/secret_generator_test.go +++ b/internal/query/projection/secret_generator_test.go @@ -40,7 +40,7 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.secret_generators WHERE (aggregate_id = $1) AND (generator_type = $2)", + expectedStmt: "DELETE FROM projections.secret_generators WHERE (aggregate_id = $1) AND (generator_type = $2)", expectedArgs: []interface{}{ "agg-id", domain.SecretGeneratorTypeInitCode, @@ -68,7 +68,7 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.secret_generators SET (change_date, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9) AND (generator_type = $10)", + expectedStmt: "UPDATE projections.secret_generators SET (change_date, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9) AND (generator_type = $10)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -104,13 +104,14 @@ func TestSecretGeneratorProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.secret_generators (aggregate_id, generator_type, creation_date, change_date, resource_owner, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", + expectedStmt: "INSERT INTO projections.secret_generators (aggregate_id, generator_type, creation_date, change_date, resource_owner, instance_id, sequence, length, expiry, include_lower_letters, include_upper_letters, include_digits, include_symbols) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", expectedArgs: []interface{}{ "agg-id", domain.SecretGeneratorTypeInitCode, anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), uint(4), time.Millisecond * 10, diff --git a/internal/query/projection/sms.go b/internal/query/projection/sms.go index ad484dd194..8d19a36435 100644 --- a/internal/query/projection/sms.go +++ b/internal/query/projection/sms.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -12,19 +11,57 @@ import ( "github.com/caos/zitadel/internal/repository/iam" ) +const ( + SMSConfigProjectionTable = "projections.sms_configs" + SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix + + SMSColumnID = "id" + SMSColumnAggregateID = "aggregate_id" + SMSColumnCreationDate = "creation_date" + SMSColumnChangeDate = "change_date" + SMSColumnSequence = "sequence" + SMSColumnState = "state" + SMSColumnResourceOwner = "resource_owner" + SMSColumnInstanceID = "instance_id" + + smsTwilioTableSuffix = "twilio" + SMSTwilioConfigColumnSMSID = "sms_id" + SMSTwilioConfigColumnSID = "sid" + SMSTwilioConfigColumnSenderNumber = "sender_number" + SMSTwilioConfigColumnToken = "token" +) + type SMSConfigProjection struct { crdb.StatementHandler } -const ( - SMSConfigProjectionTable = "zitadel.projections.sms_configs" - SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix -) - func NewSMSConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMSConfigProjection { p := new(SMSConfigProjection) config.ProjectionName = SMSConfigProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(SMSColumnID, crdb.ColumnTypeText), + crdb.NewColumn(SMSColumnAggregateID, crdb.ColumnTypeText), + crdb.NewColumn(SMSColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SMSColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SMSColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(SMSColumnState, crdb.ColumnTypeEnum), + crdb.NewColumn(SMSColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(SMSColumnInstanceID, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(SMSColumnInstanceID, SMSColumnID), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(SMSTwilioConfigColumnSMSID, crdb.ColumnTypeText, crdb.Default(SMSColumnID)), + crdb.NewColumn(SMSTwilioConfigColumnSID, crdb.ColumnTypeText), + crdb.NewColumn(SMSTwilioConfigColumnSenderNumber, crdb.ColumnTypeText), + crdb.NewColumn(SMSTwilioConfigColumnToken, crdb.ColumnTypeJSONB), + }, + crdb.NewPrimaryKey(SMSTwilioConfigColumnSMSID), + smsTwilioTableSuffix, + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -59,27 +96,10 @@ func (p *SMSConfigProjection) reducers() []handler.AggregateReducer { } } -const ( - SMSColumnID = "id" - SMSColumnAggregateID = "aggregate_id" - SMSColumnCreationDate = "creation_date" - SMSColumnChangeDate = "change_date" - SMSColumnResourceOwner = "resource_owner" - SMSColumnState = "state" - SMSColumnSequence = "sequence" - - smsTwilioTableSuffix = "twilio" - SMSTwilioConfigColumnSMSID = "sms_id" - SMSTwilioConfigColumnSID = "sid" - SMSTwilioConfigColumnToken = "token" - SMSTwilioConfigColumnSenderNumber = "sender_number" -) - func (p *SMSConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMSConfigTwilioAddedEvent) if !ok { - logging.LogWithFields("HANDL-9jiWf", "seq", event.Sequence(), "expectedType", iam.SMSConfigTwilioAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-s8efs", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-s8efs", "reduce.wrong.event.type %s", iam.SMSConfigTwilioAddedEventType) } return crdb.NewMultiStatement( @@ -91,6 +111,7 @@ func (p *SMSConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) handler.NewCol(SMSColumnCreationDate, e.CreationDate()), handler.NewCol(SMSColumnChangeDate, e.CreationDate()), handler.NewCol(SMSColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(SMSColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(SMSColumnState, domain.SMSConfigStateInactive), handler.NewCol(SMSColumnSequence, e.Sequence()), }, @@ -110,8 +131,7 @@ func (p *SMSConfigProjection) reduceSMSConfigTwilioAdded(event eventstore.Event) func (p *SMSConfigProjection) reduceSMSConfigTwilioChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMSConfigTwilioChangedEvent) if !ok { - logging.LogWithFields("HANDL-fm9el", "seq", event.Sequence(), "expectedType", iam.SMSConfigTwilioChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-fi99F", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fi99F", "reduce.wrong.event.type %s", iam.SMSConfigTwilioChangedEventType) } columns := make([]handler.Column, 0) if e.SID != nil { @@ -145,8 +165,7 @@ func (p *SMSConfigProjection) reduceSMSConfigTwilioChanged(event eventstore.Even func (p *SMSConfigProjection) reduceSMSConfigActivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMSConfigActivatedEvent) if !ok { - logging.LogWithFields("HANDL-fm03F", "seq", event.Sequence(), "expectedType", iam.SMSConfigActivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-fj9Ef", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fj9Ef", "reduce.wrong.event.type %s", iam.SMSConfigActivatedEventType) } return crdb.NewUpdateStatement( e, @@ -164,8 +183,7 @@ func (p *SMSConfigProjection) reduceSMSConfigActivated(event eventstore.Event) ( func (p *SMSConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMSConfigDeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-9fnHS", "seq", event.Sequence(), "expectedType", iam.SMSConfigDeactivatedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-dj9Js", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-dj9Js", "reduce.wrong.event.type %s", iam.SMSConfigDeactivatedEventType) } return crdb.NewUpdateStatement( e, @@ -183,8 +201,7 @@ func (p *SMSConfigProjection) reduceSMSConfigDeactivated(event eventstore.Event) func (p *SMSConfigProjection) reduceSMSConfigRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMSConfigRemovedEvent) if !ok { - logging.LogWithFields("HANDL-0Opew", "seq", event.Sequence(), "expectedType", iam.SMSConfigRemovedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-s9JJf", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-s9JJf", "reduce.wrong.event.type %s", iam.SMSConfigRemovedEventType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/sms_test.go b/internal/query/projection/sms_test.go index e02080888e..d1ff35e9ca 100644 --- a/internal/query/projection/sms_test.go +++ b/internal/query/projection/sms_test.go @@ -54,19 +54,20 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.sms_configs (id, aggregate_id, creation_date, change_date, resource_owner, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "INSERT INTO projections.sms_configs (id, aggregate_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "id", "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.SMSConfigStateInactive, uint64(15), }, }, { - expectedStmt: "INSERT INTO zitadel.projections.sms_configs_twilio (sms_id, sid, token, sender_number) VALUES ($1, $2, $3, $4)", + expectedStmt: "INSERT INTO projections.sms_configs_twilio (sms_id, sid, token, sender_number) VALUES ($1, $2, $3, $4)", expectedArgs: []interface{}{ "id", "sid", @@ -100,7 +101,7 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.sms_configs_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3)", + expectedStmt: "UPDATE projections.sms_configs_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3)", expectedArgs: []interface{}{ &sid, &senderNumber, @@ -108,7 +109,7 @@ func TestSMSProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.sms_configs SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.sms_configs SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -139,7 +140,7 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.SMSConfigStateActive, anyArg{}, @@ -171,7 +172,7 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ domain.SMSConfigStateInactive, anyArg{}, @@ -203,7 +204,7 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.sms_configs WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.sms_configs WHERE (id = $1)", expectedArgs: []interface{}{ "id", }, diff --git a/internal/query/projection/smtp.go b/internal/query/projection/smtp.go index 69b94bf4dd..e50c50341d 100644 --- a/internal/query/projection/smtp.go +++ b/internal/query/projection/smtp.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -12,18 +11,49 @@ import ( "github.com/caos/zitadel/internal/repository/project" ) +const ( + SMTPConfigProjectionTable = "projections.smtp_configs" + + SMTPConfigColumnAggregateID = "aggregate_id" + SMTPConfigColumnCreationDate = "creation_date" + SMTPConfigColumnChangeDate = "change_date" + SMTPConfigColumnSequence = "sequence" + SMTPConfigColumnResourceOwner = "resource_owner" + SMTPConfigColumnInstanceID = "instance_id" + SMTPConfigColumnTLS = "tls" + SMTPConfigColumnSenderAddress = "sender_address" + SMTPConfigColumnSenderName = "sender_name" + SMTPConfigColumnSMTPHost = "host" + SMTPConfigColumnSMTPUser = "username" + SMTPConfigColumnSMTPPassword = "password" +) + type SMTPConfigProjection struct { crdb.StatementHandler } -const ( - SMTPConfigProjectionTable = "zitadel.projections.smtp_configs" -) - func NewSMTPConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMTPConfigProjection { p := new(SMTPConfigProjection) config.ProjectionName = SMTPConfigProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(SMTPConfigColumnAggregateID, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SMTPConfigColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(SMTPConfigColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(SMTPConfigColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnTLS, crdb.ColumnTypeBool), + crdb.NewColumn(SMTPConfigColumnSenderAddress, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnSenderName, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnSMTPHost, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnSMTPUser, crdb.ColumnTypeText), + crdb.NewColumn(SMTPConfigColumnSMTPPassword, crdb.ColumnTypeJSONB, crdb.Nullable()), + }, + crdb.NewPrimaryKey(SMTPConfigColumnInstanceID, SMTPConfigColumnAggregateID), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -50,25 +80,10 @@ func (p *SMTPConfigProjection) reducers() []handler.AggregateReducer { } } -const ( - SMTPConfigColumnAggregateID = "aggregate_id" - SMTPConfigColumnCreationDate = "creation_date" - SMTPConfigColumnChangeDate = "change_date" - SMTPConfigColumnResourceOwner = "resource_owner" - SMTPConfigColumnSequence = "sequence" - SMTPConfigColumnTLS = "tls" - SMTPConfigColumnFromAddress = "sender_address" - SMTPConfigColumnFromName = "sender_name" - SMTPConfigColumnSMTPHost = "host" - SMTPConfigColumnSMTPUser = "username" - SMTPConfigColumnSMTPPassword = "password" -) - func (p *SMTPConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMTPConfigAddedEvent) if !ok { - logging.LogWithFields("HANDL-wkofs", "seq", event.Sequence(), "expectedType", iam.SMTPConfigAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-sk99F", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-sk99F", "reduce.wrong.event.type %s", iam.SMTPConfigAddedEventType) } return crdb.NewCreateStatement( e, @@ -77,10 +92,11 @@ func (p *SMTPConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*h handler.NewCol(SMTPConfigColumnCreationDate, e.CreationDate()), handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()), handler.NewCol(SMTPConfigColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(SMTPConfigColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(SMTPConfigColumnSequence, e.Sequence()), handler.NewCol(SMTPConfigColumnTLS, e.TLS), - handler.NewCol(SMTPConfigColumnFromAddress, e.SenderAddress), - handler.NewCol(SMTPConfigColumnFromName, e.SenderName), + handler.NewCol(SMTPConfigColumnSenderAddress, e.SenderAddress), + handler.NewCol(SMTPConfigColumnSenderName, e.SenderName), handler.NewCol(SMTPConfigColumnSMTPHost, e.Host), handler.NewCol(SMTPConfigColumnSMTPUser, e.User), handler.NewCol(SMTPConfigColumnSMTPPassword, e.Password), @@ -91,8 +107,7 @@ func (p *SMTPConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*h func (p *SMTPConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMTPConfigChangedEvent) if !ok { - logging.LogWithFields("HANDL-wo00f", "seq", event.Sequence(), "expected", iam.SMTPConfigChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-wl0wd", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-wl0wd", "reduce.wrong.event.type %s", iam.SMTPConfigChangedEventType) } columns := make([]handler.Column, 0, 7) @@ -102,10 +117,10 @@ func (p *SMTPConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) ( columns = append(columns, handler.NewCol(SMTPConfigColumnTLS, *e.TLS)) } if e.FromAddress != nil { - columns = append(columns, handler.NewCol(SMTPConfigColumnFromAddress, *e.FromAddress)) + columns = append(columns, handler.NewCol(SMTPConfigColumnSenderAddress, *e.FromAddress)) } if e.FromName != nil { - columns = append(columns, handler.NewCol(SMTPConfigColumnFromName, *e.FromName)) + columns = append(columns, handler.NewCol(SMTPConfigColumnSenderName, *e.FromName)) } if e.Host != nil { columns = append(columns, handler.NewCol(SMTPConfigColumnSMTPHost, *e.Host)) @@ -125,8 +140,7 @@ func (p *SMTPConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) ( func (p *SMTPConfigProjection) reduceSMTPConfigPasswordChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*iam.SMTPConfigPasswordChangedEvent) if !ok { - logging.LogWithFields("HANDL-f92sf", "seq", event.Sequence(), "expected", iam.SMTPConfigChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-fk02f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-fk02f", "reduce.wrong.event.type %s", iam.SMTPConfigChangedEventType) } return crdb.NewUpdateStatement( diff --git a/internal/query/projection/smtp_test.go b/internal/query/projection/smtp_test.go index 5c6343fa36..bcd838264e 100644 --- a/internal/query/projection/smtp_test.go +++ b/internal/query/projection/smtp_test.go @@ -45,7 +45,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.smtp_configs SET (change_date, sequence, tls, sender_address, sender_name, host, username) = ($1, $2, $3, $4, $5, $6, $7) WHERE (aggregate_id = $8)", + expectedStmt: "UPDATE projections.smtp_configs SET (change_date, sequence, tls, sender_address, sender_name, host, username) = ($1, $2, $3, $4, $5, $6, $7) WHERE (aggregate_id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -90,12 +90,13 @@ func TestSMTPConfigProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.smtp_configs (aggregate_id, creation_date, change_date, resource_owner, sequence, tls, sender_address, sender_name, host, username, password) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", + expectedStmt: "INSERT INTO projections.smtp_configs (aggregate_id, creation_date, change_date, resource_owner, instance_id, sequence, tls, sender_address, sender_name, host, username, password) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), true, "sender", @@ -133,7 +134,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.smtp_configs SET (change_date, sequence, password) = ($1, $2, $3) WHERE (aggregate_id = $4)", + expectedStmt: "UPDATE projections.smtp_configs SET (change_date, sequence, password) = ($1, $2, $3) WHERE (aggregate_id = $4)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/user.go b/internal/query/projection/user.go index ab31ba4a1d..342810603d 100644 --- a/internal/query/projection/user.go +++ b/internal/query/projection/user.go @@ -4,8 +4,6 @@ import ( "context" "database/sql" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -19,31 +17,20 @@ type UserProjection struct { } const ( - UserTable = "zitadel.projections.users" + UserTable = "projections.users" UserHumanTable = UserTable + "_" + UserHumanSuffix UserMachineTable = UserTable + "_" + UserMachineSuffix -) -func NewUserProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserProjection { - p := new(UserProjection) - config.ProjectionName = UserTable - config.Reducers = p.reducers() - p.StatementHandler = crdb.NewStatementHandler(ctx, config) - return p -} - -const ( UserIDCol = "id" UserCreationDateCol = "creation_date" UserChangeDateCol = "change_date" - UserResourceOwnerCol = "resource_owner" - UserStateCol = "state" UserSequenceCol = "sequence" + UserStateCol = "state" + UserResourceOwnerCol = "resource_owner" + UserInstanceIDCol = "instance_id" UserUsernameCol = "username" UserTypeCol = "type" -) -const ( UserHumanSuffix = "humans" HumanUserIDCol = "user_id" @@ -63,16 +50,64 @@ const ( // phone HumanPhoneCol = "phone" HumanIsPhoneVerifiedCol = "is_phone_verified" -) - -const ( - UserMachineSuffix = "machines" - MachineUserIDCol = "user_id" + // machine + UserMachineSuffix = "machines" + MachineUserIDCol = "user_id" MachineNameCol = "name" MachineDescriptionCol = "description" ) +func NewUserProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserProjection { + p := new(UserProjection) + config.ProjectionName = UserTable + config.Reducers = p.reducers() + config.InitCheck = crdb.NewMultiTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(UserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(UserCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(UserStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(UserResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(UserInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(UserUsernameCol, crdb.ColumnTypeText), + crdb.NewColumn(UserTypeCol, crdb.ColumnTypeEnum), + }, + crdb.NewPrimaryKey(UserInstanceIDCol, UserIDCol), + crdb.NewIndex("username_idx", []string{UserUsernameCol}), + crdb.NewIndex("ro_idx", []string{UserResourceOwnerCol}), + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(HumanUserIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(UserIDCol)), + crdb.NewColumn(HumanFirstNameCol, crdb.ColumnTypeText), + crdb.NewColumn(HumanLastNameCol, crdb.ColumnTypeText), + crdb.NewColumn(HumanNickNameCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(HumanDisplayNameCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(HumanPreferredLanguageCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(HumanGenderCol, crdb.ColumnTypeEnum), + crdb.NewColumn(HumanAvatarURLCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(HumanEmailCol, crdb.ColumnTypeText), + crdb.NewColumn(HumanIsEmailVerifiedCol, crdb.ColumnTypeBool, crdb.Default(false)), + crdb.NewColumn(HumanPhoneCol, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(HumanIsPhoneVerifiedCol, crdb.ColumnTypeBool, crdb.Nullable()), + }, + crdb.NewPrimaryKey(HumanUserIDCol), + UserHumanSuffix, + ), + crdb.NewSuffixedTable([]*crdb.Column{ + crdb.NewColumn(MachineUserIDCol, crdb.ColumnTypeText, crdb.DeleteCascade(UserIDCol)), + crdb.NewColumn(MachineNameCol, crdb.ColumnTypeText), + crdb.NewColumn(MachineDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()), + }, + crdb.NewPrimaryKey(MachineUserIDCol), + UserMachineSuffix, + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) + return p +} + func (p *UserProjection) reducers() []handler.AggregateReducer { return []handler.AggregateReducer{ { @@ -206,8 +241,7 @@ func (p *UserProjection) reducers() []handler.AggregateReducer { func (p *UserProjection) reduceHumanAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanAddedEvent) if !ok { - logging.LogWithFields("HANDL-Cw9BX", "seq", event.Sequence(), "expectedType", user.HumanAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Ebynp", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Ebynp", "reduce.wrong.event.type %s", user.HumanAddedType) } return crdb.NewMultiStatement( e, @@ -217,6 +251,7 @@ func (p *UserProjection) reduceHumanAdded(event eventstore.Event) (*handler.Stat handler.NewCol(UserCreationDateCol, e.CreationDate()), handler.NewCol(UserChangeDateCol, e.CreationDate()), handler.NewCol(UserResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(UserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(UserStateCol, domain.UserStateActive), handler.NewCol(UserSequenceCol, e.Sequence()), handler.NewCol(UserUsernameCol, e.UserName), @@ -243,8 +278,7 @@ func (p *UserProjection) reduceHumanAdded(event eventstore.Event) (*handler.Stat func (p *UserProjection) reduceHumanRegistered(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanRegisteredEvent) if !ok { - logging.LogWithFields("HANDL-qoZyC", "seq", event.Sequence(), "expectedType", user.HumanRegisteredType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-xE53M", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-xE53M", "reduce.wrong.event.type %s", user.HumanRegisteredType) } return crdb.NewMultiStatement( e, @@ -254,6 +288,7 @@ func (p *UserProjection) reduceHumanRegistered(event eventstore.Event) (*handler handler.NewCol(UserCreationDateCol, e.CreationDate()), handler.NewCol(UserChangeDateCol, e.CreationDate()), handler.NewCol(UserResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(UserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(UserStateCol, domain.UserStateActive), handler.NewCol(UserSequenceCol, e.Sequence()), handler.NewCol(UserUsernameCol, e.UserName), @@ -280,8 +315,7 @@ func (p *UserProjection) reduceHumanRegistered(event eventstore.Event) (*handler func (p *UserProjection) reduceHumanInitCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanInitialCodeAddedEvent) if !ok { - logging.LogWithFields("HANDL-DSfe2", "seq", event.Sequence(), "expectedType", user.HumanInitialCodeAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dvgws", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dvgws", "reduce.wrong.event.type %s", user.HumanInitialCodeAddedType) } return crdb.NewUpdateStatement( e, @@ -297,8 +331,7 @@ func (p *UserProjection) reduceHumanInitCodeAdded(event eventstore.Event) (*hand func (p *UserProjection) reduceHumanInitCodeSucceeded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanInitializedCheckSucceededEvent) if !ok { - logging.LogWithFields("HANDL-Dgff2", "seq", event.Sequence(), "expectedType", user.HumanInitializedCheckSucceededType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dfvwq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dfvwq", "reduce.wrong.event.type %s", user.HumanInitializedCheckSucceededType) } return crdb.NewUpdateStatement( e, @@ -314,8 +347,7 @@ func (p *UserProjection) reduceHumanInitCodeSucceeded(event eventstore.Event) (* func (p *UserProjection) reduceUserLocked(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserLockedEvent) if !ok { - logging.LogWithFields("HANDL-c6irw", "seq", event.Sequence(), "expectedType", user.UserLockedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-exyBF", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-exyBF", "reduce.wrong.event.type %s", user.UserLockedType) } return crdb.NewUpdateStatement( @@ -334,8 +366,7 @@ func (p *UserProjection) reduceUserLocked(event eventstore.Event) (*handler.Stat func (p *UserProjection) reduceUserUnlocked(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserUnlockedEvent) if !ok { - logging.LogWithFields("HANDL-eyHv5", "seq", event.Sequence(), "expectedType", user.UserUnlockedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-JIyRl", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-JIyRl", "reduce.wrong.event.type %s", user.UserUnlockedType) } return crdb.NewUpdateStatement( @@ -354,8 +385,7 @@ func (p *UserProjection) reduceUserUnlocked(event eventstore.Event) (*handler.St func (p *UserProjection) reduceUserDeactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserDeactivatedEvent) if !ok { - logging.LogWithFields("HANDL-EqbaJ", "seq", event.Sequence(), "expectedType", user.UserDeactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-6BNjj", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-6BNjj", "reduce.wrong.event.type %s", user.UserDeactivatedType) } return crdb.NewUpdateStatement( @@ -374,8 +404,7 @@ func (p *UserProjection) reduceUserDeactivated(event eventstore.Event) (*handler func (p *UserProjection) reduceUserReactivated(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserReactivatedEvent) if !ok { - logging.LogWithFields("HANDL-kAaBr", "seq", event.Sequence(), "expectedType", user.UserReactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-IoF6j", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-IoF6j", "reduce.wrong.event.type %s", user.UserReactivatedType) } return crdb.NewUpdateStatement( @@ -394,8 +423,7 @@ func (p *UserProjection) reduceUserReactivated(event eventstore.Event) (*handler func (p *UserProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-n2JMe", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-BQB2t", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-BQB2t", "reduce.wrong.event.type %s", user.UserRemovedType) } return crdb.NewDeleteStatement( @@ -409,8 +437,7 @@ func (p *UserProjection) reduceUserRemoved(event eventstore.Event) (*handler.Sta func (p *UserProjection) reduceUserNameChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UsernameChangedEvent) if !ok { - logging.LogWithFields("HANDL-7J5xL", "seq", event.Sequence(), "expectedType", user.UserUserNameChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-QNKyV", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-QNKyV", "reduce.wrong.event.type %s", user.UserUserNameChangedType) } return crdb.NewUpdateStatement( @@ -429,8 +456,7 @@ func (p *UserProjection) reduceUserNameChanged(event eventstore.Event) (*handler func (p *UserProjection) reduceHumanProfileChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanProfileChangedEvent) if !ok { - logging.LogWithFields("HANDL-Dwfyn", "seq", event.Sequence(), "expectedType", user.HumanProfileChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-769v4", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-769v4", "reduce.wrong.event.type %s", user.HumanProfileChangedType) } cols := make([]handler.Column, 0, 6) if e.FirstName != "" { @@ -481,8 +507,7 @@ func (p *UserProjection) reduceHumanProfileChanged(event eventstore.Event) (*han func (p *UserProjection) reduceHumanPhoneChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanPhoneChangedEvent) if !ok { - logging.LogWithFields("HANDL-pnRqf", "seq", event.Sequence(), "expectedType", user.HumanPhoneChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-xOGIA", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-xOGIA", "reduce.wrong.event.type %s", user.HumanPhoneChangedType) } return crdb.NewMultiStatement( @@ -512,8 +537,7 @@ func (p *UserProjection) reduceHumanPhoneChanged(event eventstore.Event) (*handl func (p *UserProjection) reduceHumanPhoneRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanPhoneRemovedEvent) if !ok { - logging.LogWithFields("HANDL-eMpOG", "seq", event.Sequence(), "expectedType", user.HumanPhoneRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-JI4S1", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-JI4S1", "reduce.wrong.event.type %s", user.HumanPhoneRemovedType) } return crdb.NewMultiStatement( @@ -543,8 +567,7 @@ func (p *UserProjection) reduceHumanPhoneRemoved(event eventstore.Event) (*handl func (p *UserProjection) reduceHumanPhoneVerified(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanPhoneVerifiedEvent) if !ok { - logging.LogWithFields("HANDL-GhFOY", "seq", event.Sequence(), "expectedType", user.HumanPhoneVerifiedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-LBnqG", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-LBnqG", "reduce.wrong.event.type %s", user.HumanPhoneVerifiedType) } return crdb.NewMultiStatement( @@ -573,8 +596,7 @@ func (p *UserProjection) reduceHumanPhoneVerified(event eventstore.Event) (*hand func (p *UserProjection) reduceHumanEmailChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanEmailChangedEvent) if !ok { - logging.LogWithFields("HANDL-MDfHX", "seq", event.Sequence(), "expectedType", user.HumanEmailChangedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-KwiHa", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-KwiHa", "reduce.wrong.event.type %s", user.HumanEmailChangedType) } return crdb.NewMultiStatement( @@ -604,8 +626,7 @@ func (p *UserProjection) reduceHumanEmailChanged(event eventstore.Event) (*handl func (p *UserProjection) reduceHumanEmailVerified(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanEmailVerifiedEvent) if !ok { - logging.LogWithFields("HANDL-FdN0b", "seq", event.Sequence(), "expectedType", user.HumanEmailVerifiedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-JzcDq", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-JzcDq", "reduce.wrong.event.type %s", user.HumanEmailVerifiedType) } return crdb.NewMultiStatement( @@ -634,8 +655,7 @@ func (p *UserProjection) reduceHumanEmailVerified(event eventstore.Event) (*hand func (p *UserProjection) reduceHumanAvatarAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanAvatarAddedEvent) if !ok { - logging.LogWithFields("HANDL-naQue", "seq", event.Sequence(), "expectedType", user.HumanAvatarAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-eDEdt", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-eDEdt", "reduce.wrong.event.type %s", user.HumanAvatarAddedType) } return crdb.NewMultiStatement( @@ -664,8 +684,7 @@ func (p *UserProjection) reduceHumanAvatarAdded(event eventstore.Event) (*handle func (p *UserProjection) reduceHumanAvatarRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.HumanAvatarRemovedEvent) if !ok { - logging.LogWithFields("HANDL-c6zoV", "seq", event.Sequence(), "expectedType", user.HumanAvatarRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-KhETX", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-KhETX", "reduce.wrong.event.type %s", user.HumanAvatarRemovedType) } return crdb.NewMultiStatement( @@ -694,8 +713,7 @@ func (p *UserProjection) reduceHumanAvatarRemoved(event eventstore.Event) (*hand func (p *UserProjection) reduceMachineAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.MachineAddedEvent) if !ok { - logging.LogWithFields("HANDL-8xr78", "seq", event.Sequence(), "expectedType", user.MachineAddedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-q7ier", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-q7ier", "reduce.wrong.event.type %s", user.MachineAddedEventType) } return crdb.NewMultiStatement( @@ -706,6 +724,7 @@ func (p *UserProjection) reduceMachineAdded(event eventstore.Event) (*handler.St handler.NewCol(UserCreationDateCol, e.CreationDate()), handler.NewCol(UserChangeDateCol, e.CreationDate()), handler.NewCol(UserResourceOwnerCol, e.Aggregate().ResourceOwner), + handler.NewCol(UserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(UserStateCol, domain.UserStateActive), handler.NewCol(UserSequenceCol, e.Sequence()), handler.NewCol(UserUsernameCol, e.UserName), @@ -726,8 +745,7 @@ func (p *UserProjection) reduceMachineAdded(event eventstore.Event) (*handler.St func (p *UserProjection) reduceMachineChanged(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.MachineChangedEvent) if !ok { - logging.LogWithFields("HANDL-uUFCy", "seq", event.Sequence(), "expectedType", user.MachineChangedEventType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-qYHvj", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-qYHvj", "reduce.wrong.event.type %s", user.MachineChangedEventType) } cols := make([]handler.Column, 0, 2) diff --git a/internal/query/projection/user_auth_method.go b/internal/query/projection/user_auth_method.go index c99cb60b2b..95765a177f 100644 --- a/internal/query/projection/user_auth_method.go +++ b/internal/query/projection/user_auth_method.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" @@ -12,34 +11,50 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + UserAuthMethodTable = "projections.user_auth_methods" + + UserAuthMethodUserIDCol = "user_id" + UserAuthMethodTypeCol = "method_type" + UserAuthMethodTokenIDCol = "token_id" + UserAuthMethodCreationDateCol = "creation_date" + UserAuthMethodChangeDateCol = "change_date" + UserAuthMethodSequenceCol = "sequence" + UserAuthMethodResourceOwnerCol = "resource_owner" + UserAuthMethodInstanceIDCol = "instance_id" + UserAuthMethodStateCol = "state" + UserAuthMethodNameCol = "name" +) + type UserAuthMethodProjection struct { crdb.StatementHandler } -const ( - UserAuthMethodTable = "zitadel.projections.user_auth_methods" -) - func NewUserAuthMethodProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserAuthMethodProjection { p := new(UserAuthMethodProjection) config.ProjectionName = UserAuthMethodTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(UserAuthMethodUserIDCol, crdb.ColumnTypeText), + crdb.NewColumn(UserAuthMethodTypeCol, crdb.ColumnTypeText), + crdb.NewColumn(UserAuthMethodTokenIDCol, crdb.ColumnTypeText), + crdb.NewColumn(UserAuthMethodCreationDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserAuthMethodChangeDateCol, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserAuthMethodSequenceCol, crdb.ColumnTypeInt64), + crdb.NewColumn(UserAuthMethodStateCol, crdb.ColumnTypeEnum), + crdb.NewColumn(UserAuthMethodResourceOwnerCol, crdb.ColumnTypeText), + crdb.NewColumn(UserAuthMethodInstanceIDCol, crdb.ColumnTypeText), + crdb.NewColumn(UserAuthMethodNameCol, crdb.ColumnTypeText), + }, + crdb.NewPrimaryKey(UserAuthMethodInstanceIDCol, UserAuthMethodUserIDCol, UserAuthMethodTypeCol, UserAuthMethodTokenIDCol), + crdb.NewIndex("ro_idx", []string{UserAuthMethodResourceOwnerCol}), + ), + ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } -const ( - UserAuthMethodTokenIDCol = "token_id" - UserAuthMethodCreationDateCol = "creation_date" - UserAuthMethodChangeDateCol = "change_date" - UserAuthMethodResourceOwnerCol = "resource_owner" - UserAuthMethodUserIDCol = "user_id" - UserAuthMethodSequenceCol = "sequence" - UserAuthMethodNameCol = "name" - UserAuthMethodStateCol = "state" - UserAuthMethodTypeCol = "method_type" -) - func (p *UserAuthMethodProjection) reducers() []handler.AggregateReducer { return []handler.AggregateReducer{ { @@ -99,8 +114,7 @@ func (p *UserAuthMethodProjection) reduceInitAuthMethod(event eventstore.Event) case *user.HumanOTPAddedEvent: methodType = domain.UserAuthMethodTypeOTP default: - logging.LogWithFields("PROJE-9j3f", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-f92f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-f92f", "reduce.wrong.event.type %v", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}) } return crdb.NewUpsertStatement( @@ -110,6 +124,7 @@ func (p *UserAuthMethodProjection) reduceInitAuthMethod(event eventstore.Event) handler.NewCol(UserAuthMethodCreationDateCol, event.CreationDate()), handler.NewCol(UserAuthMethodChangeDateCol, event.CreationDate()), handler.NewCol(UserAuthMethodResourceOwnerCol, event.Aggregate().ResourceOwner), + handler.NewCol(UserAuthMethodInstanceIDCol, event.Aggregate().InstanceID), handler.NewCol(UserAuthMethodUserIDCol, event.Aggregate().ID), handler.NewCol(UserAuthMethodSequenceCol, event.Sequence()), handler.NewCol(UserAuthMethodStateCol, domain.MFAStateNotReady), @@ -137,8 +152,7 @@ func (p *UserAuthMethodProjection) reduceActivateEvent(event eventstore.Event) ( methodType = domain.UserAuthMethodTypeOTP default: - logging.LogWithFields("PROJE-9j3f", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-f92f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-f92f", "reduce.wrong.event.type %v", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}) } return crdb.NewUpdateStatement( @@ -172,8 +186,7 @@ func (p *UserAuthMethodProjection) reduceRemoveAuthMethod(event eventstore.Event methodType = domain.UserAuthMethodTypeOTP default: - logging.LogWithFields("PROJE-9j3f", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-f92f", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-f92f", "reduce.wrong.event.type %v", []eventstore.EventType{user.HumanPasswordlessTokenAddedType, user.HumanU2FTokenAddedType}) } conditions := []handler.Condition{ handler.NewCond(UserAuthMethodUserIDCol, event.Aggregate().ID), diff --git a/internal/query/projection/user_auth_method_test.go b/internal/query/projection/user_auth_method_test.go index f4c96c1382..5532c4376e 100644 --- a/internal/query/projection/user_auth_method_test.go +++ b/internal/query/projection/user_auth_method_test.go @@ -41,12 +41,13 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "UPSERT INTO projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, instance_id, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "token-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", "agg-id", uint64(15), domain.MFAStateNotReady, @@ -78,12 +79,13 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "UPSERT INTO projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, instance_id, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "token-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", "agg-id", uint64(15), domain.MFAStateNotReady, @@ -114,12 +116,13 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "UPSERT INTO projections.user_auth_methods (token_id, creation_date, change_date, resource_owner, instance_id, user_id, sequence, state, method_type, name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ "", anyArg{}, anyArg{}, "ro-id", + "instance-id", "agg-id", uint64(15), domain.MFAStateNotReady, @@ -152,7 +155,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", + expectedStmt: "UPDATE projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -189,7 +192,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", + expectedStmt: "UPDATE projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -224,7 +227,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", + expectedStmt: "UPDATE projections.user_auth_methods SET (change_date, sequence, name, state) = ($1, $2, $3, $4) WHERE (user_id = $5) AND (method_type = $6) AND (resource_owner = $7) AND (token_id = $8)", expectedArgs: []interface{}{ anyArg{}, uint64(15), diff --git a/internal/query/projection/user_grant.go b/internal/query/projection/user_grant.go index 28ad9a0184..3feee4ca2a 100644 --- a/internal/query/projection/user_grant.go +++ b/internal/query/projection/user_grant.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/lib/pq" "github.com/caos/zitadel/internal/domain" @@ -16,18 +15,50 @@ import ( "github.com/caos/zitadel/internal/repository/usergrant" ) +const ( + UserGrantProjectionTable = "projections.user_grants" + + UserGrantID = "id" + UserGrantCreationDate = "creation_date" + UserGrantChangeDate = "change_date" + UserGrantSequence = "sequence" + UserGrantState = "state" + UserGrantResourceOwner = "resource_owner" + UserGrantInstanceID = "instance_id" + UserGrantUserID = "user_id" + UserGrantProjectID = "project_id" + UserGrantGrantID = "grant_id" + UserGrantRoles = "roles" +) + type UserGrantProjection struct { crdb.StatementHandler } -const ( - UserGrantProjectionTable = "zitadel.projections.user_grants" -) - func NewUserGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserGrantProjection { p := new(UserGrantProjection) config.ProjectionName = UserGrantProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(UserGrantID, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserGrantChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserGrantSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(UserGrantState, crdb.ColumnTypeEnum), + crdb.NewColumn(UserGrantResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantUserID, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantProjectID, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantGrantID, crdb.ColumnTypeText), + crdb.NewColumn(UserGrantRoles, crdb.ColumnTypeTextArray, crdb.Nullable()), + }, + crdb.NewPrimaryKey(UserGrantInstanceID, UserGrantID), + crdb.NewIndex("user_idx", []string{UserGrantUserID}), + crdb.NewIndex("ro_idx", []string{UserGrantResourceOwner}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -104,32 +135,17 @@ func (p *UserGrantProjection) reducers() []handler.AggregateReducer { } } -type UserGrantColumn string - -const ( - UserGrantID = "id" - UserGrantResourceOwner = "resource_owner" - UserGrantCreationDate = "creation_date" - UserGrantChangeDate = "change_date" - UserGrantSequence = "sequence" - UserGrantUserID = "user_id" - UserGrantProjectID = "project_id" - UserGrantGrantID = "grant_id" - UserGrantRoles = "roles" - UserGrantState = "state" -) - func (p *UserGrantProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*usergrant.UserGrantAddedEvent) if !ok { - logging.LogWithFields("PROJE-WYOHD", "seq", event.Sequence(), "expectedType", usergrant.UserGrantAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-MQHVB", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-MQHVB", "reduce.wrong.event.type %s", usergrant.UserGrantAddedType) } return crdb.NewCreateStatement( e, []handler.Column{ handler.NewCol(UserGrantID, e.Aggregate().ID), handler.NewCol(UserGrantResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(UserGrantInstanceID, e.Aggregate().InstanceID), handler.NewCol(UserGrantCreationDate, e.CreationDate()), handler.NewCol(UserGrantChangeDate, e.CreationDate()), handler.NewCol(UserGrantSequence, e.Sequence()), @@ -151,8 +167,7 @@ func (p *UserGrantProjection) reduceChanged(event eventstore.Event) (*handler.St case *usergrant.UserGrantCascadeChangedEvent: roles = e.RoleKeys default: - logging.LogWithFields("PROJE-dIflx", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{usergrant.UserGrantChangedType, usergrant.UserGrantCascadeChangedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-hOr1E", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-hOr1E", "reduce.wrong.event.type %v", []eventstore.EventType{usergrant.UserGrantChangedType, usergrant.UserGrantCascadeChangedType}) } return crdb.NewUpdateStatement( @@ -173,8 +188,7 @@ func (p *UserGrantProjection) reduceRemoved(event eventstore.Event) (*handler.St case *usergrant.UserGrantRemovedEvent, *usergrant.UserGrantCascadeRemovedEvent: // ok default: - logging.LogWithFields("PROJE-Nw0cR", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{usergrant.UserGrantRemovedType, usergrant.UserGrantCascadeRemovedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-7OBEC", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-7OBEC", "reduce.wrong.event.type %v", []eventstore.EventType{usergrant.UserGrantRemovedType, usergrant.UserGrantCascadeRemovedType}) } return crdb.NewDeleteStatement( @@ -187,8 +201,7 @@ func (p *UserGrantProjection) reduceRemoved(event eventstore.Event) (*handler.St func (p *UserGrantProjection) reduceDeactivated(event eventstore.Event) (*handler.Statement, error) { if _, ok := event.(*usergrant.UserGrantDeactivatedEvent); !ok { - logging.LogWithFields("PROJE-V3txf", "seq", event.Sequence(), "expectedType", usergrant.UserGrantDeactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-oP7Gm", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-oP7Gm", "reduce.wrong.event.type %s", usergrant.UserGrantDeactivatedType) } return crdb.NewUpdateStatement( @@ -206,8 +219,7 @@ func (p *UserGrantProjection) reduceDeactivated(event eventstore.Event) (*handle func (p *UserGrantProjection) reduceReactivated(event eventstore.Event) (*handler.Statement, error) { if _, ok := event.(*usergrant.UserGrantDeactivatedEvent); !ok { - logging.LogWithFields("PROJE-ly6oe", "seq", event.Sequence(), "expectedType", usergrant.UserGrantReactivatedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-DGsKh", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-DGsKh", "reduce.wrong.event.type %s", usergrant.UserGrantReactivatedType) } return crdb.NewUpdateStatement( @@ -225,8 +237,7 @@ func (p *UserGrantProjection) reduceReactivated(event eventstore.Event) (*handle func (p *UserGrantProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { if _, ok := event.(*user.UserRemovedEvent); !ok { - logging.LogWithFields("PROJE-Vfeg3", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Bner2a", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Bner2a", "reduce.wrong.event.type %s", user.UserRemovedType) } return crdb.NewDeleteStatement( @@ -239,8 +250,7 @@ func (p *UserGrantProjection) reduceUserRemoved(event eventstore.Event) (*handle func (p *UserGrantProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) { if _, ok := event.(*project.ProjectRemovedEvent); !ok { - logging.LogWithFields("PROJE-Vfeg3", "seq", event.Sequence(), "expectedType", project.ProjectRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Bne2a", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Bne2a", "reduce.wrong.event.type %s", project.ProjectRemovedType) } return crdb.NewDeleteStatement( @@ -254,8 +264,7 @@ func (p *UserGrantProjection) reduceProjectRemoved(event eventstore.Event) (*han func (p *UserGrantProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.GrantRemovedEvent) if !ok { - logging.LogWithFields("PROJE-DGfe2", "seq", event.Sequence(), "expectedType", project.GrantRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-dGr2a", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dGr2a", "reduce.wrong.event.type %s", project.GrantRemovedType) } return crdb.NewDeleteStatement( @@ -269,8 +278,7 @@ func (p *UserGrantProjection) reduceProjectGrantRemoved(event eventstore.Event) func (p *UserGrantProjection) reduceRoleRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*project.RoleRemovedEvent) if !ok { - logging.LogWithFields("PROJE-Edg22", "seq", event.Sequence(), "expectedType", project.RoleRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-dswg2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dswg2", "reduce.wrong.event.type %s", project.RoleRemovedType) } return crdb.NewUpdateStatement( @@ -295,8 +303,7 @@ func (p *UserGrantProjection) reduceProjectGrantChanged(event eventstore.Event) grantID = e.GrantID keys = e.RoleKeys default: - logging.LogWithFields("PROJE-FGgw2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{project.GrantChangedType, project.GrantCascadeChangedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "PROJE-Fh3gw", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Fh3gw", "reduce.wrong.event.type %v", []eventstore.EventType{project.GrantChangedType, project.GrantCascadeChangedType}) } return crdb.NewUpdateStatement( diff --git a/internal/query/projection/user_grant_test.go b/internal/query/projection/user_grant_test.go index 1b93e376ca..ca97407f42 100644 --- a/internal/query/projection/user_grant_test.go +++ b/internal/query/projection/user_grant_test.go @@ -47,10 +47,11 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.user_grants (id, resource_owner, creation_date, change_date, sequence, user_id, project_id, grant_id, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", + expectedStmt: "INSERT INTO projections.user_grants (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, project_id, grant_id, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", expectedArgs: []interface{}{ "agg-id", "ro-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -85,7 +86,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.user_grants SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, pq.StringArray{"role"}, @@ -117,7 +118,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.user_grants SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, pq.StringArray{"role"}, @@ -147,7 +148,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_grants WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.user_grants WHERE (id = $1)", expectedArgs: []interface{}{ anyArg{}, }, @@ -174,7 +175,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_grants WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.user_grants WHERE (id = $1)", expectedArgs: []interface{}{ anyArg{}, }, @@ -201,7 +202,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.user_grants SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserGrantStateInactive, @@ -231,7 +232,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.user_grants SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserGrantStateActive, @@ -261,7 +262,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_grants WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.user_grants WHERE (user_id = $1)", expectedArgs: []interface{}{ anyArg{}, }, @@ -288,7 +289,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_grants WHERE (project_id = $1)", + expectedStmt: "DELETE FROM projections.user_grants WHERE (project_id = $1)", expectedArgs: []interface{}{ anyArg{}, }, @@ -315,7 +316,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_grants WHERE (grant_id = $1)", + expectedStmt: "DELETE FROM projections.user_grants WHERE (grant_id = $1)", expectedArgs: []interface{}{ "grantID", }, @@ -342,7 +343,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (roles) = (array_remove(roles, $1)) WHERE (project_id = $2)", + expectedStmt: "UPDATE projections.user_grants SET (roles) = (array_remove(roles, $1)) WHERE (project_id = $2)", expectedArgs: []interface{}{ "key", "agg-id", @@ -370,7 +371,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.user_grants SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::STRING[]))) WHERE (grant_id = $2)", + expectedStmt: "UPDATE projections.user_grants SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::STRING[]))) WHERE (grant_id = $2)", expectedArgs: []interface{}{ pq.StringArray{"key"}, "grantID", diff --git a/internal/query/projection/user_metadata.go b/internal/query/projection/user_metadata.go index c94e50f195..42a991663d 100644 --- a/internal/query/projection/user_metadata.go +++ b/internal/query/projection/user_metadata.go @@ -3,8 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/handler" @@ -12,16 +10,43 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + UserMetadataProjectionTable = "projections.user_metadata" + + UserMetadataColumnUserID = "user_id" + UserMetadataColumnCreationDate = "creation_date" + UserMetadataColumnChangeDate = "change_date" + UserMetadataColumnSequence = "sequence" + UserMetadataColumnResourceOwner = "resource_owner" + UserMetadataColumnInstanceID = "instance_id" + UserMetadataColumnKey = "key" + UserMetadataColumnValue = "value" +) + type UserMetadataProjection struct { crdb.StatementHandler } -const UserMetadataProjectionTable = "zitadel.projections.user_metadata" - func NewUserMetadataProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserMetadataProjection { p := new(UserMetadataProjection) config.ProjectionName = UserMetadataProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(UserMetadataColumnUserID, crdb.ColumnTypeText), + crdb.NewColumn(UserMetadataColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserMetadataColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(UserMetadataColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(UserMetadataColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(UserMetadataColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(UserMetadataColumnKey, crdb.ColumnTypeText), + crdb.NewColumn(UserMetadataColumnValue, crdb.ColumnTypeBytes, crdb.Nullable()), + }, + crdb.NewPrimaryKey(UserMetadataColumnInstanceID, UserMetadataColumnUserID), + crdb.NewIndex("ro_idx", []string{UserGrantResourceOwner}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -52,27 +77,17 @@ func (p *UserMetadataProjection) reducers() []handler.AggregateReducer { } } -const ( - UserMetadataColumnUserID = "user_id" - UserMetadataColumnResourceOwner = "resource_owner" - UserMetadataColumnCreationDate = "creation_date" - UserMetadataColumnChangeDate = "change_date" - UserMetadataColumnSequence = "sequence" - UserMetadataColumnKey = "key" - UserMetadataColumnValue = "value" -) - func (p *UserMetadataProjection) reduceMetadataSet(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.MetadataSetEvent) if !ok { - logging.LogWithFields("HANDL-Sgn5w", "seq", event.Sequence(), "expectedType", user.MetadataSetType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Ghn52", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Ghn52", "reduce.wrong.event.type %s", user.MetadataSetType) } return crdb.NewUpsertStatement( e, []handler.Column{ handler.NewCol(UserMetadataColumnUserID, e.Aggregate().ID), handler.NewCol(UserMetadataColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(UserMetadataColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(UserMetadataColumnCreationDate, e.CreationDate()), handler.NewCol(UserMetadataColumnChangeDate, e.CreationDate()), handler.NewCol(UserMetadataColumnSequence, e.Sequence()), @@ -85,8 +100,7 @@ func (p *UserMetadataProjection) reduceMetadataSet(event eventstore.Event) (*han func (p *UserMetadataProjection) reduceMetadataRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.MetadataRemovedEvent) if !ok { - logging.LogWithFields("HANDL-Dbfg2", "seq", event.Sequence(), "expectedType", user.MetadataRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Bm542", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Bm542", "reduce.wrong.event.type %s", user.MetadataRemovedType) } return crdb.NewDeleteStatement( e, @@ -103,8 +117,7 @@ func (p *UserMetadataProjection) reduceMetadataRemovedAll(event eventstore.Event *user.UserRemovedEvent: //ok default: - logging.LogWithFields("HANDL-Dfbh2", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{user.MetadataRemovedAllType, user.UserRemovedType}).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Bmnf2", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Bmnf2", "reduce.wrong.event.type %v", []eventstore.EventType{user.MetadataRemovedAllType, user.UserRemovedType}) } return crdb.NewDeleteStatement( event, diff --git a/internal/query/projection/user_metadata_test.go b/internal/query/projection/user_metadata_test.go index e5c88ac1fc..b105aadb34 100644 --- a/internal/query/projection/user_metadata_test.go +++ b/internal/query/projection/user_metadata_test.go @@ -41,10 +41,11 @@ func TestUserMetadataProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPSERT INTO zitadel.projections.user_metadata (user_id, resource_owner, creation_date, change_date, sequence, key, value) VALUES ($1, $2, $3, $4, $5, $6, $7)", + expectedStmt: "UPSERT INTO projections.user_metadata (user_id, resource_owner, instance_id, creation_date, change_date, sequence, key, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", expectedArgs: []interface{}{ "agg-id", "ro-id", + "instance-id", anyArg{}, anyArg{}, uint64(15), @@ -76,7 +77,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_metadata WHERE (user_id = $1) AND (key = $2)", + expectedStmt: "DELETE FROM projections.user_metadata WHERE (user_id = $1) AND (key = $2)", expectedArgs: []interface{}{ "agg-id", "key", @@ -104,7 +105,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_metadata WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.user_metadata WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -131,7 +132,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.user_metadata WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.user_metadata WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/user_personal_access_token.go b/internal/query/projection/user_personal_access_token.go index a11a3b45c5..a6f28d3a3a 100644 --- a/internal/query/projection/user_personal_access_token.go +++ b/internal/query/projection/user_personal_access_token.go @@ -3,7 +3,6 @@ package projection import ( "context" - "github.com/caos/logging" "github.com/lib/pq" "github.com/caos/zitadel/internal/errors" @@ -13,18 +12,46 @@ import ( "github.com/caos/zitadel/internal/repository/user" ) +const ( + PersonalAccessTokenProjectionTable = "projections.personal_access_tokens" + + PersonalAccessTokenColumnID = "id" + PersonalAccessTokenColumnCreationDate = "creation_date" + PersonalAccessTokenColumnChangeDate = "change_date" + PersonalAccessTokenColumnSequence = "sequence" + PersonalAccessTokenColumnResourceOwner = "resource_owner" + PersonalAccessTokenColumnInstanceID = "instance_id" + PersonalAccessTokenColumnUserID = "user_id" + PersonalAccessTokenColumnExpiration = "expiration" + PersonalAccessTokenColumnScopes = "scopes" +) + type PersonalAccessTokenProjection struct { crdb.StatementHandler } -const ( - PersonalAccessTokenProjectionTable = "zitadel.projections.personal_access_tokens" -) - func NewPersonalAccessTokenProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PersonalAccessTokenProjection { p := new(PersonalAccessTokenProjection) config.ProjectionName = PersonalAccessTokenProjectionTable config.Reducers = p.reducers() + config.InitCheck = crdb.NewTableCheck( + crdb.NewTable([]*crdb.Column{ + crdb.NewColumn(PersonalAccessTokenColumnID, crdb.ColumnTypeText), + crdb.NewColumn(PersonalAccessTokenColumnCreationDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(PersonalAccessTokenColumnChangeDate, crdb.ColumnTypeTimestamp), + crdb.NewColumn(PersonalAccessTokenColumnSequence, crdb.ColumnTypeInt64), + crdb.NewColumn(PersonalAccessTokenColumnResourceOwner, crdb.ColumnTypeText), + crdb.NewColumn(PersonalAccessTokenColumnInstanceID, crdb.ColumnTypeText), + crdb.NewColumn(PersonalAccessTokenColumnUserID, crdb.ColumnTypeText), + crdb.NewColumn(PersonalAccessTokenColumnExpiration, crdb.ColumnTypeTimestamp), + crdb.NewColumn(PersonalAccessTokenColumnScopes, crdb.ColumnTypeTextArray, crdb.Nullable()), + }, + crdb.NewPrimaryKey(PersonalAccessTokenColumnInstanceID, PersonalAccessTokenColumnID), + crdb.NewIndex("user_idx", []string{PersonalAccessTokenColumnUserID}), + crdb.NewIndex("ro_idx", []string{PersonalAccessTokenColumnResourceOwner}), + ), + ) + p.StatementHandler = crdb.NewStatementHandler(ctx, config) return p } @@ -51,22 +78,10 @@ func (p *PersonalAccessTokenProjection) reducers() []handler.AggregateReducer { } } -const ( - PersonalAccessTokenColumnID = "id" - PersonalAccessTokenColumnCreationDate = "creation_date" - PersonalAccessTokenColumnChangeDate = "change_date" - PersonalAccessTokenColumnResourceOwner = "resource_owner" - PersonalAccessTokenColumnSequence = "sequence" - PersonalAccessTokenColumnUserID = "user_id" - PersonalAccessTokenColumnExpiration = "expiration" - PersonalAccessTokenColumnScopes = "scopes" -) - func (p *PersonalAccessTokenProjection) reducePersonalAccessTokenAdded(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.PersonalAccessTokenAddedEvent) if !ok { - logging.LogWithFields("HANDL-Dbfg2", "seq", event.Sequence(), "expectedType", user.PersonalAccessTokenAddedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-DVgf7", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-DVgf7", "reduce.wrong.event.type %s", user.PersonalAccessTokenAddedType) } return crdb.NewCreateStatement( e, @@ -75,6 +90,7 @@ func (p *PersonalAccessTokenProjection) reducePersonalAccessTokenAdded(event eve handler.NewCol(PersonalAccessTokenColumnCreationDate, e.CreationDate()), handler.NewCol(PersonalAccessTokenColumnChangeDate, e.CreationDate()), handler.NewCol(PersonalAccessTokenColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(PersonalAccessTokenColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(PersonalAccessTokenColumnSequence, e.Sequence()), handler.NewCol(PersonalAccessTokenColumnUserID, e.Aggregate().ID), handler.NewCol(PersonalAccessTokenColumnExpiration, e.Expiration), @@ -86,8 +102,7 @@ func (p *PersonalAccessTokenProjection) reducePersonalAccessTokenAdded(event eve func (p *PersonalAccessTokenProjection) reducePersonalAccessTokenRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.PersonalAccessTokenRemovedEvent) if !ok { - logging.LogWithFields("HANDL-Edf32", "seq", event.Sequence(), "expectedType", user.PersonalAccessTokenRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-g7u3F", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-g7u3F", "reduce.wrong.event.type %s", user.PersonalAccessTokenRemovedType) } return crdb.NewDeleteStatement( e, @@ -100,8 +115,7 @@ func (p *PersonalAccessTokenProjection) reducePersonalAccessTokenRemoved(event e func (p *PersonalAccessTokenProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, ok := event.(*user.UserRemovedEvent) if !ok { - logging.LogWithFields("HANDL-GEg43", "seq", event.Sequence(), "expectedType", user.UserRemovedType).Error("wrong event type") - return nil, errors.ThrowInvalidArgument(nil, "HANDL-Dff3h", "reduce.wrong.event.type") + return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dff3h", "reduce.wrong.event.type %s", user.UserRemovedType) } return crdb.NewDeleteStatement( e, diff --git a/internal/query/projection/user_personal_access_token_test.go b/internal/query/projection/user_personal_access_token_test.go index a3041d8e10..89acd4e0e6 100644 --- a/internal/query/projection/user_personal_access_token_test.go +++ b/internal/query/projection/user_personal_access_token_test.go @@ -41,12 +41,13 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.personal_access_tokens (id, creation_date, change_date, resource_owner, sequence, user_id, expiration, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.personal_access_tokens (id, creation_date, change_date, resource_owner, instance_id, sequence, user_id, expiration, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "tokenID", anyArg{}, anyArg{}, "ro-id", + "instance-id", uint64(15), "agg-id", time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC), @@ -75,7 +76,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.personal_access_tokens WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.personal_access_tokens WHERE (id = $1)", expectedArgs: []interface{}{ "tokenID", }, @@ -102,7 +103,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.personal_access_tokens WHERE (user_id = $1)", + expectedStmt: "DELETE FROM projections.personal_access_tokens WHERE (user_id = $1)", expectedArgs: []interface{}{ "agg-id", }, diff --git a/internal/query/projection/user_test.go b/internal/query/projection/user_test.go index 4c56d38c42..3856000bcd 100644 --- a/internal/query/projection/user_test.go +++ b/internal/query/projection/user_test.go @@ -50,12 +50,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -63,7 +64,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -108,12 +109,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -121,7 +123,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -161,12 +163,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -174,7 +177,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -219,12 +222,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -232,7 +236,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -277,12 +281,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -290,7 +295,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -330,12 +335,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "user-name", @@ -343,7 +349,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.users_humans (user_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", "first-name", @@ -378,7 +384,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (state) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ domain.UserStateInitial, "agg-id", @@ -406,7 +412,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (state) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ domain.UserStateInitial, "agg-id", @@ -434,7 +440,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (state) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ domain.UserStateActive, "agg-id", @@ -462,7 +468,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (state) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.users SET (state) = ($1) WHERE (id = $2)", expectedArgs: []interface{}{ domain.UserStateActive, "agg-id", @@ -490,7 +496,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserStateLocked, @@ -520,7 +526,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserStateActive, @@ -550,7 +556,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserStateInactive, @@ -580,7 +586,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.users SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, domain.UserStateActive, @@ -610,7 +616,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM zitadel.projections.users WHERE (id = $1)", + expectedStmt: "DELETE FROM projections.users WHERE (id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -639,7 +645,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.users SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4)", expectedArgs: []interface{}{ anyArg{}, "username", @@ -676,7 +682,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -684,7 +690,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7)", + expectedStmt: "UPDATE projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7)", expectedArgs: []interface{}{ "first-name", "last-name", @@ -724,7 +730,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -732,7 +738,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7)", + expectedStmt: "UPDATE projections.users_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7)", expectedArgs: []interface{}{ "first-name", "last-name", @@ -767,7 +773,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -775,7 +781,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ "+41 00 000 00 00", false, @@ -806,7 +812,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -814,7 +820,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ "+41 00 000 00 00", false, @@ -843,7 +849,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -851,7 +857,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ nil, nil, @@ -880,7 +886,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -888,7 +894,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ nil, nil, @@ -917,7 +923,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -925,7 +931,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ true, "agg-id", @@ -953,7 +959,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -961,7 +967,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ true, "agg-id", @@ -991,7 +997,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -999,7 +1005,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ "email@zitadel.ch", false, @@ -1030,7 +1036,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1038,7 +1044,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ "email@zitadel.ch", false, @@ -1067,7 +1073,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1075,7 +1081,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ true, "agg-id", @@ -1103,7 +1109,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1111,7 +1117,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (is_email_verified) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ true, "agg-id", @@ -1141,7 +1147,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1149,7 +1155,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ "users/agg-id/avatar", "agg-id", @@ -1177,7 +1183,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1185,7 +1191,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_humans SET (avatar_key) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ nil, "agg-id", @@ -1216,12 +1222,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "username", @@ -1229,7 +1236,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_machines (user_id, name, description) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.users_machines (user_id, name, description) VALUES ($1, $2, $3)", expectedArgs: []interface{}{ "agg-id", "machine-name", @@ -1262,12 +1269,13 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO zitadel.projections.users (id, creation_date, change_date, resource_owner, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.users (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedArgs: []interface{}{ "agg-id", anyArg{}, anyArg{}, "ro-id", + "instance-id", domain.UserStateActive, uint64(15), "username", @@ -1275,7 +1283,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "INSERT INTO zitadel.projections.users_machines (user_id, name, description) VALUES ($1, $2, $3)", + expectedStmt: "INSERT INTO projections.users_machines (user_id, name, description) VALUES ($1, $2, $3)", expectedArgs: []interface{}{ "agg-id", "machine-name", @@ -1307,7 +1315,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1315,7 +1323,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_machines SET (name, description) = ($1, $2) WHERE (user_id = $3)", + expectedStmt: "UPDATE projections.users_machines SET (name, description) = ($1, $2) WHERE (user_id = $3)", expectedArgs: []interface{}{ "machine-name", "description", @@ -1346,7 +1354,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1354,7 +1362,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_machines SET (name) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_machines SET (name) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ "machine-name", "agg-id", @@ -1384,7 +1392,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE zitadel.projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", + expectedStmt: "UPDATE projections.users SET (change_date, sequence) = ($1, $2) WHERE (id = $3)", expectedArgs: []interface{}{ anyArg{}, uint64(15), @@ -1392,7 +1400,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE zitadel.projections.users_machines SET (description) = ($1) WHERE (user_id = $2)", + expectedStmt: "UPDATE projections.users_machines SET (description) = ($1) WHERE (user_id = $2)", expectedArgs: []interface{}{ "description", "agg-id", diff --git a/internal/query/secret_generator_test.go b/internal/query/secret_generator_test.go index 3f4617d1e7..fe8d8fb37a 100644 --- a/internal/query/secret_generator_test.go +++ b/internal/query/secret_generator_test.go @@ -29,20 +29,20 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols,`+ + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.secret_generators`), + ` FROM projections.secret_generators`), nil, nil, ), @@ -54,20 +54,20 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols,`+ + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.secret_generators`), + ` FROM projections.secret_generators`), []string{ "aggregate_id", "generator_type", @@ -128,20 +128,20 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols,`+ + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.secret_generators`), + ` FROM projections.secret_generators`), []string{ "aggregate_id", "generator_type", @@ -230,20 +230,20 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols,`+ + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.secret_generators`), + ` FROM projections.secret_generators`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -260,19 +260,19 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorQuery, want: want{ sqlExpectations: mockQueries( - `SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols`+ - ` FROM zitadel.projections.secret_generators`, + `SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols`+ + ` FROM projections.secret_generators`, nil, nil, ), @@ -290,19 +290,19 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols`+ - ` FROM zitadel.projections.secret_generators`), + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols`+ + ` FROM projections.secret_generators`), []string{ "aggregate_id", "generator_type", @@ -353,19 +353,19 @@ func Test_SecretGeneratorsPrepares(t *testing.T) { prepare: prepareSecretGeneratorQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.secret_generators.aggregate_id,`+ - ` zitadel.projections.secret_generators.generator_type,`+ - ` zitadel.projections.secret_generators.creation_date,`+ - ` zitadel.projections.secret_generators.change_date,`+ - ` zitadel.projections.secret_generators.resource_owner,`+ - ` zitadel.projections.secret_generators.sequence,`+ - ` zitadel.projections.secret_generators.length,`+ - ` zitadel.projections.secret_generators.expiry,`+ - ` zitadel.projections.secret_generators.include_lower_letters,`+ - ` zitadel.projections.secret_generators.include_upper_letters,`+ - ` zitadel.projections.secret_generators.include_digits,`+ - ` zitadel.projections.secret_generators.include_symbols`+ - ` FROM zitadel.projections.secret_generators`), + regexp.QuoteMeta(`SELECT projections.secret_generators.aggregate_id,`+ + ` projections.secret_generators.generator_type,`+ + ` projections.secret_generators.creation_date,`+ + ` projections.secret_generators.change_date,`+ + ` projections.secret_generators.resource_owner,`+ + ` projections.secret_generators.sequence,`+ + ` projections.secret_generators.length,`+ + ` projections.secret_generators.expiry,`+ + ` projections.secret_generators.include_lower_letters,`+ + ` projections.secret_generators.include_upper_letters,`+ + ` projections.secret_generators.include_digits,`+ + ` projections.secret_generators.include_symbols`+ + ` FROM projections.secret_generators`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/secret_generators.go b/internal/query/secret_generators.go index f029c07fd8..c8c7c963e2 100644 --- a/internal/query/secret_generators.go +++ b/internal/query/secret_generators.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/crypto" @@ -23,6 +25,10 @@ var ( name: projection.SecretGeneratorColumnAggregateID, table: secretGeneratorsTable, } + SecretGeneratorColumnInstanceID = Column{ + name: projection.SecretGeneratorColumnInstanceID, + table: secretGeneratorsTable, + } SecretGeneratorColumnGeneratorType = Column{ name: projection.SecretGeneratorColumnGeneratorType, table: secretGeneratorsTable, @@ -131,6 +137,7 @@ func (q *Queries) SecretGeneratorByType(ctx context.Context, generatorType domai stmt, scan := prepareSecretGeneratorQuery() query, args, err := stmt.Where(sq.Eq{ SecretGeneratorColumnGeneratorType.identifier(): generatorType, + SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-3k99f", "Errors.Query.SQLStatment") @@ -142,7 +149,10 @@ func (q *Queries) SecretGeneratorByType(ctx context.Context, generatorType domai func (q *Queries) SearchSecretGenerators(ctx context.Context, queries *SecretGeneratorSearchQueries) (secretGenerators *SecretGenerators, err error) { query, scan := prepareSecretGeneratorsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-sn9lw", "Errors.Query.InvalidRequest") } diff --git a/internal/query/sms.go b/internal/query/sms.go index ab7a1ae163..6e7451f94c 100644 --- a/internal/query/sms.go +++ b/internal/query/sms.go @@ -7,6 +7,8 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -73,6 +75,10 @@ var ( name: projection.SMSColumnResourceOwner, table: smsConfigsTable, } + SMSConfigColumnInstanceID = Column{ + name: projection.SMSColumnInstanceID, + table: smsConfigsTable, + } SMSConfigColumnState = Column{ name: projection.SMSColumnState, table: smsConfigsTable, @@ -109,7 +115,8 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (*SMSCon stmt, scan := prepareSMSConfigQuery() query, args, err := stmt.Where( sq.Eq{ - SMSConfigColumnID.identifier(): id, + SMSConfigColumnID.identifier(): id, + SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }, ).ToSql() if err != nil { @@ -122,7 +129,10 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (*SMSCon func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearchQueries) (*SMSConfigs, error) { query, scan := prepareSMSConfigsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-sn9Jf", "Errors.Query.InvalidRequest") } diff --git a/internal/query/sms_test.go b/internal/query/sms_test.go index 8e155d9cdb..5b2ccaaad4 100644 --- a/internal/query/sms_test.go +++ b/internal/query/sms_test.go @@ -14,37 +14,37 @@ import ( ) var ( - expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT zitadel.projections.sms_configs.id,` + - ` zitadel.projections.sms_configs.aggregate_id,` + - ` zitadel.projections.sms_configs.creation_date,` + - ` zitadel.projections.sms_configs.change_date,` + - ` zitadel.projections.sms_configs.resource_owner,` + - ` zitadel.projections.sms_configs.state,` + - ` zitadel.projections.sms_configs.sequence,` + + expectedSMSConfigQuery = regexp.QuoteMeta(`SELECT projections.sms_configs.id,` + + ` projections.sms_configs.aggregate_id,` + + ` projections.sms_configs.creation_date,` + + ` projections.sms_configs.change_date,` + + ` projections.sms_configs.resource_owner,` + + ` projections.sms_configs.state,` + + ` projections.sms_configs.sequence,` + // twilio config - ` zitadel.projections.sms_configs_twilio.sms_id,` + - ` zitadel.projections.sms_configs_twilio.sid,` + - ` zitadel.projections.sms_configs_twilio.token,` + - ` zitadel.projections.sms_configs_twilio.sender_number` + - ` FROM zitadel.projections.sms_configs` + - ` LEFT JOIN zitadel.projections.sms_configs_twilio ON zitadel.projections.sms_configs.id = zitadel.projections.sms_configs_twilio.sms_id`) - expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT zitadel.projections.sms_configs.id,` + - ` zitadel.projections.sms_configs.aggregate_id,` + - ` zitadel.projections.sms_configs.creation_date,` + - ` zitadel.projections.sms_configs.change_date,` + - ` zitadel.projections.sms_configs.resource_owner,` + - ` zitadel.projections.sms_configs.state,` + - ` zitadel.projections.sms_configs.sequence,` + + ` projections.sms_configs_twilio.sms_id,` + + ` projections.sms_configs_twilio.sid,` + + ` projections.sms_configs_twilio.token,` + + ` projections.sms_configs_twilio.sender_number` + + ` FROM projections.sms_configs` + + ` LEFT JOIN projections.sms_configs_twilio ON projections.sms_configs.id = projections.sms_configs_twilio.sms_id`) + expectedSMSConfigsQuery = regexp.QuoteMeta(`SELECT projections.sms_configs.id,` + + ` projections.sms_configs.aggregate_id,` + + ` projections.sms_configs.creation_date,` + + ` projections.sms_configs.change_date,` + + ` projections.sms_configs.resource_owner,` + + ` projections.sms_configs.state,` + + ` projections.sms_configs.sequence,` + // twilio config - ` zitadel.projections.sms_configs_twilio.sms_id,` + - ` zitadel.projections.sms_configs_twilio.sid,` + - ` zitadel.projections.sms_configs_twilio.token,` + - ` zitadel.projections.sms_configs_twilio.sender_number,` + + ` projections.sms_configs_twilio.sms_id,` + + ` projections.sms_configs_twilio.sid,` + + ` projections.sms_configs_twilio.token,` + + ` projections.sms_configs_twilio.sender_number,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.sms_configs` + - ` LEFT JOIN zitadel.projections.sms_configs_twilio ON zitadel.projections.sms_configs.id = zitadel.projections.sms_configs_twilio.sms_id`) + ` FROM projections.sms_configs` + + ` LEFT JOIN projections.sms_configs_twilio ON projections.sms_configs.id = projections.sms_configs_twilio.sms_id`) smsConfigCols = []string{ "id", diff --git a/internal/query/smtp.go b/internal/query/smtp.go index 7386e65b49..69372d200e 100644 --- a/internal/query/smtp.go +++ b/internal/query/smtp.go @@ -7,6 +7,9 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/query/projection" @@ -33,6 +36,10 @@ var ( name: projection.SMTPConfigColumnResourceOwner, table: smtpConfigsTable, } + SMTPConfigColumnInstanceID = Column{ + name: projection.SMTPConfigColumnInstanceID, + table: smtpConfigsTable, + } SMTPConfigColumnSequence = Column{ name: projection.SMTPConfigColumnSequence, table: smtpConfigsTable, @@ -41,12 +48,12 @@ var ( name: projection.SMTPConfigColumnTLS, table: smtpConfigsTable, } - SMTPConfigColumnFromAddress = Column{ - name: projection.SMTPConfigColumnFromAddress, + SMTPConfigColumnSenderAddress = Column{ + name: projection.SMTPConfigColumnSenderAddress, table: smtpConfigsTable, } - SMTPConfigColumnFromName = Column{ - name: projection.SMTPConfigColumnFromName, + SMTPConfigColumnSenderName = Column{ + name: projection.SMTPConfigColumnSenderName, table: smtpConfigsTable, } SMTPConfigColumnSMTPHost = Column{ @@ -87,6 +94,7 @@ func (q *Queries) SMTPConfigByAggregateID(ctx context.Context, aggregateID strin stmt, scan := prepareSMTPConfigQuery() query, args, err := stmt.Where(sq.Eq{ SMTPConfigColumnAggregateID.identifier(): aggregateID, + SMTPConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-3m9sl", "Errors.Query.SQLStatment") @@ -106,8 +114,8 @@ func prepareSMTPConfigQuery() (sq.SelectBuilder, func(*sql.Row) (*SMTPConfig, er SMTPConfigColumnResourceOwner.identifier(), SMTPConfigColumnSequence.identifier(), SMTPConfigColumnTLS.identifier(), - SMTPConfigColumnFromAddress.identifier(), - SMTPConfigColumnFromName.identifier(), + SMTPConfigColumnSenderAddress.identifier(), + SMTPConfigColumnSenderName.identifier(), SMTPConfigColumnSMTPHost.identifier(), SMTPConfigColumnSMTPUser.identifier(), SMTPConfigColumnSMTPPassword.identifier()). diff --git a/internal/query/smtp_test.go b/internal/query/smtp_test.go index b818bc82af..f7cd5c73f0 100644 --- a/internal/query/smtp_test.go +++ b/internal/query/smtp_test.go @@ -28,18 +28,18 @@ func Test_SMTPConfigsPrepares(t *testing.T) { prepare: prepareSMTPConfigQuery, want: want{ sqlExpectations: mockQueries( - `SELECT zitadel.projections.smtp_configs.aggregate_id,`+ - ` zitadel.projections.smtp_configs.creation_date,`+ - ` zitadel.projections.smtp_configs.change_date,`+ - ` zitadel.projections.smtp_configs.resource_owner,`+ - ` zitadel.projections.smtp_configs.sequence,`+ - ` zitadel.projections.smtp_configs.tls,`+ - ` zitadel.projections.smtp_configs.sender_address,`+ - ` zitadel.projections.smtp_configs.sender_name,`+ - ` zitadel.projections.smtp_configs.host,`+ - ` zitadel.projections.smtp_configs.username,`+ - ` zitadel.projections.smtp_configs.password`+ - ` FROM zitadel.projections.smtp_configs`, + `SELECT projections.smtp_configs.aggregate_id,`+ + ` projections.smtp_configs.creation_date,`+ + ` projections.smtp_configs.change_date,`+ + ` projections.smtp_configs.resource_owner,`+ + ` projections.smtp_configs.sequence,`+ + ` projections.smtp_configs.tls,`+ + ` projections.smtp_configs.sender_address,`+ + ` projections.smtp_configs.sender_name,`+ + ` projections.smtp_configs.host,`+ + ` projections.smtp_configs.username,`+ + ` projections.smtp_configs.password`+ + ` FROM projections.smtp_configs`, nil, nil, ), @@ -57,18 +57,18 @@ func Test_SMTPConfigsPrepares(t *testing.T) { prepare: prepareSMTPConfigQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.smtp_configs.aggregate_id,`+ - ` zitadel.projections.smtp_configs.creation_date,`+ - ` zitadel.projections.smtp_configs.change_date,`+ - ` zitadel.projections.smtp_configs.resource_owner,`+ - ` zitadel.projections.smtp_configs.sequence,`+ - ` zitadel.projections.smtp_configs.tls,`+ - ` zitadel.projections.smtp_configs.sender_address,`+ - ` zitadel.projections.smtp_configs.sender_name,`+ - ` zitadel.projections.smtp_configs.host,`+ - ` zitadel.projections.smtp_configs.username,`+ - ` zitadel.projections.smtp_configs.password`+ - ` FROM zitadel.projections.smtp_configs`), + regexp.QuoteMeta(`SELECT projections.smtp_configs.aggregate_id,`+ + ` projections.smtp_configs.creation_date,`+ + ` projections.smtp_configs.change_date,`+ + ` projections.smtp_configs.resource_owner,`+ + ` projections.smtp_configs.sequence,`+ + ` projections.smtp_configs.tls,`+ + ` projections.smtp_configs.sender_address,`+ + ` projections.smtp_configs.sender_name,`+ + ` projections.smtp_configs.host,`+ + ` projections.smtp_configs.username,`+ + ` projections.smtp_configs.password`+ + ` FROM projections.smtp_configs`), []string{ "aggregate_id", "creation_date", @@ -116,18 +116,18 @@ func Test_SMTPConfigsPrepares(t *testing.T) { prepare: prepareSMTPConfigQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.smtp_configs.aggregate_id,`+ - ` zitadel.projections.smtp_configs.creation_date,`+ - ` zitadel.projections.smtp_configs.change_date,`+ - ` zitadel.projections.smtp_configs.resource_owner,`+ - ` zitadel.projections.smtp_configs.sequence,`+ - ` zitadel.projections.smtp_configs.tls,`+ - ` zitadel.projections.smtp_configs.sender_address,`+ - ` zitadel.projections.smtp_configs.sender_name,`+ - ` zitadel.projections.smtp_configs.host,`+ - ` zitadel.projections.smtp_configs.username,`+ - ` zitadel.projections.smtp_configs.password`+ - ` FROM zitadel.projections.smtp_configs`), + regexp.QuoteMeta(`SELECT projections.smtp_configs.aggregate_id,`+ + ` projections.smtp_configs.creation_date,`+ + ` projections.smtp_configs.change_date,`+ + ` projections.smtp_configs.resource_owner,`+ + ` projections.smtp_configs.sequence,`+ + ` projections.smtp_configs.tls,`+ + ` projections.smtp_configs.sender_address,`+ + ` projections.smtp_configs.sender_name,`+ + ` projections.smtp_configs.host,`+ + ` projections.smtp_configs.username,`+ + ` projections.smtp_configs.password`+ + ` FROM projections.smtp_configs`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/user.go b/internal/query/user.go index 95dc9e2527..5efb7186af 100644 --- a/internal/query/user.go +++ b/internal/query/user.go @@ -10,6 +10,8 @@ import ( "github.com/lib/pq" "golang.org/x/text/language" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" @@ -115,6 +117,10 @@ var ( name: projection.UserResourceOwnerCol, table: userTable, } + UserInstanceIDCol = Column{ + name: projection.UserInstanceIDCol, + table: userTable, + } UserStateCol = Column{ name: projection.UserStateCol, table: userTable, @@ -132,17 +138,19 @@ var ( table: userTable, } - userLoginNamesTable = loginNameTable.setAlias("login_names") - userLoginNamesUserIDCol = LoginNameUserIDCol.setTable(userLoginNamesTable) - userLoginNamesNameCol = LoginNameNameCol.setTable(userLoginNamesTable) - userLoginNamesListCol = Column{ + userLoginNamesTable = loginNameTable.setAlias("login_names") + userLoginNamesUserIDCol = LoginNameUserIDCol.setTable(userLoginNamesTable) + userLoginNamesNameCol = LoginNameNameCol.setTable(userLoginNamesTable) + userLoginNamesInstanceIDCol = LoginNameInstanceIDCol.setTable(userLoginNamesTable) + userLoginNamesListCol = Column{ name: "loginnames", table: userLoginNamesTable, } - userPreferredLoginNameTable = loginNameTable.setAlias("preferred_login_name") - userPreferredLoginNameUserIDCol = LoginNameUserIDCol.setTable(userPreferredLoginNameTable) - userPreferredLoginNameCol = LoginNameNameCol.setTable(userPreferredLoginNameTable) - userPreferredLoginNameIsPrimaryCol = LoginNameIsPrimaryCol.setTable(userPreferredLoginNameTable) + userPreferredLoginNameTable = loginNameTable.setAlias("preferred_login_name") + userPreferredLoginNameUserIDCol = LoginNameUserIDCol.setTable(userPreferredLoginNameTable) + userPreferredLoginNameCol = LoginNameNameCol.setTable(userPreferredLoginNameTable) + userPreferredLoginNameIsPrimaryCol = LoginNameIsPrimaryCol.setTable(userPreferredLoginNameTable) + userPreferredLoginNameInstanceIDCol = LoginNameInstanceIDCol.setTable(userPreferredLoginNameTable) ) var ( @@ -223,14 +231,15 @@ var ( ) func (q *Queries) GetUserByID(ctx context.Context, userID string, queries ...SearchQuery) (*User, error) { - query, scan := prepareUserQuery() + instanceID := authz.GetInstance(ctx).ID + query, scan := prepareUserQuery(instanceID) for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.Where( - sq.Eq{ - UserIDCol.identifier(): userID, - }).ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserIDCol.identifier(): userID, + UserInstanceIDCol.identifier(): instanceID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-FBg21", "Errors.Query.SQLStatment") } @@ -240,11 +249,14 @@ func (q *Queries) GetUserByID(ctx context.Context, userID string, queries ...Sea } func (q *Queries) GetUser(ctx context.Context, queries ...SearchQuery) (*User, error) { - query, scan := prepareUserQuery() + instanceID := authz.GetInstance(ctx).ID + query, scan := prepareUserQuery(instanceID) for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserInstanceIDCol.identifier(): instanceID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dnhr2", "Errors.Query.SQLStatment") } @@ -258,10 +270,10 @@ func (q *Queries) GetHumanProfile(ctx context.Context, userID string, queries .. for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.Where( - sq.Eq{ - UserIDCol.identifier(): userID, - }).ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserIDCol.identifier(): userID, + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dgbg2", "Errors.Query.SQLStatment") } @@ -275,10 +287,10 @@ func (q *Queries) GetHumanEmail(ctx context.Context, userID string, queries ...S for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.Where( - sq.Eq{ - UserIDCol.identifier(): userID, - }).ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserIDCol.identifier(): userID, + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-BHhj3", "Errors.Query.SQLStatment") } @@ -292,10 +304,10 @@ func (q *Queries) GetHumanPhone(ctx context.Context, userID string, queries ...S for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.Where( - sq.Eq{ - UserIDCol.identifier(): userID, - }).ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserIDCol.identifier(): userID, + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dg43g", "Errors.Query.SQLStatment") } @@ -306,7 +318,10 @@ func (q *Queries) GetHumanPhone(ctx context.Context, userID string, queries ...S func (q *Queries) SearchUsers(ctx context.Context, queries *UserSearchQueries) (*Users, error) { query, scan := prepareUsersQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dgbg2", "Errors.Query.SQLStatment") } @@ -350,7 +365,9 @@ func (q *Queries) IsUserUnique(ctx context.Context, username, email, resourceOwn for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.ToSql() + stmt, args, err := query.Where(sq.Eq{ + UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return false, errors.ThrowInternal(err, "QUERY-Dg43g", "Errors.Query.SQLStatment") } @@ -419,13 +436,15 @@ func NewUserLoginNamesSearchQuery(value string) (SearchQuery, error) { return NewTextQuery(userLoginNamesListCol, value, TextListContains) } -func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { +func prepareUserQuery(instanceID string) (sq.SelectBuilder, func(*sql.Row) (*User, error)) { loginNamesQuery, _, err := sq.Select( userLoginNamesUserIDCol.identifier(), "ARRAY_AGG("+userLoginNamesNameCol.identifier()+") as "+userLoginNamesListCol.name). From(userLoginNamesTable.identifier()). GroupBy(userLoginNamesUserIDCol.identifier()). - ToSql() + Where(sq.Eq{ + userLoginNamesInstanceIDCol.identifier(): instanceID, + }).ToSql() if err != nil { return sq.SelectBuilder{}, nil } @@ -433,10 +452,10 @@ func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { userPreferredLoginNameUserIDCol.identifier(), userPreferredLoginNameCol.identifier()). From(userPreferredLoginNameTable.identifier()). - Where( - sq.Eq{ - userPreferredLoginNameIsPrimaryCol.identifier(): true, - }).ToSql() + Where(sq.Eq{ + userPreferredLoginNameIsPrimaryCol.identifier(): true, + userPreferredLoginNameInstanceIDCol.identifier(): instanceID, + }).ToSql() if err != nil { return sq.SelectBuilder{}, nil } diff --git a/internal/query/user_auth_method.go b/internal/query/user_auth_method.go index 368f85c3da..7919cd5ad6 100644 --- a/internal/query/user_auth_method.go +++ b/internal/query/user_auth_method.go @@ -7,6 +7,9 @@ import ( "time" sq "github.com/Masterminds/squirrel" + + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/query/projection" "github.com/caos/zitadel/internal/domain" @@ -33,6 +36,10 @@ var ( name: projection.UserAuthMethodResourceOwnerCol, table: userAuthMethodTable, } + UserAuthMethodColumnInstanceID = Column{ + name: projection.UserAuthMethodInstanceIDCol, + table: userAuthMethodTable, + } UserAuthMethodColumnUserID = Column{ name: projection.UserAuthMethodUserIDCol, table: userAuthMethodTable, @@ -84,6 +91,7 @@ func (q *Queries) UserAuthMethodByIDs(ctx context.Context, userID, tokenID, reso UserAuthMethodColumnTokenID.identifier(): tokenID, UserAuthMethodColumnResourceOwner.identifier(): resourceOwner, UserAuthMethodColumnMethodType.identifier(): methodType, + UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-2m00Q", "Errors.Query.SQLStatment") @@ -95,7 +103,10 @@ func (q *Queries) UserAuthMethodByIDs(ctx context.Context, userID, tokenID, reso func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMethodSearchQueries) (userAuthMethods *AuthMethods, err error) { query, scan := prepareUserAuthMethodsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-j9NJd", "Errors.Query.InvalidRequest") } diff --git a/internal/query/user_auth_method_test.go b/internal/query/user_auth_method_test.go index c1ccf042fd..ba0e32538a 100644 --- a/internal/query/user_auth_method_test.go +++ b/internal/query/user_auth_method_test.go @@ -28,17 +28,17 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type,`+ + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.user_auth_methods`), + ` FROM projections.user_auth_methods`), nil, nil, ), @@ -50,17 +50,17 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type,`+ + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.user_auth_methods`), + ` FROM projections.user_auth_methods`), []string{ "token_id", "creation_date", @@ -112,17 +112,17 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodsQuery, want: want{ sqlExpectations: mockQueries( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type,`+ + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.user_auth_methods`), + ` FROM projections.user_auth_methods`), []string{ "token_id", "creation_date", @@ -196,17 +196,17 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodsQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type,`+ + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type,`+ ` COUNT(*) OVER ()`+ - ` FROM zitadel.projections.user_auth_methods`), + ` FROM projections.user_auth_methods`), sql.ErrConnDone, ), err: func(err error) (error, bool) { @@ -223,16 +223,16 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodQuery, want: want{ sqlExpectations: mockQueries( - `SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type`+ - ` FROM zitadel.projections.user_auth_methods`, + `SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type`+ + ` FROM projections.user_auth_methods`, nil, nil, ), @@ -250,16 +250,16 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodQuery, want: want{ sqlExpectations: mockQuery( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type`+ - ` FROM zitadel.projections.user_auth_methods`), + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type`+ + ` FROM projections.user_auth_methods`), []string{ "token_id", "creation_date", @@ -301,16 +301,16 @@ func Test_UserAuthMethodPrepares(t *testing.T) { prepare: prepareUserAuthMethodQuery, want: want{ sqlExpectations: mockQueryErr( - regexp.QuoteMeta(`SELECT zitadel.projections.user_auth_methods.token_id,`+ - ` zitadel.projections.user_auth_methods.creation_date,`+ - ` zitadel.projections.user_auth_methods.change_date,`+ - ` zitadel.projections.user_auth_methods.resource_owner,`+ - ` zitadel.projections.user_auth_methods.user_id,`+ - ` zitadel.projections.user_auth_methods.sequence,`+ - ` zitadel.projections.user_auth_methods.name,`+ - ` zitadel.projections.user_auth_methods.state,`+ - ` zitadel.projections.user_auth_methods.method_type`+ - ` FROM zitadel.projections.user_auth_methods`), + regexp.QuoteMeta(`SELECT projections.user_auth_methods.token_id,`+ + ` projections.user_auth_methods.creation_date,`+ + ` projections.user_auth_methods.change_date,`+ + ` projections.user_auth_methods.resource_owner,`+ + ` projections.user_auth_methods.user_id,`+ + ` projections.user_auth_methods.sequence,`+ + ` projections.user_auth_methods.name,`+ + ` projections.user_auth_methods.state,`+ + ` projections.user_auth_methods.method_type`+ + ` FROM projections.user_auth_methods`), sql.ErrConnDone, ), err: func(err error) (error, bool) { diff --git a/internal/query/user_grant.go b/internal/query/user_grant.go index fbf4feb75b..5dbe1f9ab1 100644 --- a/internal/query/user_grant.go +++ b/internal/query/user_grant.go @@ -9,6 +9,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" @@ -151,6 +153,10 @@ var ( name: projection.UserGrantResourceOwner, table: userGrantTable, } + UserGrantInstanceID = Column{ + name: projection.UserGrantInstanceID, + table: userGrantTable, + } UserGrantCreationDate = Column{ name: projection.UserGrantCreationDate, table: userGrantTable, @@ -190,7 +196,10 @@ func (q *Queries) UserGrant(ctx context.Context, queries ...SearchQuery) (*UserG for _, q := range queries { query = q.toQuery(query) } - stmt, args, err := query.ToSql() + stmt, args, err := query. + Where(sq.Eq{ + UserGrantInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Fa1KW", "Errors.Query.SQLStatement") } @@ -201,7 +210,10 @@ func (q *Queries) UserGrant(ctx context.Context, queries ...SearchQuery) (*UserG func (q *Queries) UserGrants(ctx context.Context, queries *UserGrantsQueries) (*UserGrants, error) { query, scan := prepareUserGrantsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + UserGrantInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-wXnQR", "Errors.Query.SQLStatement") } diff --git a/internal/query/user_grant_test.go b/internal/query/user_grant_test.go index ec08d6c5f1..f84a5b00ab 100644 --- a/internal/query/user_grant_test.go +++ b/internal/query/user_grant_test.go @@ -16,32 +16,32 @@ import ( var ( userGrantStmt = regexp.QuoteMeta( - "SELECT zitadel.projections.user_grants.id" + - ", zitadel.projections.user_grants.creation_date" + - ", zitadel.projections.user_grants.change_date" + - ", zitadel.projections.user_grants.sequence" + - ", zitadel.projections.user_grants.grant_id" + - ", zitadel.projections.user_grants.roles" + - ", zitadel.projections.user_grants.state" + - ", zitadel.projections.user_grants.user_id" + - ", zitadel.projections.users.username" + - ", zitadel.projections.users.type" + - ", zitadel.projections.users.resource_owner" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_humans.avatar_key" + - ", zitadel.projections.user_grants.resource_owner" + - ", zitadel.projections.orgs.name" + - ", zitadel.projections.orgs.primary_domain" + - ", zitadel.projections.user_grants.project_id" + - ", zitadel.projections.projects.name" + - " FROM zitadel.projections.user_grants" + - " LEFT JOIN zitadel.projections.users ON zitadel.projections.user_grants.user_id = zitadel.projections.users.id" + - " LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.user_grants.user_id = zitadel.projections.users_humans.user_id" + - " LEFT JOIN zitadel.projections.orgs ON zitadel.projections.user_grants.resource_owner = zitadel.projections.orgs.id" + - " LEFT JOIN zitadel.projections.projects ON zitadel.projections.user_grants.project_id = zitadel.projections.projects.id") + "SELECT projections.user_grants.id" + + ", projections.user_grants.creation_date" + + ", projections.user_grants.change_date" + + ", projections.user_grants.sequence" + + ", projections.user_grants.grant_id" + + ", projections.user_grants.roles" + + ", projections.user_grants.state" + + ", projections.user_grants.user_id" + + ", projections.users.username" + + ", projections.users.type" + + ", projections.users.resource_owner" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.email" + + ", projections.users_humans.display_name" + + ", projections.users_humans.avatar_key" + + ", projections.user_grants.resource_owner" + + ", projections.orgs.name" + + ", projections.orgs.primary_domain" + + ", projections.user_grants.project_id" + + ", projections.projects.name" + + " FROM projections.user_grants" + + " LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" + + " LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" + + " LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" + + " LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id") userGrantCols = []string{ "id", "creation_date", @@ -66,33 +66,33 @@ var ( "name", //project name } userGrantsStmt = regexp.QuoteMeta( - "SELECT zitadel.projections.user_grants.id" + - ", zitadel.projections.user_grants.creation_date" + - ", zitadel.projections.user_grants.change_date" + - ", zitadel.projections.user_grants.sequence" + - ", zitadel.projections.user_grants.grant_id" + - ", zitadel.projections.user_grants.roles" + - ", zitadel.projections.user_grants.state" + - ", zitadel.projections.user_grants.user_id" + - ", zitadel.projections.users.username" + - ", zitadel.projections.users.type" + - ", zitadel.projections.users.resource_owner" + - ", zitadel.projections.users_humans.first_name" + - ", zitadel.projections.users_humans.last_name" + - ", zitadel.projections.users_humans.email" + - ", zitadel.projections.users_humans.display_name" + - ", zitadel.projections.users_humans.avatar_key" + - ", zitadel.projections.user_grants.resource_owner" + - ", zitadel.projections.orgs.name" + - ", zitadel.projections.orgs.primary_domain" + - ", zitadel.projections.user_grants.project_id" + - ", zitadel.projections.projects.name" + + "SELECT projections.user_grants.id" + + ", projections.user_grants.creation_date" + + ", projections.user_grants.change_date" + + ", projections.user_grants.sequence" + + ", projections.user_grants.grant_id" + + ", projections.user_grants.roles" + + ", projections.user_grants.state" + + ", projections.user_grants.user_id" + + ", projections.users.username" + + ", projections.users.type" + + ", projections.users.resource_owner" + + ", projections.users_humans.first_name" + + ", projections.users_humans.last_name" + + ", projections.users_humans.email" + + ", projections.users_humans.display_name" + + ", projections.users_humans.avatar_key" + + ", projections.user_grants.resource_owner" + + ", projections.orgs.name" + + ", projections.orgs.primary_domain" + + ", projections.user_grants.project_id" + + ", projections.projects.name" + ", COUNT(*) OVER ()" + - " FROM zitadel.projections.user_grants" + - " LEFT JOIN zitadel.projections.users ON zitadel.projections.user_grants.user_id = zitadel.projections.users.id" + - " LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.user_grants.user_id = zitadel.projections.users_humans.user_id" + - " LEFT JOIN zitadel.projections.orgs ON zitadel.projections.user_grants.resource_owner = zitadel.projections.orgs.id" + - " LEFT JOIN zitadel.projections.projects ON zitadel.projections.user_grants.project_id = zitadel.projections.projects.id") + " FROM projections.user_grants" + + " LEFT JOIN projections.users ON projections.user_grants.user_id = projections.users.id" + + " LEFT JOIN projections.users_humans ON projections.user_grants.user_id = projections.users_humans.user_id" + + " LEFT JOIN projections.orgs ON projections.user_grants.resource_owner = projections.orgs.id" + + " LEFT JOIN projections.projects ON projections.user_grants.project_id = projections.projects.id") userGrantsCols = append( userGrantCols, "count", diff --git a/internal/query/user_membership.go b/internal/query/user_membership.go index bdbecaed4e..8d70156675 100644 --- a/internal/query/user_membership.go +++ b/internal/query/user_membership.go @@ -6,9 +6,11 @@ import ( "time" sq "github.com/Masterminds/squirrel" + "github.com/lib/pq" + + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" - "github.com/lib/pq" ) type Memberships struct { @@ -90,7 +92,10 @@ func (q *MembershipSearchQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder func (q *Queries) Memberships(ctx context.Context, queries *MembershipSearchQuery) (*Memberships, error) { query, scan := prepareMembershipsQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + membershipInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-T84X9", "Errors.Query.InvalidRequest") } @@ -140,6 +145,10 @@ var ( name: projection.MemberResourceOwner, table: membershipAlias, } + membershipInstanceID = Column{ + name: projection.MemberInstanceID, + table: membershipAlias, + } membershipOrgID = Column{ name: projection.OrgMemberOrgIDCol, table: membershipAlias, diff --git a/internal/query/user_membership_test.go b/internal/query/user_membership_test.go index bdfc70e99d..83c0ec2376 100644 --- a/internal/query/user_membership_test.go +++ b/internal/query/user_membership_test.go @@ -23,8 +23,8 @@ var ( ", memberships.iam_id" + ", memberships.project_id" + ", memberships.grant_id" + - ", zitadel.projections.projects.name" + - ", zitadel.projections.orgs.name" + + ", projections.projects.name" + + ", projections.orgs.name" + ", COUNT(*) OVER ()" + " FROM (" + "SELECT members.user_id" + @@ -37,7 +37,7 @@ var ( ", NULL::STRING AS iam_id" + ", NULL::STRING AS project_id" + ", NULL::STRING AS grant_id" + - " FROM zitadel.projections.org_members as members" + + " FROM projections.org_members as members" + " UNION ALL " + "SELECT members.user_id" + ", members.roles" + @@ -49,7 +49,7 @@ var ( ", members.iam_id" + ", NULL::STRING AS project_id" + ", NULL::STRING AS grant_id" + - " FROM zitadel.projections.iam_members as members" + + " FROM projections.iam_members as members" + " UNION ALL " + "SELECT members.user_id" + ", members.roles" + @@ -61,7 +61,7 @@ var ( ", NULL::STRING AS iam_id" + ", members.project_id" + ", NULL::STRING AS grant_id" + - " FROM zitadel.projections.project_members as members" + + " FROM projections.project_members as members" + " UNION ALL " + "SELECT members.user_id" + ", members.roles" + @@ -73,10 +73,10 @@ var ( ", NULL::STRING AS iam_id" + ", members.project_id" + ", members.grant_id" + - " FROM zitadel.projections.project_grant_members as members" + + " FROM projections.project_grant_members as members" + ") AS memberships" + - " LEFT JOIN zitadel.projections.projects ON memberships.project_id = zitadel.projections.projects.id" + - " LEFT JOIN zitadel.projections.orgs ON memberships.org_id = zitadel.projections.orgs.id") + " LEFT JOIN projections.projects ON memberships.project_id = projections.projects.id" + + " LEFT JOIN projections.orgs ON memberships.org_id = projections.orgs.id") membershipCols = []string{ "user_id", "roles", diff --git a/internal/query/user_metadata.go b/internal/query/user_metadata.go index ad68c05ac1..a29ce2b2da 100644 --- a/internal/query/user_metadata.go +++ b/internal/query/user_metadata.go @@ -8,6 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query/projection" ) @@ -51,6 +53,10 @@ var ( name: projection.UserMetadataColumnResourceOwner, table: userMetadataTable, } + UserMetadataInstanceIDCol = Column{ + name: projection.UserMetadataColumnInstanceID, + table: userMetadataTable, + } UserMetadataSequenceCol = Column{ name: projection.UserMetadataColumnSequence, table: userMetadataTable, @@ -72,8 +78,9 @@ func (q *Queries) GetUserMetadataByKey(ctx context.Context, userID, key string, } stmt, args, err := query.Where( sq.Eq{ - UserMetadataUserIDCol.identifier(): userID, - UserMetadataKeyCol.identifier(): key, + UserMetadataUserIDCol.identifier(): userID, + UserMetadataKeyCol.identifier(): key, + UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-aDGG2", "Errors.Query.SQLStatment") @@ -87,7 +94,8 @@ func (q *Queries) SearchUserMetadata(ctx context.Context, userID string, queries query, scan := prepareUserMetadataListQuery() stmt, args, err := queries.toQuery(query).Where( sq.Eq{ - UserMetadataUserIDCol.identifier(): userID, + UserMetadataUserIDCol.identifier(): userID, + UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).ID, }). ToSql() if err != nil { diff --git a/internal/query/user_metadata_test.go b/internal/query/user_metadata_test.go index 4544755766..ad2e5cf0e7 100644 --- a/internal/query/user_metadata_test.go +++ b/internal/query/user_metadata_test.go @@ -12,13 +12,13 @@ import ( ) var ( - userMetadataQuery = `SELECT zitadel.projections.user_metadata.creation_date,` + - ` zitadel.projections.user_metadata.change_date,` + - ` zitadel.projections.user_metadata.resource_owner,` + - ` zitadel.projections.user_metadata.sequence,` + - ` zitadel.projections.user_metadata.key,` + - ` zitadel.projections.user_metadata.value` + - ` FROM zitadel.projections.user_metadata` + userMetadataQuery = `SELECT projections.user_metadata.creation_date,` + + ` projections.user_metadata.change_date,` + + ` projections.user_metadata.resource_owner,` + + ` projections.user_metadata.sequence,` + + ` projections.user_metadata.key,` + + ` projections.user_metadata.value` + + ` FROM projections.user_metadata` userMetadataCols = []string{ "creation_date", "change_date", @@ -27,14 +27,14 @@ var ( "key", "value", } - userMetadataListQuery = `SELECT zitadel.projections.user_metadata.creation_date,` + - ` zitadel.projections.user_metadata.change_date,` + - ` zitadel.projections.user_metadata.resource_owner,` + - ` zitadel.projections.user_metadata.sequence,` + - ` zitadel.projections.user_metadata.key,` + - ` zitadel.projections.user_metadata.value,` + + userMetadataListQuery = `SELECT projections.user_metadata.creation_date,` + + ` projections.user_metadata.change_date,` + + ` projections.user_metadata.resource_owner,` + + ` projections.user_metadata.sequence,` + + ` projections.user_metadata.key,` + + ` projections.user_metadata.value,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.user_metadata` + ` FROM projections.user_metadata` userMetadataListCols = []string{ "creation_date", "change_date", diff --git a/internal/query/user_personal_access_token.go b/internal/query/user_personal_access_token.go index b0cf26178c..02d62939d7 100644 --- a/internal/query/user_personal_access_token.go +++ b/internal/query/user_personal_access_token.go @@ -9,6 +9,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" + "github.com/caos/zitadel/internal/api/authz" + "github.com/caos/zitadel/internal/query/projection" "github.com/caos/zitadel/internal/errors" @@ -46,6 +48,10 @@ var ( name: projection.PersonalAccessTokenColumnResourceOwner, table: personalAccessTokensTable, } + PersonalAccessTokenColumnInstanceID = Column{ + name: projection.PersonalAccessTokenColumnInstanceID, + table: personalAccessTokensTable, + } PersonalAccessTokenColumnSequence = Column{ name: projection.PersonalAccessTokenColumnSequence, table: personalAccessTokensTable, @@ -80,7 +86,8 @@ func (q *Queries) PersonalAccessTokenByID(ctx context.Context, id string, querie query = q.toQuery(query) } stmt, args, err := query.Where(sq.Eq{ - PersonalAccessTokenColumnID.identifier(): id, + PersonalAccessTokenColumnID.identifier(): id, + PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, }).ToSql() if err != nil { return nil, errors.ThrowInternal(err, "QUERY-Dgfb4", "Errors.Query.SQLStatment") @@ -92,7 +99,10 @@ func (q *Queries) PersonalAccessTokenByID(ctx context.Context, id string, querie func (q *Queries) SearchPersonalAccessTokens(ctx context.Context, queries *PersonalAccessTokenSearchQueries) (personalAccessTokens *PersonalAccessTokens, err error) { query, scan := preparePersonalAccessTokensQuery() - stmt, args, err := queries.toQuery(query).ToSql() + stmt, args, err := queries.toQuery(query). + Where(sq.Eq{ + PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).ID, + }).ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-Hjw2w", "Errors.Query.InvalidRequest") } diff --git a/internal/query/user_personal_access_token_test.go b/internal/query/user_personal_access_token_test.go index 8d35b67967..831762bae8 100644 --- a/internal/query/user_personal_access_token_test.go +++ b/internal/query/user_personal_access_token_test.go @@ -16,15 +16,15 @@ import ( var ( personalAccessTokenStmt = regexp.QuoteMeta( - "SELECT zitadel.projections.personal_access_tokens.id," + - " zitadel.projections.personal_access_tokens.creation_date," + - " zitadel.projections.personal_access_tokens.change_date," + - " zitadel.projections.personal_access_tokens.resource_owner," + - " zitadel.projections.personal_access_tokens.sequence," + - " zitadel.projections.personal_access_tokens.user_id," + - " zitadel.projections.personal_access_tokens.expiration," + - " zitadel.projections.personal_access_tokens.scopes" + - " FROM zitadel.projections.personal_access_tokens") + "SELECT projections.personal_access_tokens.id," + + " projections.personal_access_tokens.creation_date," + + " projections.personal_access_tokens.change_date," + + " projections.personal_access_tokens.resource_owner," + + " projections.personal_access_tokens.sequence," + + " projections.personal_access_tokens.user_id," + + " projections.personal_access_tokens.expiration," + + " projections.personal_access_tokens.scopes" + + " FROM projections.personal_access_tokens") personalAccessTokenCols = []string{ "id", "creation_date", @@ -36,16 +36,16 @@ var ( "scopes", } personalAccessTokensStmt = regexp.QuoteMeta( - "SELECT zitadel.projections.personal_access_tokens.id," + - " zitadel.projections.personal_access_tokens.creation_date," + - " zitadel.projections.personal_access_tokens.change_date," + - " zitadel.projections.personal_access_tokens.resource_owner," + - " zitadel.projections.personal_access_tokens.sequence," + - " zitadel.projections.personal_access_tokens.user_id," + - " zitadel.projections.personal_access_tokens.expiration," + - " zitadel.projections.personal_access_tokens.scopes," + + "SELECT projections.personal_access_tokens.id," + + " projections.personal_access_tokens.creation_date," + + " projections.personal_access_tokens.change_date," + + " projections.personal_access_tokens.resource_owner," + + " projections.personal_access_tokens.sequence," + + " projections.personal_access_tokens.user_id," + + " projections.personal_access_tokens.expiration," + + " projections.personal_access_tokens.scopes," + " COUNT(*) OVER ()" + - " FROM zitadel.projections.personal_access_tokens") + " FROM projections.personal_access_tokens") personalAccessTokensCols = []string{ "id", "creation_date", diff --git a/internal/query/user_test.go b/internal/query/user_test.go index 93dd9e6543..1169bec371 100644 --- a/internal/query/user_test.go +++ b/internal/query/user_test.go @@ -8,6 +8,7 @@ import ( "regexp" "testing" + sq "github.com/Masterminds/squirrel" "github.com/lib/pq" "golang.org/x/text/language" @@ -16,42 +17,43 @@ import ( ) var ( - userQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.creation_date,` + - ` zitadel.projections.users.change_date,` + - ` zitadel.projections.users.resource_owner,` + - ` zitadel.projections.users.sequence,` + - ` zitadel.projections.users.state,` + - ` zitadel.projections.users.type,` + - ` zitadel.projections.users.username,` + + userQuery = `SELECT projections.users.id,` + + ` projections.users.creation_date,` + + ` projections.users.change_date,` + + ` projections.users.resource_owner,` + + ` projections.users.sequence,` + + ` projections.users.state,` + + ` projections.users.type,` + + ` projections.users.username,` + ` login_names.loginnames,` + ` preferred_login_name.login_name,` + - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.first_name,` + - ` zitadel.projections.users_humans.last_name,` + - ` zitadel.projections.users_humans.nick_name,` + - ` zitadel.projections.users_humans.display_name,` + - ` zitadel.projections.users_humans.preferred_language,` + - ` zitadel.projections.users_humans.gender,` + - ` zitadel.projections.users_humans.avatar_key,` + - ` zitadel.projections.users_humans.email,` + - ` zitadel.projections.users_humans.is_email_verified,` + - ` zitadel.projections.users_humans.phone,` + - ` zitadel.projections.users_humans.is_phone_verified,` + - ` zitadel.projections.users_machines.user_id,` + - ` zitadel.projections.users_machines.name,` + - ` zitadel.projections.users_machines.description` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + - ` LEFT JOIN zitadel.projections.users_machines ON zitadel.projections.users.id = zitadel.projections.users_machines.user_id` + + ` projections.users_humans.user_id,` + + ` projections.users_humans.first_name,` + + ` projections.users_humans.last_name,` + + ` projections.users_humans.nick_name,` + + ` projections.users_humans.display_name,` + + ` projections.users_humans.preferred_language,` + + ` projections.users_humans.gender,` + + ` projections.users_humans.avatar_key,` + + ` projections.users_humans.email,` + + ` projections.users_humans.is_email_verified,` + + ` projections.users_humans.phone,` + + ` projections.users_humans.is_phone_verified,` + + ` projections.users_machines.user_id,` + + ` projections.users_machines.name,` + + ` projections.users_machines.description` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` + + ` LEFT JOIN projections.users_machines ON projections.users.id = projections.users_machines.user_id` + ` LEFT JOIN` + ` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as loginnames` + - ` FROM zitadel.projections.login_names as login_names` + + ` FROM projections.login_names as login_names` + + ` WHERE login_names.instance_id = $1` + ` GROUP BY login_names.user_id) as login_names` + - ` on login_names.user_id = zitadel.projections.users.id` + + ` on login_names.user_id = projections.users.id` + ` LEFT JOIN` + - ` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM zitadel.projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` + - ` on preferred_login_name.user_id = zitadel.projections.users.id` + ` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.instance_id = $2 AND preferred_login_name.is_primary = $3) as preferred_login_name` + + ` on preferred_login_name.user_id = projections.users.id` userCols = []string{ "id", "creation_date", @@ -81,22 +83,22 @@ var ( "name", "description", } - profileQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.creation_date,` + - ` zitadel.projections.users.change_date,` + - ` zitadel.projections.users.resource_owner,` + - ` zitadel.projections.users.sequence,` + - //` zitadel.projections.users.state,` + //TODO: - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.first_name,` + - ` zitadel.projections.users_humans.last_name,` + - ` zitadel.projections.users_humans.nick_name,` + - ` zitadel.projections.users_humans.display_name,` + - ` zitadel.projections.users_humans.preferred_language,` + - ` zitadel.projections.users_humans.gender,` + - ` zitadel.projections.users_humans.avatar_key` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + profileQuery = `SELECT projections.users.id,` + + ` projections.users.creation_date,` + + ` projections.users.change_date,` + + ` projections.users.resource_owner,` + + ` projections.users.sequence,` + + //` projections.users.state,` + //TODO: + ` projections.users_humans.user_id,` + + ` projections.users_humans.first_name,` + + ` projections.users_humans.last_name,` + + ` projections.users_humans.nick_name,` + + ` projections.users_humans.display_name,` + + ` projections.users_humans.preferred_language,` + + ` projections.users_humans.gender,` + + ` projections.users_humans.avatar_key` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` profileCols = []string{ "id", "creation_date", @@ -113,17 +115,17 @@ var ( "gender", "avatar_key", } - emailQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.creation_date,` + - ` zitadel.projections.users.change_date,` + - ` zitadel.projections.users.resource_owner,` + - ` zitadel.projections.users.sequence,` + - //` zitadel.projections.users.state,` + //TODO: - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.email,` + - ` zitadel.projections.users_humans.is_email_verified` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + emailQuery = `SELECT projections.users.id,` + + ` projections.users.creation_date,` + + ` projections.users.change_date,` + + ` projections.users.resource_owner,` + + ` projections.users.sequence,` + + //` projections.users.state,` + //TODO: + ` projections.users_humans.user_id,` + + ` projections.users_humans.email,` + + ` projections.users_humans.is_email_verified` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` emailCols = []string{ "id", "creation_date", @@ -135,17 +137,17 @@ var ( "email", "is_email_verified", } - phoneQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.creation_date,` + - ` zitadel.projections.users.change_date,` + - ` zitadel.projections.users.resource_owner,` + - ` zitadel.projections.users.sequence,` + - //` zitadel.projections.users.state,` + //TODO: - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.phone,` + - ` zitadel.projections.users_humans.is_phone_verified` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + phoneQuery = `SELECT projections.users.id,` + + ` projections.users.creation_date,` + + ` projections.users.change_date,` + + ` projections.users.resource_owner,` + + ` projections.users.sequence,` + + //` projections.users.state,` + //TODO: + ` projections.users_humans.user_id,` + + ` projections.users_humans.phone,` + + ` projections.users_humans.is_phone_verified` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` phoneCols = []string{ "id", "creation_date", @@ -158,24 +160,24 @@ var ( "is_phone_verified", } - userUniqueQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.state,` + - ` zitadel.projections.users.username,` + + userUniqueQuery = `SELECT projections.users.id,` + + ` projections.users.state,` + + ` projections.users.username,` + //` login_names.login_names,` + //` preferred_login_name.login_name,` + - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.email,` + - ` zitadel.projections.users_humans.is_email_verified` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + ` projections.users_humans.user_id,` + + ` projections.users_humans.email,` + + ` projections.users_humans.is_email_verified` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` //` LEFT JOIN` + //` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as login_names` + - //` FROM zitadel.projections.login_names as login_names` + + //` FROM projections.login_names as login_names` + //` GROUP BY login_names.user_id) as login_names` + - //` on login_names.user_id = zitadel.projections.users.id` + + //` on login_names.user_id = projections.users.id` + //` LEFT JOIN` + - //` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM zitadel.projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` + - //` on preferred_login_name.user_id = zitadel.projections.users.id` + //` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` + + //` on preferred_login_name.user_id = projections.users.id` userUniqueCols = []string{ "id", "state", @@ -187,43 +189,43 @@ var ( "email", "is_email_verified", } - usersQuery = `SELECT zitadel.projections.users.id,` + - ` zitadel.projections.users.creation_date,` + - ` zitadel.projections.users.change_date,` + - ` zitadel.projections.users.resource_owner,` + - ` zitadel.projections.users.sequence,` + - ` zitadel.projections.users.state,` + - ` zitadel.projections.users.type,` + - ` zitadel.projections.users.username,` + + usersQuery = `SELECT projections.users.id,` + + ` projections.users.creation_date,` + + ` projections.users.change_date,` + + ` projections.users.resource_owner,` + + ` projections.users.sequence,` + + ` projections.users.state,` + + ` projections.users.type,` + + ` projections.users.username,` + ` login_names.loginnames,` + ` preferred_login_name.login_name,` + - ` zitadel.projections.users_humans.user_id,` + - ` zitadel.projections.users_humans.first_name,` + - ` zitadel.projections.users_humans.last_name,` + - ` zitadel.projections.users_humans.nick_name,` + - ` zitadel.projections.users_humans.display_name,` + - ` zitadel.projections.users_humans.preferred_language,` + - ` zitadel.projections.users_humans.gender,` + - ` zitadel.projections.users_humans.avatar_key,` + - ` zitadel.projections.users_humans.email,` + - ` zitadel.projections.users_humans.is_email_verified,` + - ` zitadel.projections.users_humans.phone,` + - ` zitadel.projections.users_humans.is_phone_verified,` + - ` zitadel.projections.users_machines.user_id,` + - ` zitadel.projections.users_machines.name,` + - ` zitadel.projections.users_machines.description,` + + ` projections.users_humans.user_id,` + + ` projections.users_humans.first_name,` + + ` projections.users_humans.last_name,` + + ` projections.users_humans.nick_name,` + + ` projections.users_humans.display_name,` + + ` projections.users_humans.preferred_language,` + + ` projections.users_humans.gender,` + + ` projections.users_humans.avatar_key,` + + ` projections.users_humans.email,` + + ` projections.users_humans.is_email_verified,` + + ` projections.users_humans.phone,` + + ` projections.users_humans.is_phone_verified,` + + ` projections.users_machines.user_id,` + + ` projections.users_machines.name,` + + ` projections.users_machines.description,` + ` COUNT(*) OVER ()` + - ` FROM zitadel.projections.users` + - ` LEFT JOIN zitadel.projections.users_humans ON zitadel.projections.users.id = zitadel.projections.users_humans.user_id` + - ` LEFT JOIN zitadel.projections.users_machines ON zitadel.projections.users.id = zitadel.projections.users_machines.user_id` + + ` FROM projections.users` + + ` LEFT JOIN projections.users_humans ON projections.users.id = projections.users_humans.user_id` + + ` LEFT JOIN projections.users_machines ON projections.users.id = projections.users_machines.user_id` + ` LEFT JOIN` + ` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) as loginnames` + - ` FROM zitadel.projections.login_names as login_names` + + ` FROM projections.login_names as login_names` + ` GROUP BY login_names.user_id) as login_names` + - ` on login_names.user_id = zitadel.projections.users.id` + + ` on login_names.user_id = projections.users.id` + ` LEFT JOIN` + - ` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM zitadel.projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` + - ` on preferred_login_name.user_id = zitadel.projections.users.id` + ` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names as preferred_login_name WHERE preferred_login_name.is_primary = $1) as preferred_login_name` + + ` on preferred_login_name.user_id = projections.users.id` usersCols = []string{ "id", "creation_date", @@ -268,8 +270,10 @@ func Test_UserPrepares(t *testing.T) { object interface{} }{ { - name: "prepareUserQuery no result", - prepare: prepareUserQuery, + name: "prepareUserQuery no result", + prepare: func() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { + return prepareUserQuery("instanceID") + }, want: want{ sqlExpectations: mockQuery( regexp.QuoteMeta(userQuery), @@ -286,8 +290,10 @@ func Test_UserPrepares(t *testing.T) { object: (*User)(nil), }, { - name: "prepareUserQuery human found", - prepare: prepareUserQuery, + name: "prepareUserQuery human found", + prepare: func() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { + return prepareUserQuery("instanceID") + }, want: want{ sqlExpectations: mockQuery( regexp.QuoteMeta(userQuery), @@ -350,8 +356,10 @@ func Test_UserPrepares(t *testing.T) { }, }, { - name: "prepareUserQuery machine found", - prepare: prepareUserQuery, + name: "prepareUserQuery machine found", + prepare: func() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { + return prepareUserQuery("instanceID") + }, want: want{ sqlExpectations: mockQuery( regexp.QuoteMeta(userQuery), @@ -405,8 +413,10 @@ func Test_UserPrepares(t *testing.T) { }, }, { - name: "prepareUserQuery sql err", - prepare: prepareUserQuery, + name: "prepareUserQuery sql err", + prepare: func() (sq.SelectBuilder, func(*sql.Row) (*User, error)) { + return prepareUserQuery("instanceID") + }, want: want{ sqlExpectations: mockQueryErr( regexp.QuoteMeta(userQuery), diff --git a/internal/user/model/refresh_token_view.go b/internal/user/model/refresh_token_view.go index 76688fe8de..9fbd6b01a4 100644 --- a/internal/user/model/refresh_token_view.go +++ b/internal/user/model/refresh_token_view.go @@ -43,6 +43,7 @@ const ( RefreshTokenSearchKeyUserAgentID RefreshTokenSearchKeyExpiration RefreshTokenSearchKeyResourceOwner + RefreshTokenSearchKeyInstanceID ) type RefreshTokenSearchQuery struct { diff --git a/internal/user/model/token_view.go b/internal/user/model/token_view.go index 1cbb9a2e85..3dac7ff35f 100644 --- a/internal/user/model/token_view.go +++ b/internal/user/model/token_view.go @@ -43,6 +43,7 @@ const ( TokenSearchKeyUserAgentID TokenSearchKeyExpiration TokenSearchKeyResourceOwner + TokenSearchKeyInstanceID ) type TokenSearchQuery struct { diff --git a/internal/user/model/user_membership_view.go b/internal/user/model/user_membership_view.go index ed4ce1c523..50bdac7314 100644 --- a/internal/user/model/user_membership_view.go +++ b/internal/user/model/user_membership_view.go @@ -50,6 +50,7 @@ const ( UserMembershipSearchKeyAggregateID UserMembershipSearchKeyObjectID UserMembershipSearchKeyResourceOwner + UserMembershipSearchKeyInstanceID ) type UserMembershipSearchQuery struct { diff --git a/internal/user/model/user_view.go b/internal/user/model/user_view.go index cba130064d..ae249634ec 100644 --- a/internal/user/model/user_view.go +++ b/internal/user/model/user_view.go @@ -100,6 +100,7 @@ const ( UserSearchKeyLoginNames UserSearchKeyType UserSearchKeyPreferredLoginName + UserSearchKeyInstanceID ) type UserSearchQuery struct { diff --git a/internal/user/repository/view/model/external_idps.go b/internal/user/repository/view/model/external_idps.go index 4aa0619ca0..69d91b092d 100644 --- a/internal/user/repository/view/model/external_idps.go +++ b/internal/user/repository/view/model/external_idps.go @@ -2,12 +2,14 @@ package model import ( "encoding/json" + "time" + "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/user/model" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - "time" ) const ( @@ -27,6 +29,7 @@ type ExternalIDPView struct { ChangeDate time.Time `json:"-" gorm:"column:change_date"` ResourceOwner string `json:"-" gorm:"column:resource_owner"` Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func ExternalIDPViewFromModel(externalIDP *model.ExternalIDPView) *ExternalIDPView { @@ -80,6 +83,7 @@ func (i *ExternalIDPView) AppendEvent(event *models.Event) (err error) { func (r *ExternalIDPView) setRootData(event *models.Event) { r.UserID = event.AggregateID r.ResourceOwner = event.ResourceOwner + r.InstanceID = event.InstanceID } func (r *ExternalIDPView) SetData(event *models.Event) error { diff --git a/internal/user/repository/view/model/notify_user.go b/internal/user/repository/view/model/notify_user.go index 586b2684bc..1171c3a943 100644 --- a/internal/user/repository/view/model/notify_user.go +++ b/internal/user/repository/view/model/notify_user.go @@ -42,6 +42,7 @@ type NotifyUser struct { PasswordSet bool `json:"-" gorm:"column:password_set"` Sequence uint64 `json:"-" gorm:"column:sequence"` State int32 `json:"-" gorm:"-"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func NotifyUserFromModel(user *model.NotifyUser) *NotifyUser { @@ -158,6 +159,7 @@ func (u *NotifyUser) AppendEvent(event *models.Event) (err error) { func (u *NotifyUser) setRootData(event *models.Event) { u.ID = event.AggregateID u.ResourceOwner = event.ResourceOwner + u.InstanceID = event.InstanceID } func (u *NotifyUser) setData(event *models.Event) error { diff --git a/internal/user/repository/view/model/refresh_token.go b/internal/user/repository/view/model/refresh_token.go index cad29f5de3..58be9c5926 100644 --- a/internal/user/repository/view/model/refresh_token.go +++ b/internal/user/repository/view/model/refresh_token.go @@ -21,6 +21,7 @@ const ( RefreshTokenKeyUserAgentID = "user_agent_id" RefreshTokenKeyExpiration = "expiration" RefreshTokenKeyResourceOwner = "resource_owner" + RefreshTokenKeyInstanceID = "instance_id" ) type RefreshTokenView struct { @@ -39,6 +40,7 @@ type RefreshTokenView struct { IdleExpiration time.Time `json:"-" gorm:"column:idle_expiration"` Expiration time.Time `json:"-" gorm:"column:expiration"` Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func RefreshTokenViewsToModel(tokens []*RefreshTokenView) []*usr_model.RefreshTokenView { @@ -115,6 +117,7 @@ func (t *RefreshTokenView) AppendEvent(event *es_models.Event) error { func (t *RefreshTokenView) setRootData(event *es_models.Event) { t.UserID = event.AggregateID t.ResourceOwner = event.ResourceOwner + t.InstanceID = event.InstanceID } func (t *RefreshTokenView) appendAddedEvent(event *es_models.Event) error { diff --git a/internal/user/repository/view/model/refresh_token_query.go b/internal/user/repository/view/model/refresh_token_query.go index 0ac1d439db..a363394422 100644 --- a/internal/user/repository/view/model/refresh_token_query.go +++ b/internal/user/repository/view/model/refresh_token_query.go @@ -63,6 +63,8 @@ func (key RefreshTokenSearchKey) ToColumnName() string { return RefreshTokenKeyExpiration case model.RefreshTokenSearchKeyResourceOwner: return RefreshTokenKeyResourceOwner + case model.RefreshTokenSearchKeyInstanceID: + return RefreshTokenKeyInstanceID default: return "" } diff --git a/internal/user/repository/view/model/token.go b/internal/user/repository/view/model/token.go index bddbd6e198..c41e941ace 100644 --- a/internal/user/repository/view/model/token.go +++ b/internal/user/repository/view/model/token.go @@ -23,6 +23,7 @@ const ( TokenKeyUserAgentID = "user_agent_id" TokenKeyExpiration = "expiration" TokenKeyResourceOwner = "resource_owner" + TokenKeyInstanceID = "instance_id" ) type TokenView struct { @@ -41,6 +42,7 @@ type TokenView struct { RefreshTokenID string `json:"refreshTokenID,omitempty" gorm:"refresh_token_id"` IsPAT bool `json:"-" gorm:"is_pat"` Deactivated bool `json:"-" gorm:"-"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func TokenViewToModel(token *TokenView) *usr_model.TokenView { @@ -125,6 +127,7 @@ func (t *TokenView) AppendEvent(event *es_models.Event) error { func (t *TokenView) setRootData(event *es_models.Event) { t.UserID = event.AggregateID t.ResourceOwner = event.ResourceOwner + t.InstanceID = event.InstanceID } func (t *TokenView) setData(event *es_models.Event) error { diff --git a/internal/user/repository/view/model/token_query.go b/internal/user/repository/view/model/token_query.go index 948e262bef..d7b5747616 100644 --- a/internal/user/repository/view/model/token_query.go +++ b/internal/user/repository/view/model/token_query.go @@ -65,6 +65,8 @@ func (key TokenSearchKey) ToColumnName() string { return TokenKeyExpiration case model.TokenSearchKeyResourceOwner: return TokenKeyResourceOwner + case model.TokenSearchKeyInstanceID: + return TokenKeyInstanceID default: return "" } diff --git a/internal/user/repository/view/model/user.go b/internal/user/repository/view/model/user.go index f5ccf7acb7..18b615fc05 100644 --- a/internal/user/repository/view/model/user.go +++ b/internal/user/repository/view/model/user.go @@ -6,9 +6,10 @@ import ( "time" "github.com/caos/logging" - "github.com/caos/zitadel/internal/query" "github.com/lib/pq" + "github.com/caos/zitadel/internal/query" + req_model "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" @@ -32,6 +33,7 @@ const ( UserKeyLoginNames = "login_names" UserKeyPreferredLoginName = "preferred_login_name" UserKeyType = "user_type" + UserKeyInstanceID = "instance_id" ) type userType string @@ -53,6 +55,7 @@ type UserView struct { Sequence uint64 `json:"-" gorm:"column:sequence"` Type userType `json:"-" gorm:"column:user_type"` UserName string `json:"userName" gorm:"column:user_name"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` *MachineView *HumanView } @@ -363,6 +366,7 @@ func (u *UserView) AppendEvent(event *models.Event) (err error) { func (u *UserView) setRootData(event *models.Event) { u.ID = event.AggregateID u.ResourceOwner = event.ResourceOwner + u.InstanceID = event.InstanceID } func (u *UserView) setData(event *models.Event) error { diff --git a/internal/user/repository/view/model/user_membership.go b/internal/user/repository/view/model/user_membership.go index 7d90ea01ad..dc7f853969 100644 --- a/internal/user/repository/view/model/user_membership.go +++ b/internal/user/repository/view/model/user_membership.go @@ -21,6 +21,7 @@ const ( UserMembershipKeyObjectID = "object_id" UserMembershipKeyResourceOwner = "resource_owner" UserMembershipKeyMemberType = "member_type" + UserMembershipKeyInstanceID = "instance_id" ) type UserMembershipView struct { @@ -36,6 +37,7 @@ type UserMembershipView struct { ResourceOwner string `json:"-" gorm:"column:resource_owner"` ResourceOwnerName string `json:"-" gorm:"column:resource_owner_name"` Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func UserMembershipToModel(membership *UserMembershipView) *model.UserMembershipView { @@ -105,6 +107,7 @@ func (u *UserMembershipView) setRootData(event *models.Event, memberType model.M u.ObjectID = event.AggregateID u.ResourceOwner = event.ResourceOwner u.MemberType = int32(memberType) + u.InstanceID = event.InstanceID } func (u *UserMembershipView) setIamMemberData(event *models.Event) error { diff --git a/internal/user/repository/view/model/user_membership_query.go b/internal/user/repository/view/model/user_membership_query.go index 1f9458a00d..0df4784489 100644 --- a/internal/user/repository/view/model/user_membership_query.go +++ b/internal/user/repository/view/model/user_membership_query.go @@ -61,6 +61,9 @@ func (key UserMembershipSearchKey) ToColumnName() string { return UserMembershipKeyAggregateID case usr_model.UserMembershipSearchKeyObjectID: return UserMembershipKeyObjectID + case usr_model.UserMembershipSearchKeyInstanceID: + return UserMembershipKeyInstanceID + default: return "" } diff --git a/internal/user/repository/view/model/user_query.go b/internal/user/repository/view/model/user_query.go index 17d2367ed3..e46dd8986c 100644 --- a/internal/user/repository/view/model/user_query.go +++ b/internal/user/repository/view/model/user_query.go @@ -75,6 +75,8 @@ func (key UserSearchKey) ToColumnName() string { return UserKeyPreferredLoginName case usr_model.UserSearchKeyType: return UserKeyType + case usr_model.UserSearchKeyInstanceID: + return UserKeyInstanceID default: return "" } diff --git a/internal/user/repository/view/model/user_session.go b/internal/user/repository/view/model/user_session.go index 2fa847d0c6..2e0a79cbdf 100644 --- a/internal/user/repository/view/model/user_session.go +++ b/internal/user/repository/view/model/user_session.go @@ -41,6 +41,7 @@ type UserSessionView struct { MultiFactorVerification time.Time `json:"-" gorm:"column:multi_factor_verification"` MultiFactorVerificationType int32 `json:"-" gorm:"column:multi_factor_verification_type"` Sequence uint64 `json:"-" gorm:"column:sequence"` + InstanceID string `json:"instanceID" gorm:"column:instance_id"` } func UserSessionFromEvent(event *models.Event) (*UserSessionView, error) { diff --git a/internal/usergrant/model/user_grant_view.go b/internal/usergrant/model/user_grant_view.go index f285079e4d..4b4cd5857d 100644 --- a/internal/usergrant/model/user_grant_view.go +++ b/internal/usergrant/model/user_grant_view.go @@ -67,6 +67,7 @@ const ( UserGrantSearchKeyProjectName UserGrantSearchKeyDisplayName UserGrantSearchKeyWithGranted + UserGrantSearchKeyInstanceID ) type UserGrantSearchQuery struct { diff --git a/internal/usergrant/repository/view/model/user_grant.go b/internal/usergrant/repository/view/model/user_grant.go index 4f932b7027..724909a6bf 100644 --- a/internal/usergrant/repository/view/model/user_grant.go +++ b/internal/usergrant/repository/view/model/user_grant.go @@ -30,6 +30,7 @@ const ( UserGrantKeyOrgDomain = "org_primary_domain" UserGrantKeyProjectName = "project_name" UserGrantKeyDisplayName = "display_name" + UserGrantKeyInstanceID = "instance_id" ) type UserGrantView struct { diff --git a/internal/usergrant/repository/view/model/user_grant_query.go b/internal/usergrant/repository/view/model/user_grant_query.go index cdb9311072..7292e78944 100644 --- a/internal/usergrant/repository/view/model/user_grant_query.go +++ b/internal/usergrant/repository/view/model/user_grant_query.go @@ -81,6 +81,8 @@ func (key UserGrantSearchKey) ToColumnName() string { return UserGrantKeyProjectName case grant_model.UserGrantSearchKeyDisplayName: return UserGrantKeyDisplayName + case grant_model.UserGrantSearchKeyInstanceID: + return UserGrantKeyInstanceID default: return "" } diff --git a/internal/usergrant/repository/view/user_grant_view.go b/internal/usergrant/repository/view/user_grant_view.go index 27b61ea796..2d8fa5c7b0 100644 --- a/internal/usergrant/repository/view/user_grant_view.go +++ b/internal/usergrant/repository/view/user_grant_view.go @@ -1,17 +1,21 @@ package view import ( + "github.com/jinzhu/gorm" + "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" grant_model "github.com/caos/zitadel/internal/usergrant/model" "github.com/caos/zitadel/internal/usergrant/repository/view/model" "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" ) func UserGrantByID(db *gorm.DB, table, grantID string) (*model.UserGrantView, error) { grant := new(model.UserGrantView) - query := repository.PrepareGetByKey(table, model.UserGrantSearchKey(grant_model.UserGrantSearchKeyID), grantID) + query := repository.PrepareGetByQuery(table, + model.UserGrantSearchQuery{Key: grant_model.UserGrantSearchKeyID, Method: domain.SearchMethodNotEquals, Value: grantID}, + model.UserGrantSearchQuery{Key: grant_model.UserGrantSearchKeyInstanceID, Method: domain.SearchMethodNotEquals, Value: grantID}, + ) err := query(db, grant) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Nqwf1", "Errors.UserGrant.NotFound") diff --git a/migrations/cockroach/V1.0__databases.sql b/migrations/cockroach/V1.0__databases.sql deleted file mode 100644 index 961e64349a..0000000000 --- a/migrations/cockroach/V1.0__databases.sql +++ /dev/null @@ -1,35 +0,0 @@ -CREATE DATABASE management; -CREATE DATABASE auth; -CREATE DATABASE notification; -CREATE DATABASE adminapi; -CREATE DATABASE authz; -CREATE DATABASE eventstore; - - -CREATE USER eventstore WITH PASSWORD ${eventstorepassword}; -GRANT SELECT, INSERT ON DATABASE eventstore TO eventstore; - -CREATE USER management WITH PASSWORD ${managementpassword}; -GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE management TO management; -GRANT SELECT, INSERT ON DATABASE eventstore TO management; - -CREATE USER adminapi WITH PASSWORD ${adminapipassword}; -GRANT SELECT, INSERT, UPDATE, DELETE, DROP ON DATABASE adminapi TO adminapi; -GRANT SELECT, INSERT ON DATABASE eventstore TO adminapi; -GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE auth TO adminapi; -GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE authz TO adminapi; -GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE management TO adminapi; -GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE notification TO adminapi; - -CREATE USER auth WITH PASSWORD ${authpassword}; -GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE auth TO auth; -GRANT SELECT, INSERT ON DATABASE eventstore TO auth; - -CREATE USER notification WITH PASSWORD ${notificationpassword}; -GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE notification TO notification; -GRANT SELECT, INSERT ON DATABASE eventstore TO notification; - -CREATE USER authz WITH PASSWORD ${authzpassword}; -GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE authz TO authz; -GRANT SELECT, INSERT ON DATABASE eventstore TO authz; -GRANT SELECT, INSERT, UPDATE ON DATABASE auth TO authz; diff --git a/migrations/cockroach/V1.100__idp_type.sql b/migrations/cockroach/V1.100__idp_type.sql deleted file mode 100644 index 53f99c953c..0000000000 --- a/migrations/cockroach/V1.100__idp_type.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE zitadel.projections.idps ADD COLUMN type INT2; - --- jwt-type is 2 --- oidc-type is 0 -WITH doa AS ( - SELECT i.id, IF(o.idp_id IS NULL, 0, 2) as type - FROM zitadel.projections.idps i - LEFT JOIN zitadel.projections.idps_oidc_config o - ON o.idp_id = i.id - LEFT JOIN zitadel.projections.idps_jwt_config j - ON j.idp_id = i.id -) -UPDATE zitadel.projections.idps SET type = doa.type FROM doa WHERE doa.id = zitadel.projections.idps.id; diff --git a/migrations/cockroach/V1.101__authn_keys.sql b/migrations/cockroach/V1.101__authn_keys.sql deleted file mode 100644 index 97433b5b1f..0000000000 --- a/migrations/cockroach/V1.101__authn_keys.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE TABLE zitadel.projections.authn_keys( - id STRING - , creation_date TIMESTAMPTZ NOT NULL - , resource_owner STRING NOT NULL - , aggregate_id STRING NOT NULL - , sequence INT8 NOT NULL - - , object_id STRING NOT NULL - , expiration TIMESTAMPTZ NOT NULL - , identifier STRING NOT NULL - , public_key BYTES NOT NULL - , enabled BOOLEAN NOT NULL DEFAULT true - , type INT2 NOT NULL DEFAULT 0 - - , PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.102__event_idx.sql b/migrations/cockroach/V1.102__event_idx.sql deleted file mode 100644 index 2365e48038..0000000000 --- a/migrations/cockroach/V1.102__event_idx.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE INDEX agg_type_seq ON eventstore.events - (aggregate_type, event_sequence DESC) -STORING ( - id - , event_type - , aggregate_id - , aggregate_version - , previous_aggregate_sequence - , creation_date - , event_data - , editor_user - , editor_service - , resource_owner - , previous_aggregate_type_sequence -); \ No newline at end of file diff --git a/migrations/cockroach/V1.103__queries.sql b/migrations/cockroach/V1.103__queries.sql deleted file mode 100644 index 5053c2a7ca..0000000000 --- a/migrations/cockroach/V1.103__queries.sql +++ /dev/null @@ -1,2 +0,0 @@ -GRANT DROP ON DATABASE zitadel TO queries; -GRANT DROP ON TABLE zitadel.projections.* TO queries; diff --git a/migrations/cockroach/V1.104__user_grants.sql b/migrations/cockroach/V1.104__user_grants.sql deleted file mode 100644 index 00902f90f1..0000000000 --- a/migrations/cockroach/V1.104__user_grants.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE zitadel.projections.user_grants ( - id STRING NOT NULL - , resource_owner STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - - , user_id STRING NOT NULL - , project_id STRING NOT NULL - , grant_id STRING NOT NULL - , roles STRING[] - , state INT2 NOT NULL - - , PRIMARY KEY (id) - , INDEX idx_user (user_id) - , INDEX idx_ro (resource_owner) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.105__user_type.sql b/migrations/cockroach/V1.105__user_type.sql deleted file mode 100644 index 01a67b6e46..0000000000 --- a/migrations/cockroach/V1.105__user_type.sql +++ /dev/null @@ -1,15 +0,0 @@ -ALTER TABLE zitadel.projections.users ADD COLUMN type INT2; - --- human is 1 --- machine is 2 -WITH doa AS ( - SELECT u.id, IF(h.user_id IS NULL, 2, 1) as type - FROM zitadel.projections.users u - LEFT JOIN zitadel.projections.users_humans h - ON h.user_id = u.id - LEFT JOIN zitadel.projections.users_machines m - ON m.user_id = u.id -) -UPDATE zitadel.projections.users SET type = doa.type FROM doa WHERE doa.id = zitadel.projections.users.id; - -ALTER TABLE zitadel.projections.users_humans RENAME COLUMN avater_key to avatar_key; diff --git a/migrations/cockroach/V1.106__user_metadata.sql b/migrations/cockroach/V1.106__user_metadata.sql deleted file mode 100644 index 50263dfd20..0000000000 --- a/migrations/cockroach/V1.106__user_metadata.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE zitadel.projections.user_metadata ( - user_id STRING NOT NULL - , resource_owner STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - - , key STRING NOT NULL - , value BYTES - - , PRIMARY KEY (user_id, key) - , INDEX idx_ro (resource_owner) -); diff --git a/migrations/cockroach/V1.107__user_type.sql b/migrations/cockroach/V1.107__user_type.sql deleted file mode 100644 index 60e63de07a..0000000000 --- a/migrations/cockroach/V1.107__user_type.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE zitadel.projections.user_auth_methods ( - token_id STRING NOT NULL - , resource_owner STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - - , user_id STRING NOT NULL - , state INT2 NOT NULL - , method_type INT2 NOT NULL - , name STRING NOT NULL - - , PRIMARY KEY (user_id, method_type, token_id) - , INDEX idx_ro (resource_owner) -); diff --git a/migrations/cockroach/V1.108__iam.sql b/migrations/cockroach/V1.108__iam.sql deleted file mode 100644 index 1095fbb597..0000000000 --- a/migrations/cockroach/V1.108__iam.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE zitadel.projections.iam ( - id STRING NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - - , global_org_id STRING DEFAULT '' - , iam_project_id STRING DEFAULT '' - , setup_started SMALLINT DEFAULT 0 - , setup_done SMALLINT DEFAULT 0 - - , PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.109__features_max_actions.sql b/migrations/cockroach/V1.109__features_max_actions.sql deleted file mode 100644 index c66bed939f..0000000000 --- a/migrations/cockroach/V1.109__features_max_actions.sql +++ /dev/null @@ -1,5 +0,0 @@ -alter table zitadel.projections.features - ADD COLUMN actions_allowed INT2 default 0, - ADD COLUMN max_actions INT8 default 0; - -update zitadel.projections.features set actions_allowed = 2 where actions = true; diff --git a/migrations/cockroach/V1.10__user_machine_keys.sql b/migrations/cockroach/V1.10__user_machine_keys.sql deleted file mode 100644 index 6799937ad4..0000000000 --- a/migrations/cockroach/V1.10__user_machine_keys.sql +++ /dev/null @@ -1,16 +0,0 @@ - -ALTER TABLE management.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING; -ALTER TABLE adminapi.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING; -ALTER TABLE auth.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING; - -CREATE TABLE management.machine_keys ( - id TEXT, - user_id TEXT, - - machine_type SMALLINT, - expiration_date TIMESTAMPTZ, - sequence BIGINT, - creation_date TIMESTAMPTZ, - - PRIMARY KEY (id, user_id) -) diff --git a/migrations/cockroach/V1.110__personal_access_token.sql b/migrations/cockroach/V1.110__personal_access_token.sql deleted file mode 100644 index d9e1f86c5e..0000000000 --- a/migrations/cockroach/V1.110__personal_access_token.sql +++ /dev/null @@ -1,14 +0,0 @@ -ALTER TABLE auth.tokens ADD COLUMN is_pat BOOLEAN DEFAULT false NOT NULL; - -CREATE TABLE zitadel.projections.personal_access_tokens ( - id STRING - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , resource_owner STRING NOT NULL - , sequence INT8 NOT NULL - , user_id STRING NOT NULL - , expiration TIMESTAMPTZ NOT NULL - , scopes STRING[] - - , PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.111__settings.sql b/migrations/cockroach/V1.111__settings.sql deleted file mode 100644 index aa015cd552..0000000000 --- a/migrations/cockroach/V1.111__settings.sql +++ /dev/null @@ -1,64 +0,0 @@ -ALTER TABLE zitadel.projections.iam ADD COLUMN default_language TEXT DEFAULT ''; - -CREATE TABLE zitadel.projections.secret_generators ( - generator_type INT2 NOT NULL - , aggregate_id STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , resource_owner STRING NOT NULL - , sequence INT8 NOT NULL - - , length BIGINT NOT NULL - , expiry BIGINT NOT NULL - , include_lower_letters BOOLEAN NOT NULL - , include_upper_letters BOOLEAN NOT NULL - , include_digits BOOLEAN NOT NULL - , include_symbols BOOLEAN NOT NULL - - , PRIMARY KEY (generator_type, aggregate_id) -); - -CREATE TABLE zitadel.projections.smtp_configs ( - aggregate_id STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , resource_owner STRING NOT NULL - , sequence INT8 NOT NULL - - , tls BOOLEAN NOT NULL - , sender_address STRING NOT NULL - , sender_number STRING NOT NULL - , host STRING NOT NULL - , username STRING NOT NULL DEFAULT '' - , password JSONB - - , PRIMARY KEY (aggregate_id) -); - -CREATE TABLE zitadel.projections.sms_configs ( - id STRING NOT NULL - ,aggregate_id STRING NOT NULL - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , resource_owner STRING NOT NULL - , sequence INT8 NOT NULL - , state INT2 - - , PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.sms_configs_twilio ( - sms_id STRING NOT NULL - ,sid STRING NOT NULL - ,sender_name STRING NOT NULL - ,token JSONB - - , PRIMARY KEY (sms_id) -); - -ALTER TABLE zitadel.projections.login_policies - ADD COLUMN password_check_lifetime BIGINT NOT NULL DEFAULT 0 - , ADD COLUMN external_login_check_lifetime BIGINT NOT NULL DEFAULT 0 - , ADD COLUMN mfa_init_skip_lifetime BIGINT NOT NULL DEFAULT 0 - , ADD COLUMN second_factor_check_lifetime BIGINT NOT NULL DEFAULT 0 - , ADD COLUMN multi_factor_check_lifetime BIGINT NOT NULL DEFAULT 0; diff --git a/migrations/cockroach/V1.11__usermembership.sql b/migrations/cockroach/V1.11__usermembership.sql deleted file mode 100644 index 20bba86942..0000000000 --- a/migrations/cockroach/V1.11__usermembership.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE TABLE auth.user_memberships ( - user_id TEXT, - member_type SMALLINT, - aggregate_id TEXT, - object_id TEXT, - - roles TEXT ARRAY, - display_name TEXT, - resource_owner TEXT, - resource_owner_name TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (user_id, member_type, aggregate_id, object_id) -); - -ALTER TABLE management.user_memberships ADD COLUMN resource_owner_name TEXT; \ No newline at end of file diff --git a/migrations/cockroach/V1.12__machine_keys.sql b/migrations/cockroach/V1.12__machine_keys.sql deleted file mode 100644 index d428bd87c1..0000000000 --- a/migrations/cockroach/V1.12__machine_keys.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE auth.machine_keys ( - id TEXT, - user_id TEXT, - - machine_type SMALLINT, - expiration_date TIMESTAMPTZ, - sequence BIGINT, - creation_date TIMESTAMPTZ, - public_key JSONB, - - PRIMARY KEY (id, user_id) -); - -ALTER TABLE management.machine_keys ADD COLUMN public_key JSONB; \ No newline at end of file diff --git a/migrations/cockroach/V1.13__machine_keys_public.sql b/migrations/cockroach/V1.13__machine_keys_public.sql deleted file mode 100644 index 45f622bc92..0000000000 --- a/migrations/cockroach/V1.13__machine_keys_public.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE management.machine_keys DROP COLUMN IF EXISTS public_key; -ALTER TABLE management.machine_keys ADD COLUMN public_key BYTES; - -ALTER TABLE auth.machine_keys DROP COLUMN IF EXISTS public_key; -ALTER TABLE auth.machine_keys ADD COLUMN public_key BYTES; diff --git a/migrations/cockroach/V1.14__auth_loginpolicy.sql b/migrations/cockroach/V1.14__auth_loginpolicy.sql deleted file mode 100644 index 402dfc8a3d..0000000000 --- a/migrations/cockroach/V1.14__auth_loginpolicy.sql +++ /dev/null @@ -1,104 +0,0 @@ - -ALTER TABLE adminapi.idp_configs ADD COLUMN oidc_idp_display_name_mapping SMALLINT; -ALTER TABLE adminapi.idp_configs ADD COLUMN oidc_idp_username_mapping SMALLINT; - -ALTER TABLE management.idp_configs ADD COLUMN oidc_idp_display_name_mapping SMALLINT; -ALTER TABLE management.idp_configs ADD COLUMN oidc_idp_username_mapping SMALLINT; - -CREATE TABLE auth.idp_configs ( - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - aggregate_id TEXT, - name TEXT, - logo_src BYTES, - idp_state SMALLINT, - idp_provider_type SMALLINT, - - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_client_secret JSONB, - oidc_issuer TEXT, - oidc_scopes TEXT ARRAY, - oidc_idp_display_name_mapping SMALLINT, - oidc_idp_username_mapping SMALLINT, - - PRIMARY KEY (idp_config_id) -); - -CREATE TABLE auth.login_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - login_policy_state SMALLINT, - sequence BIGINT, - - allow_register BOOLEAN, - allow_username_password BOOLEAN, - allow_external_idp BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.idp_providers ( - aggregate_id TEXT, - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - name string, - idp_config_type SMALLINT, - idp_provider_type SMALLINT, - - PRIMARY KEY (aggregate_id, idp_config_id) -); - -CREATE TABLE auth.user_external_idps ( - external_user_id TEXT, - idp_config_id TEXT, - user_id TEXT, - idp_name TEXT, - user_display_name TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - resource_owner TEXT, - - PRIMARY KEY (external_user_id, idp_config_id) -); - -CREATE TABLE management.user_external_idps ( - idp_config_id TEXT, - external_user_id TEXT, - user_id TEXT, - idp_name TEXT, - user_display_name TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - resource_owner TEXT, - - PRIMARY KEY (external_user_id, idp_config_id) -); - -CREATE TABLE adminapi.user_external_idps ( - idp_config_id TEXT, - external_user_id TEXT, - user_id TEXT, - idp_name TEXT, - user_display_name TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - resource_owner TEXT, - - PRIMARY KEY (external_user_id, idp_config_id) -); diff --git a/migrations/cockroach/V1.15__idp_providers.sql b/migrations/cockroach/V1.15__idp_providers.sql deleted file mode 100644 index 4bdbd8fd56..0000000000 --- a/migrations/cockroach/V1.15__idp_providers.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE adminapi.idp_providers ADD COLUMN idp_state SMALLINT; -ALTER TABLE management.idp_providers ADD COLUMN idp_state SMALLINT; -ALTER TABLE auth.idp_providers ADD COLUMN idp_state SMALLINT; diff --git a/migrations/cockroach/V1.16__user_session.sql b/migrations/cockroach/V1.16__user_session.sql deleted file mode 100644 index 913a11561c..0000000000 --- a/migrations/cockroach/V1.16__user_session.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE auth.user_sessions ADD COLUMN external_login_verification TIMESTAMPTZ; -ALTER TABLE auth.user_sessions ADD COLUMN selected_idp_config_id TEXT; diff --git a/migrations/cockroach/V1.17__policies.sql b/migrations/cockroach/V1.17__policies.sql deleted file mode 100644 index 94b6aa40be..0000000000 --- a/migrations/cockroach/V1.17__policies.sql +++ /dev/null @@ -1,173 +0,0 @@ -CREATE TABLE auth.password_complexity_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - complexity_policy_state SMALLINT, - sequence BIGINT, - - min_length BIGINT, - has_lowercase BOOLEAN, - has_uppercase BOOLEAN, - has_symbol BOOLEAN, - has_number BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.password_complexity_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - complexity_policy_state SMALLINT, - sequence BIGINT, - - min_length BIGINT, - has_lowercase BOOLEAN, - has_uppercase BOOLEAN, - has_symbol BOOLEAN, - has_number BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.password_complexity_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - complexity_policy_state SMALLINT, - sequence BIGINT, - - min_length BIGINT, - has_lowercase BOOLEAN, - has_uppercase BOOLEAN, - has_symbol BOOLEAN, - has_number BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.password_age_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - age_policy_state SMALLINT, - sequence BIGINT, - - max_age_days BIGINT, - expire_warn_days BIGINT, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.password_age_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - age_policy_state SMALLINT, - sequence BIGINT, - - max_age_days BIGINT, - expire_warn_days BIGINT, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.password_age_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - age_policy_state SMALLINT, - sequence BIGINT, - - max_age_days BIGINT, - expire_warn_days BIGINT, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.password_lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.password_lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.password_lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.org_iam_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - org_iam_policy_state SMALLINT, - sequence BIGINT, - - user_login_must_be_domain BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.org_iam_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - org_iam_policy_state SMALLINT, - sequence BIGINT, - - user_login_must_be_domain BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.org_iam_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - org_iam_policy_state SMALLINT, - sequence BIGINT, - - user_login_must_be_domain BOOLEAN, - - PRIMARY KEY (aggregate_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.18__scope_projectroles.sql b/migrations/cockroach/V1.18__scope_projectroles.sql deleted file mode 100644 index 0a07159d45..0000000000 --- a/migrations/cockroach/V1.18__scope_projectroles.sql +++ /dev/null @@ -1,40 +0,0 @@ -CREATE TABLE auth.project_roles ( - project_id TEXT, - role_key TEXT, - display_name TEXT, - resource_owner TEXT, - org_id TEXT, - group_name TEXT, - - creation_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (org_id, project_id, role_key) -); - -ALTER TABLE authz.user_grants ADD COLUMN org_primary_domain TEXT; -ALTER TABLE auth.user_grants ADD COLUMN org_primary_domain TEXT; -ALTER TABLE management.user_grants ADD COLUMN org_primary_domain TEXT; - -ALTER TABLE authz.applications ADD COLUMN access_token_type SMALLINT; -ALTER TABLE auth.applications ADD COLUMN access_token_type SMALLINT; -ALTER TABLE management.applications ADD COLUMN access_token_type SMALLINT; - -ALTER TABLE management.projects ADD COLUMN project_role_assertion BOOLEAN; -ALTER TABLE management.projects ADD COLUMN project_role_check BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN project_role_assertion BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN project_role_assertion BOOLEAN; -ALTER TABLE management.applications ADD COLUMN project_role_assertion BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN project_role_check BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN project_role_check BOOLEAN; -ALTER TABLE management.applications ADD COLUMN project_role_check BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN access_token_role_assertion BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN access_token_role_assertion BOOLEAN; -ALTER TABLE management.applications ADD COLUMN access_token_role_assertion BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN id_token_role_assertion BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN id_token_role_assertion BOOLEAN; -ALTER TABLE management.applications ADD COLUMN id_token_role_assertion BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.19__idp_configs.sql b/migrations/cockroach/V1.19__idp_configs.sql deleted file mode 100644 index 24a8cb7561..0000000000 --- a/migrations/cockroach/V1.19__idp_configs.sql +++ /dev/null @@ -1,12 +0,0 @@ -ALTER TABLE management.idp_configs DROP COLUMN logo_src; -ALTER TABLE adminapi.idp_configs DROP COLUMN logo_src; -ALTER TABLE auth.idp_configs DROP COLUMN logo_src; - -ALTER TABLE management.idp_configs ADD COLUMN styling_type SMALLINT; -ALTER TABLE adminapi.idp_configs ADD COLUMN styling_type SMALLINT; -ALTER TABLE auth.idp_configs ADD COLUMN styling_type SMALLINT; - -ALTER TABLE management.idp_providers ADD COLUMN styling_type SMALLINT; -ALTER TABLE adminapi.idp_providers ADD COLUMN styling_type SMALLINT; -ALTER TABLE auth.idp_providers ADD COLUMN styling_type SMALLINT; - diff --git a/migrations/cockroach/V1.1__eventstore.sql b/migrations/cockroach/V1.1__eventstore.sql deleted file mode 100644 index d4a32e205c..0000000000 --- a/migrations/cockroach/V1.1__eventstore.sql +++ /dev/null @@ -1,31 +0,0 @@ - -CREATE SEQUENCE eventstore.event_seq; - -GRANT UPDATE ON TABLE eventstore.event_seq TO management; -GRANT UPDATE ON TABLE eventstore.event_seq TO eventstore; -GRANT UPDATE ON TABLE eventstore.event_seq TO adminapi; -GRANT UPDATE ON TABLE eventstore.event_seq TO auth; -GRANT UPDATE ON TABLE eventstore.event_seq TO authz; -GRANT UPDATE ON TABLE eventstore.event_seq TO notification; - -SET experimental_enable_hash_sharded_indexes = on; - -CREATE TABLE eventstore.events ( - id UUID DEFAULT gen_random_uuid(), - event_type TEXT, - aggregate_type TEXT NOT NULL, - aggregate_id TEXT NOT NULL, - aggregate_version TEXT NOT NULL, - event_sequence BIGINT NOT NULL DEFAULT nextval('eventstore.event_seq'), - previous_sequence BIGINT, - creation_date TIMESTAMPTZ NOT NULL DEFAULT now(), - event_data JSONB, - editor_user TEXT NOT NULL, - editor_service TEXT NOT NULL, - resource_owner TEXT NOT NULL, - - CONSTRAINT event_sequence_pk PRIMARY KEY (event_sequence DESC) USING HASH WITH BUCKET_COUNT = 10, - INDEX agg_type_agg_id (aggregate_type, aggregate_id), - CONSTRAINT previous_sequence_unique UNIQUE (previous_sequence DESC) -); -ALTER SEQUENCE eventstore.event_seq OWNED BY eventstore.events.event_sequence; diff --git a/migrations/cockroach/V1.20__label_policies.sql b/migrations/cockroach/V1.20__label_policies.sql deleted file mode 100644 index 3bbe42a04d..0000000000 --- a/migrations/cockroach/V1.20__label_policies.sql +++ /dev/null @@ -1,31 +0,0 @@ -CREATE TABLE adminapi.label_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - label_policy_state SMALLINT, - sequence BIGINT, - - primary_color TEXT, - secondary_color TEXT, - - PRIMARY KEY (aggregate_id) -); - - -CREATE TABLE management.label_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - label_policy_state SMALLINT, - sequence BIGINT, - - primary_color TEXT, - secondary_color TEXT, - - PRIMARY KEY (aggregate_id) -); - -GRANT SELECT ON TABLE adminapi.label_policies TO notification; -GRANT SELECT ON TABLE management.label_policies TO notification; \ No newline at end of file diff --git a/migrations/cockroach/V1.21__mfa_policy.sql b/migrations/cockroach/V1.21__mfa_policy.sql deleted file mode 100644 index 852beb45e2..0000000000 --- a/migrations/cockroach/V1.21__mfa_policy.sql +++ /dev/null @@ -1,21 +0,0 @@ -ALTER TABLE management.login_policies ADD COLUMN force_mfa BOOLEAN; -ALTER TABLE adminapi.login_policies ADD COLUMN force_mfa BOOLEAN; -ALTER TABLE auth.login_policies ADD COLUMN force_mfa BOOLEAN; - -ALTER TABLE management.login_policies ADD COLUMN second_factors SMALLINT ARRAY; -ALTER TABLE adminapi.login_policies ADD COLUMN second_factors SMALLINT ARRAY; -ALTER TABLE auth.login_policies ADD COLUMN second_factors SMALLINT ARRAY; - -ALTER TABLE management.login_policies ADD COLUMN multi_factors SMALLINT ARRAY; -ALTER TABLE adminapi.login_policies ADD COLUMN multi_factors SMALLINT ARRAY; -ALTER TABLE auth.login_policies ADD COLUMN multi_factors SMALLINT ARRAY; - - -ALTER TABLE auth.user_sessions RENAME COLUMN mfa_software_verification TO second_factor_verification; -ALTER TABLE auth.user_sessions RENAME COLUMN mfa_software_verification_type TO second_factor_verification_type; -ALTER TABLE auth.user_sessions RENAME COLUMN mfa_hardware_verification TO multi_factor_verification; -ALTER TABLE auth.user_sessions RENAME COLUMN mfa_hardware_verification_type TO multi_factor_verification_type; - - - - diff --git a/migrations/cockroach/V1.22__user_grant_owners.sql b/migrations/cockroach/V1.22__user_grant_owners.sql deleted file mode 100644 index 07a11eaa08..0000000000 --- a/migrations/cockroach/V1.22__user_grant_owners.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE management.user_grants ADD COLUMN project_owner STRING; - -ALTER TABLE auth.user_grants ADD COLUMN project_owner STRING; - -ALTER TABLE authz.user_grants ADD COLUMN project_owner STRING; diff --git a/migrations/cockroach/V1.23__application_view.sql b/migrations/cockroach/V1.23__application_view.sql deleted file mode 100644 index 47d87e8f80..0000000000 --- a/migrations/cockroach/V1.23__application_view.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE management.applications ADD COLUMN id_token_userinfo_assertion BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN id_token_userinfo_assertion BOOLEAN; -ALTER TABLE authz.applications ADD COLUMN id_token_userinfo_assertion BOOLEAN; - -ALTER TABLE management.applications ADD COLUMN clock_skew BIGINT; -ALTER TABLE auth.applications ADD COLUMN clock_skew BIGINT; -ALTER TABLE authz.applications ADD COLUMN clock_skew BIGINT; diff --git a/migrations/cockroach/V1.24__current_sequence.sql b/migrations/cockroach/V1.24__current_sequence.sql deleted file mode 100644 index 6d937598f9..0000000000 --- a/migrations/cockroach/V1.24__current_sequence.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE management.current_sequences ADD COLUMN last_successful_spooler_run TIMESTAMPTZ; -ALTER TABLE auth.current_sequences ADD COLUMN last_successful_spooler_run TIMESTAMPTZ; -ALTER TABLE authz.current_sequences ADD COLUMN last_successful_spooler_run TIMESTAMPTZ; -ALTER TABLE adminapi.current_sequences ADD COLUMN last_successful_spooler_run TIMESTAMPTZ; -ALTER TABLE notification.current_sequences ADD COLUMN last_successful_spooler_run TIMESTAMPTZ; - -ALTER TABLE management.current_sequences RENAME COLUMN timestamp TO event_timestamp; -ALTER TABLE auth.current_sequences RENAME COLUMN timestamp TO event_timestamp; -ALTER TABLE authz.current_sequences RENAME COLUMN timestamp TO event_timestamp; -ALTER TABLE adminapi.current_sequences RENAME COLUMN timestamp TO event_timestamp; -ALTER TABLE notification.current_sequences RENAME COLUMN timestamp TO event_timestamp; diff --git a/migrations/cockroach/V1.25__webauthn.sql b/migrations/cockroach/V1.25__webauthn.sql deleted file mode 100644 index 67787c7c1f..0000000000 --- a/migrations/cockroach/V1.25__webauthn.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE management.login_policies ADD COLUMN passwordless_type SMALLINT; -ALTER TABLE adminapi.login_policies ADD COLUMN passwordless_type SMALLINT; -ALTER TABLE auth.login_policies ADD COLUMN passwordless_type SMALLINT; - -ALTER TABLE management.users ADD COLUMN u2f_tokens BYTEA; -ALTER TABLE auth.users ADD COLUMN u2f_tokens BYTEA; -ALTER TABLE adminapi.users ADD COLUMN u2f_tokens BYTEA; - -ALTER TABLE management.users ADD COLUMN passwordless_tokens BYTEA; -ALTER TABLE auth.users ADD COLUMN passwordless_tokens BYTEA; -ALTER TABLE adminapi.users ADD COLUMN passwordless_tokens BYTEA; - -ALTER TABLE auth.user_sessions ADD COLUMN passwordless_verification TIMESTAMPTZ; diff --git a/migrations/cockroach/V1.26__current_sequence_table.sql b/migrations/cockroach/V1.26__current_sequence_table.sql deleted file mode 100644 index 61bf4bb87a..0000000000 --- a/migrations/cockroach/V1.26__current_sequence_table.sql +++ /dev/null @@ -1,21 +0,0 @@ -ALTER TABLE management.current_sequences ADD COLUMN aggregate_type STRING NOT NULL DEFAULT ''; -ALTER TABLE auth.current_sequences ADD COLUMN aggregate_type STRING NOT NULL DEFAULT ''; -ALTER TABLE authz.current_sequences ADD COLUMN aggregate_type STRING NOT NULL DEFAULT ''; -ALTER TABLE adminapi.current_sequences ADD COLUMN aggregate_type STRING NOT NULL DEFAULT ''; -ALTER TABLE notification.current_sequences ADD COLUMN aggregate_type STRING NOT NULL DEFAULT ''; - -BEGIN; - -ALTER TABLE management.current_sequences DROP CONSTRAINT "primary"; -ALTER TABLE auth.current_sequences DROP CONSTRAINT "primary"; -ALTER TABLE authz.current_sequences DROP CONSTRAINT "primary"; -ALTER TABLE adminapi.current_sequences DROP CONSTRAINT "primary"; -ALTER TABLE notification.current_sequences DROP CONSTRAINT "primary"; - -ALTER TABLE management.current_sequences ADD CONSTRAINT "primary" PRIMARY KEY (view_name, aggregate_type); -ALTER TABLE auth.current_sequences ADD CONSTRAINT "primary" PRIMARY KEY (view_name, aggregate_type); -ALTER TABLE authz.current_sequences ADD CONSTRAINT "primary" PRIMARY KEY (view_name, aggregate_type); -ALTER TABLE adminapi.current_sequences ADD CONSTRAINT "primary" PRIMARY KEY (view_name, aggregate_type); -ALTER TABLE notification.current_sequences ADD CONSTRAINT "primary" PRIMARY KEY (view_name, aggregate_type); - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.27__database_and_table_ownership.sql b/migrations/cockroach/V1.27__database_and_table_ownership.sql deleted file mode 100644 index 2d09c39fca..0000000000 --- a/migrations/cockroach/V1.27__database_and_table_ownership.sql +++ /dev/null @@ -1,82 +0,0 @@ -ALTER DATABASE adminapi OWNER TO admin; -ALTER DATABASE auth OWNER TO admin; -ALTER DATABASE authz OWNER TO admin; -ALTER DATABASE eventstore OWNER TO admin; -ALTER DATABASE management OWNER TO admin; -ALTER DATABASE notification OWNER TO admin; -ALTER DATABASE defaultdb OWNER TO admin; -ALTER DATABASE postgres OWNER TO admin; -ALTER TABLE eventstore.events OWNER TO admin; -ALTER TABLE management.locks OWNER TO admin; -ALTER TABLE management.current_sequences OWNER TO admin; -ALTER TABLE management.failed_events OWNER TO admin; -ALTER TABLE management.projects OWNER TO admin; -ALTER TABLE management.project_grants OWNER TO admin; -ALTER TABLE management.project_roles OWNER TO admin; -ALTER TABLE management.project_members OWNER TO admin; -ALTER TABLE management.project_grant_members OWNER TO admin; -ALTER TABLE management.applications OWNER TO admin; -ALTER TABLE management.users OWNER TO admin; -ALTER TABLE management.user_grants OWNER TO admin; -ALTER TABLE management.org_domains OWNER TO admin; -ALTER TABLE auth.locks OWNER TO admin; -ALTER TABLE auth.current_sequences OWNER TO admin; -ALTER TABLE auth.failed_events OWNER TO admin; -ALTER TABLE auth.auth_requests OWNER TO admin; -ALTER TABLE auth.users OWNER TO admin; -ALTER TABLE auth.user_sessions OWNER TO admin; -ALTER TABLE auth.tokens OWNER TO admin; -ALTER TABLE notification.locks OWNER TO admin; -ALTER TABLE notification.current_sequences OWNER TO admin; -ALTER TABLE notification.failed_events OWNER TO admin; -ALTER TABLE notification.notify_users OWNER TO admin; -ALTER TABLE adminapi.orgs OWNER TO admin; -ALTER TABLE adminapi.failed_events OWNER TO admin; -ALTER TABLE adminapi.locks OWNER TO admin; -ALTER TABLE adminapi.current_sequences OWNER TO admin; -ALTER TABLE adminapi.iam_members OWNER TO admin; -ALTER TABLE management.orgs OWNER TO admin; -ALTER TABLE management.org_members OWNER TO admin; -ALTER TABLE auth.keys OWNER TO admin; -ALTER TABLE auth.applications OWNER TO admin; -ALTER TABLE auth.user_grants OWNER TO admin; -ALTER TABLE auth.orgs OWNER TO admin; -ALTER TABLE authz.locks OWNER TO admin; -ALTER TABLE authz.current_sequences OWNER TO admin; -ALTER TABLE authz.failed_events OWNER TO admin; -ALTER TABLE authz.user_grants OWNER TO admin; -ALTER TABLE authz.applications OWNER TO admin; -ALTER TABLE authz.orgs OWNER TO admin; -ALTER TABLE management.user_memberships OWNER TO admin; -ALTER TABLE adminapi.users OWNER TO admin; -ALTER TABLE adminapi.idp_configs OWNER TO admin; -ALTER TABLE management.idp_configs OWNER TO admin; -ALTER TABLE adminapi.login_policies OWNER TO admin; -ALTER TABLE management.login_policies OWNER TO admin; -ALTER TABLE adminapi.idp_providers OWNER TO admin; -ALTER TABLE management.idp_providers OWNER TO admin; -ALTER TABLE management.machine_keys OWNER TO admin; -ALTER TABLE auth.user_memberships OWNER TO admin; -ALTER TABLE auth.machine_keys OWNER TO admin; -ALTER TABLE auth.idp_configs OWNER TO admin; -ALTER TABLE auth.login_policies OWNER TO admin; -ALTER TABLE auth.idp_providers OWNER TO admin; -ALTER TABLE auth.user_external_idps OWNER TO admin; -ALTER TABLE management.user_external_idps OWNER TO admin; -ALTER TABLE adminapi.user_external_idps OWNER TO admin; -ALTER TABLE auth.password_complexity_policies OWNER TO admin; -ALTER TABLE adminapi.password_complexity_policies OWNER TO admin; -ALTER TABLE management.password_complexity_policies OWNER TO admin; -ALTER TABLE auth.password_age_policies OWNER TO admin; -ALTER TABLE adminapi.password_age_policies OWNER TO admin; -ALTER TABLE management.password_age_policies OWNER TO admin; -ALTER TABLE auth.password_lockout_policies OWNER TO admin; -ALTER TABLE adminapi.password_lockout_policies OWNER TO admin; -ALTER TABLE management.password_lockout_policies OWNER TO admin; -ALTER TABLE management.org_iam_policies OWNER TO admin; -ALTER TABLE auth.org_iam_policies OWNER TO admin; -ALTER TABLE adminapi.org_iam_policies OWNER TO admin; -ALTER TABLE auth.project_roles OWNER TO admin; -ALTER TABLE adminapi.label_policies OWNER TO admin; -ALTER TABLE management.label_policies OWNER TO admin; -ALTER TABLE defaultdb.flyway_schema_history OWNER TO admin; diff --git a/migrations/cockroach/V1.28__templates.sql b/migrations/cockroach/V1.28__templates.sql deleted file mode 100644 index c6af0a7d0c..0000000000 --- a/migrations/cockroach/V1.28__templates.sql +++ /dev/null @@ -1,83 +0,0 @@ -CREATE TABLE adminapi.mail_templates ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - mail_template_state SMALLINT, - sequence BIGINT, - - template BYTES, - - PRIMARY KEY (aggregate_id) -); - - -CREATE TABLE management.mail_templates ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - mail_template_state SMALLINT, - sequence BIGINT, - - template BYTES, - - PRIMARY KEY (aggregate_id) -); - -GRANT SELECT ON TABLE adminapi.mail_templates TO notification; -GRANT SELECT ON TABLE management.mail_templates TO notification; - - -CREATE TABLE adminapi.mail_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - mail_text_state SMALLINT, - sequence BIGINT, - - mail_text_type TEXT, - language TEXT, - title TEXT, - pre_header TEXT, - subject TEXT, - greeting TEXT, - text TEXT, - button_text TEXT, - - PRIMARY KEY (aggregate_id, mail_text_type, language) -); - - -CREATE TABLE management.mail_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - mail_text_state SMALLINT, - sequence BIGINT, - - mail_text_type TEXT, - language TEXT, - title TEXT, - pre_header TEXT, - subject TEXT, - greeting TEXT, - text TEXT, - button_text TEXT, - - PRIMARY KEY (aggregate_id, mail_text_type, language) -); - -GRANT SELECT ON TABLE adminapi.mail_texts TO notification; -GRANT SELECT ON TABLE management.mail_texts TO notification; - - -ALTER TABLE management.project_roles ADD COLUMN change_date TIMESTAMPTZ; -ALTER TABLE auth.project_roles ADD COLUMN change_date TIMESTAMPTZ; - -ALTER TABLE management.mail_texts OWNER TO admin; -ALTER TABLE adminapi.mail_texts OWNER TO admin; -ALTER TABLE management.mail_templates OWNER TO admin; -ALTER TABLE adminapi.mail_templates OWNER TO admin; \ No newline at end of file diff --git a/migrations/cockroach/V1.29__user_memberships.sql b/migrations/cockroach/V1.29__user_memberships.sql deleted file mode 100644 index 30d4259ce9..0000000000 --- a/migrations/cockroach/V1.29__user_memberships.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE TABLE authz.user_memberships ( - user_id TEXT, - member_type SMALLINT, - aggregate_id TEXT, - object_id TEXT, - - roles TEXT ARRAY, - display_name TEXT, - resource_owner TEXT, - resource_owner_name TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (user_id, member_type, aggregate_id, object_id) -); - -ALTER TABLE authz.user_memberships OWNER TO admin; \ No newline at end of file diff --git a/migrations/cockroach/V1.2__views.sql b/migrations/cockroach/V1.2__views.sql deleted file mode 100644 index 00fc1d7dc1..0000000000 --- a/migrations/cockroach/V1.2__views.sql +++ /dev/null @@ -1,628 +0,0 @@ -CREATE TABLE management.locks ( - locker_id TEXT, - locked_until TIMESTAMPTZ(3), - view_name TEXT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE management.current_sequences ( - view_name TEXT, - current_sequence BIGINT, - timestamp TIMESTAMPTZ, - - PRIMARY KEY (view_name) -); - -CREATE TABLE management.failed_events ( - view_name TEXT, - failed_sequence BIGINT, - failure_count SMALLINT, - err_msg TEXT, - - PRIMARY KEY (view_name, failed_sequence) -); - -CREATE TABLE management.projects ( - project_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - project_name TEXT, - project_state SMALLINT, - resource_owner TEXT, - sequence BIGINT, - - PRIMARY KEY (project_id) -); - -CREATE TABLE management.project_grants ( - grant_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - project_id TEXT, - project_name TEXT, - org_name TEXT, - project_state SMALLINT, - resource_owner TEXT, - org_id TEXT, - granted_role_keys TEXT Array, - sequence BIGINT, - resource_owner_name TEXT, - - PRIMARY KEY (grant_id) -); - -CREATE TABLE management.project_roles ( - project_id TEXT, - role_key TEXT, - display_name TEXT, - resource_owner TEXT, - org_id TEXT, - group_name TEXT, - - creation_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (org_id, project_id, role_key) -); - -CREATE TABLE management.project_members ( - user_id TEXT, - project_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - user_name TEXT, - email_address TEXT, - first_name TEXT, - last_name TEXT, - roles TEXT ARRAY, - display_name TEXT, - sequence BIGINT, - - PRIMARY KEY (project_id, user_id) -); - -CREATE TABLE management.project_grant_members ( - user_id TEXT, - grant_id TEXT, - project_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - user_name TEXT, - email_address TEXT, - first_name TEXT, - last_name TEXT, - roles TEXT ARRAY, - display_name TEXT, - sequence BIGINT, - - PRIMARY KEY (grant_id, user_id) -); - -CREATE TABLE management.applications ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - app_state SMALLINT, - resource_owner TEXT, - app_name TEXT, - project_id TEXT, - app_type SMALLINT, - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_redirect_uris TEXT ARRAY, - oidc_response_types SMALLINT ARRAY, - oidc_grant_types SMALLINT ARRAY, - oidc_application_type SMALLINT, - oidc_auth_method_type SMALLINT, - oidc_post_logout_redirect_uris TEXT ARRAY, - - PRIMARY KEY (id) -); - -CREATE TABLE management.users ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - user_state SMALLINT, - last_login TIMESTAMPTZ, - password_change TIMESTAMPTZ, - user_name TEXT, - login_names TEXT ARRAY, - preferred_login_name TEXT, - first_name TEXT, - last_name TEXT, - nick_Name TEXT, - display_name TEXT, - preferred_language TEXT, - gender SMALLINT, - email TEXT, - is_email_verified BOOLEAN, - phone TEXT, - is_phone_verified BOOLEAN, - country TEXT, - locality TEXT, - postal_code TEXT, - region TEXT, - street_address TEXT, - otp_state SMALLINT, - sequence BIGINT, - password_set BOOLEAN, - password_change_required BOOLEAN, - mfa_max_set_up SMALLINT, - mfa_init_skipped TIMESTAMPTZ, - init_required BOOLEAN, - - PRIMARY KEY (id) -); - -CREATE TABLE management.user_grants ( - id TEXT, - resource_owner TEXT, - project_id TEXT, - user_id TEXT, - org_name TEXT, - project_name TEXT, - user_name TEXT, - display_name TEXT, - first_name TEXT, - last_name TEXT, - email TEXT, - role_keys TEXT Array, - grant_id TEXT, - - grant_state SMALLINT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (id) -); - -CREATE TABLE management.org_domains ( - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - domain TEXT, - org_id TEXT, - verified BOOLEAN, - primary_domain BOOLEAN, - - PRIMARY KEY (org_id, domain) -); - -CREATE TABLE auth.locks ( - locker_id TEXT, - locked_until TIMESTAMPTZ(3), - view_name TEXT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE auth.current_sequences ( - view_name TEXT, - timestamp TIMESTAMPTZ, - - current_sequence BIGINT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE auth.failed_events ( - view_name TEXT, - failed_sequence BIGINT, - failure_count SMALLINT, - err_msg TEXT, - - PRIMARY KEY (view_name, failed_sequence) -); - -CREATE TABLE auth.auth_requests ( - id TEXT, - request JSONB, - code TEXT, - request_type smallint, - - PRIMARY KEY (id) -); - -CREATE TABLE auth.users ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - user_state SMALLINT, - password_set BOOLEAN, - password_change_required BOOLEAN, - password_change TIMESTAMPTZ, - last_login TIMESTAMPTZ, - user_name TEXT, - login_names TEXT ARRAY, - preferred_login_name TEXT, - first_name TEXT, - last_name TEXT, - nick_name TEXT, - display_name TEXT, - preferred_language TEXT, - gender SMALLINT, - email TEXT, - is_email_verified BOOLEAN, - phone TEXT, - is_phone_verified BOOLEAN, - country TEXT, - locality TEXT, - postal_code TEXT, - region TEXT, - street_address TEXT, - otp_state SMALLINT, - mfa_max_set_up SMALLINT, - mfa_init_skipped TIMESTAMPTZ, - sequence BIGINT, - init_required BOOLEAN, - - PRIMARY KEY (id) -); - -CREATE TABLE auth.user_sessions ( - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - state SMALLINT, - user_agent_id TEXT, - user_id TEXT, - user_name TEXT, - password_verification TIMESTAMPTZ, - mfa_software_verification TIMESTAMPTZ, - mfa_hardware_verification TIMESTAMPTZ, - sequence BIGINT, - mfa_software_verification_type SMALLINT, - mfa_hardware_verification_type SMALLINT, - user_display_name TEXT, - login_name TEXT, - - PRIMARY KEY (user_agent_id, user_id) -); - -CREATE TABLE auth.tokens ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - application_id TEXT, - user_agent_id TEXT, - user_id TEXT, - expiration TIMESTAMPTZ, - sequence BIGINT, - scopes TEXT ARRAY, - audience TEXT ARRAY, - - PRIMARY KEY (id) -); - - -CREATE TABLE notification.locks ( - locker_id TEXT, - locked_until TIMESTAMPTZ(3), - view_name TEXT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE notification.current_sequences ( - view_name TEXT, - timestamp TIMESTAMPTZ, - - current_sequence BIGINT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE notification.failed_events ( - view_name TEXT, - failed_sequence BIGINT, - failure_count SMALLINT, - err_msg TEXT, - - PRIMARY KEY (view_name, failed_sequence) -); - -CREATE TABLE notification.notify_users ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - user_name TEXT, - first_name TEXT, - last_name TEXT, - nick_Name TEXT, - display_name TEXT, - preferred_language TEXT, - gender SMALLINT, - last_email TEXT, - verified_email TEXT, - last_phone TEXT, - verified_phone TEXT, - sequence BIGINT, - password_set BOOLEAN, - login_names TEXT, - preferred_login_name TEXT, - - PRIMARY KEY (id) -); - - -CREATE TABLE adminapi.orgs ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - org_state SMALLINT, - sequence BIGINT, - - domain TEXT, - name TEXT, - - PRIMARY KEY (id) -); - -CREATE TABLE adminapi.failed_events ( - view_name TEXT, - failed_sequence BIGINT, - failure_count SMALLINT, - err_msg TEXT, - - PRIMARY KEY (view_name, failed_sequence) -); - -CREATE TABLE adminapi.locks ( - locker_id TEXT, - locked_until TIMESTAMPTZ(3), - view_name TEXT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE adminapi.current_sequences ( - view_name TEXT, - timestamp TIMESTAMPTZ, - - current_sequence BIGINT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE adminapi.iam_members ( - user_id TEXT, - - iam_id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - user_name TEXT, - email_address TEXT, - first_name TEXT, - last_name TEXT, - roles TEXT ARRAY, - display_name TEXT, - sequence BIGINT, - - PRIMARY KEY (user_id) -); - -CREATE TABLE management.orgs ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - org_state SMALLINT, - sequence BIGINT, - - domain TEXT, - name TEXT, - - PRIMARY KEY (id) -); - -CREATE TABLE management.org_members ( - user_id TEXT, - org_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - user_name TEXT, - email_address TEXT, - first_name TEXT, - last_name TEXT, - roles TEXT ARRAY, - display_name TEXT, - sequence BIGINT, - - PRIMARY KEY (org_id, user_id) -); - - -CREATE TABLE auth.keys ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - private BOOLEAN, - expiry TIMESTAMPTZ, - algorithm TEXT, - usage SMALLINT, - key JSONB, - sequence BIGINT, - - PRIMARY KEY (id, private) -); - -CREATE TABLE auth.applications ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - app_state SMALLINT, - resource_owner TEXT, - app_name TEXT, - project_id TEXT, - app_type SMALLINT, - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_redirect_uris TEXT ARRAY, - oidc_response_types SMALLINT ARRAY, - oidc_grant_types SMALLINT ARRAY, - oidc_application_type SMALLINT, - oidc_auth_method_type SMALLINT, - oidc_post_logout_redirect_uris TEXT ARRAY, - - PRIMARY KEY (id) -); - -CREATE TABLE auth.user_grants ( - id TEXT, - resource_owner TEXT, - project_id TEXT, - user_id TEXT, - org_name TEXT, - project_name TEXT, - user_name TEXT, - first_name TEXT, - last_name TEXT, - display_name TEXT, - email TEXT, - role_keys TEXT Array, - grant_id TEXT, - - grant_state SMALLINT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (id) -); - -CREATE TABLE auth.orgs ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - org_state SMALLINT, - sequence BIGINT, - - domain TEXT, - name TEXT, - - PRIMARY KEY (id) -); - -CREATE TABLE authz.locks ( - locker_id TEXT, - locked_until TIMESTAMPTZ(3), - view_name TEXT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE authz.current_sequences ( - view_name TEXT, - timestamp TIMESTAMPTZ, - - current_sequence BIGINT, - - PRIMARY KEY (view_name) -); - -CREATE TABLE authz.failed_events ( - view_name TEXT, - failed_sequence BIGINT, - failure_count SMALLINT, - err_msg TEXT, - - PRIMARY KEY (view_name, failed_sequence) -); - -CREATE TABLE authz.user_grants ( - id TEXT, - resource_owner TEXT, - project_id TEXT, - user_id TEXT, - org_name TEXT, - project_name TEXT, - user_name TEXT, - first_name TEXT, - last_name TEXT, - display_name TEXT, - email TEXT, - role_keys TEXT Array, - grant_id TEXT, - - grant_state SMALLINT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (id) -); - -CREATE TABLE authz.applications ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - app_state SMALLINT, - resource_owner TEXT, - app_name TEXT, - project_id TEXT, - app_type SMALLINT, - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_redirect_uris TEXT ARRAY, - oidc_response_types SMALLINT ARRAY, - oidc_grant_types SMALLINT ARRAY, - oidc_application_type SMALLINT, - oidc_auth_method_type SMALLINT, - oidc_post_logout_redirect_uris TEXT ARRAY, - - PRIMARY KEY (id) -); - -CREATE TABLE authz.orgs ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - org_state SMALLINT, - sequence BIGINT, - - domain TEXT, - name TEXT, - - PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.30__user_memberships.sql b/migrations/cockroach/V1.30__user_memberships.sql deleted file mode 100644 index 82146e0f18..0000000000 --- a/migrations/cockroach/V1.30__user_memberships.sql +++ /dev/null @@ -1,47 +0,0 @@ -BEGIN; - -TRUNCATE TABLE authz.user_memberships; - -INSERT INTO authz.user_memberships ( - user_id, - member_type, - aggregate_id, - object_id, - roles, - display_name, - resource_owner, - resource_owner_name, - creation_date, - change_date, - sequence -) -SELECT - user_id, - member_type, - aggregate_id, - object_id, - roles, - display_name, - resource_owner, - resource_owner_name, - creation_date, - change_date, - sequence -FROM auth.user_memberships; - -UPSERT INTO authz.current_sequences ( - view_name, - event_timestamp, - current_sequence, - last_successful_spooler_run, - aggregate_type - ) -SELECT 'authz.user_memberships', - event_timestamp, - current_sequence, - last_successful_spooler_run, - aggregate_type -FROM auth.current_sequences -WHERE view_name = 'auth.user_memberships'; - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.31__auth_keys.sql b/migrations/cockroach/V1.31__auth_keys.sql deleted file mode 100644 index 5c091d1b50..0000000000 --- a/migrations/cockroach/V1.31__auth_keys.sql +++ /dev/null @@ -1,92 +0,0 @@ -CREATE TABLE auth.authn_keys -( - key_id TEXT, - object_id TEXT, - object_type SMALLINT, - auth_identifier TEXT, - - key_type SMALLINT, - sequence BIGINT, - expiration_date TIMESTAMPTZ, - creation_date TIMESTAMPTZ, - public_key BYTES, - state SMALLINT, - - PRIMARY KEY (key_id, object_id, object_type, auth_identifier) -); - -INSERT INTO auth.authn_keys ( - key_id, - object_id, - object_type, - auth_identifier, - key_type, - sequence, - expiration_date, - creation_date, - public_key, - state - ) - SELECT - id, - user_id, - 0, - user_id, - machine_type, - sequence, - expiration_date, - creation_date, - public_key, - 0 - FROM auth.machine_keys; - -CREATE TABLE management.authn_keys -( - key_id TEXT, - object_id TEXT, - object_type SMALLINT, - auth_identifier TEXT, - - key_type SMALLINT, - sequence BIGINT, - expiration_date TIMESTAMPTZ, - creation_date TIMESTAMPTZ, - public_key BYTES, - state SMALLINT, - - PRIMARY KEY (key_id, object_id, object_type, auth_identifier) -); - -INSERT INTO management.authn_keys ( - key_id, - object_id, - object_type, - auth_identifier, - key_type, - sequence, - expiration_date, - creation_date, - public_key, - state -) -SELECT - id, - user_id, - 0, - user_id, - machine_type, - sequence, - expiration_date, - creation_date, - public_key, - 0 -FROM management.machine_keys; - -INSERT INTO auth.current_sequences (view_name, event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type) - SELECT 'auth.authn_keys', event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type FROM auth.current_sequences WHERE view_name = 'auth.machine_keys'; - -INSERT INTO management.current_sequences (view_name, event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type) - SELECT 'management.authn_keys', event_timestamp, current_sequence, last_successful_spooler_run, aggregate_type FROM management.current_sequences WHERE view_name = 'management.machine_keys'; - -ALTER TABLE auth.authn_keys OWNER TO admin; -ALTER TABLE management.authn_keys OWNER TO admin; diff --git a/migrations/cockroach/V1.32__auth_keys_type.sql b/migrations/cockroach/V1.32__auth_keys_type.sql deleted file mode 100644 index 057426d5f8..0000000000 --- a/migrations/cockroach/V1.32__auth_keys_type.sql +++ /dev/null @@ -1,6 +0,0 @@ -BEGIN; - -UPDATE auth.authn_keys SET object_type = 1 where object_type = 0; -UPDATE management.authn_keys SET object_type = 1 where object_type = 0; - -COMMIT; diff --git a/migrations/cockroach/V1.33__label_policy.sql b/migrations/cockroach/V1.33__label_policy.sql deleted file mode 100644 index 4c6645a698..0000000000 --- a/migrations/cockroach/V1.33__label_policy.sql +++ /dev/null @@ -1,21 +0,0 @@ - -ALTER TABLE management.label_policies ADD COLUMN hide_login_name_suffix BOOLEAN; -ALTER TABLE adminapi.label_policies ADD COLUMN hide_login_name_suffix BOOLEAN; - - -CREATE TABLE auth.label_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - label_policy_state SMALLINT, - sequence BIGINT, - - primary_color TEXT, - secondary_color TEXT, - hide_login_name_suffix BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -GRANT SELECT ON TABLE auth.label_policies TO notification; \ No newline at end of file diff --git a/migrations/cockroach/V1.34__new_eventstore.sql b/migrations/cockroach/V1.34__new_eventstore.sql deleted file mode 100644 index 3eb08883e0..0000000000 --- a/migrations/cockroach/V1.34__new_eventstore.sql +++ /dev/null @@ -1,23 +0,0 @@ -CREATE TABLE eventstore.unique_constraints ( - unique_type TEXT, - unique_field TEXT, - PRIMARY KEY (unique_type, unique_field) -); - -GRANT DELETE ON TABLE eventstore.unique_constraints to eventstore; - -ALTER TABLE management.login_policies ADD COLUMN default_policy BOOLEAN; -ALTER TABLE adminapi.login_policies ADD COLUMN default_policy BOOLEAN; -ALTER TABLE auth.login_policies ADD COLUMN default_policy BOOLEAN; - -CREATE INDEX event_type ON eventstore.events (event_type); -CREATE INDEX resource_owner ON eventstore.events (resource_owner); - -CREATE USER queries WITH PASSWORD ${queriespassword}; -GRANT SELECT ON TABLE eventstore.events TO queries; - -ALTER TABLE management.org_members ADD COLUMN preferred_login_name TEXT; -ALTER TABLE management.project_members ADD COLUMN preferred_login_name TEXT; -ALTER TABLE management.project_grant_members ADD COLUMN preferred_login_name TEXT; - -ALTER TABLE adminapi.iam_members ADD COLUMN preferred_login_name TEXT; diff --git a/migrations/cockroach/V1.35__features.sql b/migrations/cockroach/V1.35__features.sql deleted file mode 100644 index de4ce57368..0000000000 --- a/migrations/cockroach/V1.35__features.sql +++ /dev/null @@ -1,103 +0,0 @@ -CREATE TABLE adminapi.features -( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - default_features BOOLEAN, - - tier_name TEXT, - tier_description TEXT, - state SMALLINT, - state_description TEXT, - - audit_log_retention BIGINT, - login_policy_factors BOOLEAN, - login_policy_idp BOOLEAN, - login_policy_passwordless BOOLEAN, - login_policy_registration BOOLEAN, - login_policy_username_login BOOLEAN, - password_complexity_policy BOOLEAN, - label_policy BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.features -( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - default_features BOOLEAN, - - tier_name TEXT, - tier_description TEXT, - state SMALLINT, - state_description TEXT, - - audit_log_retention BIGINT, - login_policy_factors BOOLEAN, - login_policy_idp BOOLEAN, - login_policy_passwordless BOOLEAN, - login_policy_registration BOOLEAN, - login_policy_username_login BOOLEAN, - password_complexity_policy BOOLEAN, - label_policy BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE authz.features -( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - default_features BOOLEAN, - - tier_name TEXT, - tier_description TEXT, - state SMALLINT, - state_description TEXT, - - audit_log_retention BIGINT, - login_policy_factors BOOLEAN, - login_policy_idp BOOLEAN, - login_policy_passwordless BOOLEAN, - login_policy_registration BOOLEAN, - login_policy_username_login BOOLEAN, - password_complexity_policy BOOLEAN, - label_policy BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.features -( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - default_features BOOLEAN, - - tier_name TEXT, - tier_description TEXT, - state SMALLINT, - state_description TEXT, - - audit_log_retention BIGINT, - login_policy_factors BOOLEAN, - login_policy_idp BOOLEAN, - login_policy_passwordless BOOLEAN, - login_policy_registration BOOLEAN, - login_policy_username_login BOOLEAN, - password_complexity_policy BOOLEAN, - label_policy BOOLEAN, - - PRIMARY KEY (aggregate_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.36__cleanup_resource_owners.sql b/migrations/cockroach/V1.36__cleanup_resource_owners.sql deleted file mode 100644 index eea726f9e7..0000000000 --- a/migrations/cockroach/V1.36__cleanup_resource_owners.sql +++ /dev/null @@ -1,46 +0,0 @@ -WITH resource_owners AS ( - WITH first_sequences AS ( - WITH duplicates AS ( - select - aggregate_id, - aggregate_type - from ( - select - aggregate_type, - aggregate_id, - resource_owner - from eventstore.events - where aggregate_type not like '%.%' - group by - aggregate_type, - aggregate_id, - resource_owner - ) group by - aggregate_id, - aggregate_type - having count(resource_owner) > 1 - ) - SELECT - MIN(event_sequence) AS seq, - aggregate_type, - aggregate_id - FROM - eventstore.events - WHERE - aggregate_id IN (select aggregate_id from duplicates) - GROUP BY - aggregate_type, - aggregate_id - ORDER BY aggregate_id, seq - ) - SELECT - f.*, - e.resource_owner - FROM - first_sequences f - JOIN - eventstore.events e ON f.seq = e.event_sequence -) -UPDATE eventstore.events e -SET resource_owner = r.resource_owner -FROM resource_owners r where e.aggregate_id = r.aggregate_id; diff --git a/migrations/cockroach/V1.37__current_sequence_table.sql b/migrations/cockroach/V1.37__current_sequence_table.sql deleted file mode 100644 index 875713dab2..0000000000 --- a/migrations/cockroach/V1.37__current_sequence_table.sql +++ /dev/null @@ -1,17 +0,0 @@ -DELETE FROM management.current_sequences WHERE aggregate_type <> ''; -DELETE FROM auth.current_sequences WHERE aggregate_type <> ''; -DELETE FROM authz.current_sequences WHERE aggregate_type <> ''; -DELETE FROM adminapi.current_sequences WHERE aggregate_type <> ''; -DELETE FROM notification.current_sequences WHERE aggregate_type <> ''; - -ALTER TABLE management.current_sequences ALTER PRIMARY KEY USING COLUMNS(view_name); -ALTER TABLE auth.current_sequences ALTER PRIMARY KEY USING COLUMNS(view_name); -ALTER TABLE authz.current_sequences ALTER PRIMARY KEY USING COLUMNS(view_name); -ALTER TABLE adminapi.current_sequences ALTER PRIMARY KEY USING COLUMNS(view_name); -ALTER TABLE notification.current_sequences ALTER PRIMARY KEY USING COLUMNS(view_name); - -ALTER TABLE management.current_sequences DROP COLUMN aggregate_type; -ALTER TABLE auth.current_sequences DROP COLUMN aggregate_type; -ALTER TABLE authz.current_sequences DROP COLUMN aggregate_type; -ALTER TABLE adminapi.current_sequences DROP COLUMN aggregate_type; -ALTER TABLE notification.current_sequences DROP COLUMN aggregate_type; diff --git a/migrations/cockroach/V1.38__reset_login_policies.sql b/migrations/cockroach/V1.38__reset_login_policies.sql deleted file mode 100644 index 0e4055d436..0000000000 --- a/migrations/cockroach/V1.38__reset_login_policies.sql +++ /dev/null @@ -1,9 +0,0 @@ -BEGIN; - -TRUNCATE auth.login_policies; -TRUNCATE management.login_policies; - -UPDATE auth.current_sequences set current_sequence = 0 where view_name = 'auth.login_policies'; -UPDATE management.current_sequences set current_sequence = 0 where view_name = 'management.login_policies'; - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.39__feature_custom_domain.sql b/migrations/cockroach/V1.39__feature_custom_domain.sql deleted file mode 100644 index 0953471160..0000000000 --- a/migrations/cockroach/V1.39__feature_custom_domain.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN custom_domain BOOLEAN; -ALTER TABLE auth.features ADD COLUMN custom_domain BOOLEAN; -ALTER TABLE authz.features ADD COLUMN custom_domain BOOLEAN; -ALTER TABLE management.features ADD COLUMN custom_domain BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.3__usermembership.sql b/migrations/cockroach/V1.3__usermembership.sql deleted file mode 100644 index a750219095..0000000000 --- a/migrations/cockroach/V1.3__usermembership.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE management.user_memberships ( - user_id TEXT, - member_type SMALLINT, - aggregate_id TEXT, - object_id TEXT, - - roles TEXT ARRAY, - display_name TEXT, - resource_owner TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (user_id, member_type, aggregate_id, object_id) -); diff --git a/migrations/cockroach/V1.40__indexes.sql b/migrations/cockroach/V1.40__indexes.sql deleted file mode 100644 index 8f4edf41f2..0000000000 --- a/migrations/cockroach/V1.40__indexes.sql +++ /dev/null @@ -1,7 +0,0 @@ -use auth; -CREATE INDEX IF NOT EXISTS auth_code on auth.auth_requests (code); - -use eventstore; -CREATE INDEX IF NOT EXISTS default_event_query on eventstore.events (aggregate_type, aggregate_id, event_type, resource_owner); -DROP INDEX IF EXISTS event_type; -DROP INDEX IF EXISTS resource_owner; \ No newline at end of file diff --git a/migrations/cockroach/V1.41__index_max_seq.sql b/migrations/cockroach/V1.41__index_max_seq.sql deleted file mode 100644 index ce6916592c..0000000000 --- a/migrations/cockroach/V1.41__index_max_seq.sql +++ /dev/null @@ -1,2 +0,0 @@ -use eventstore; -CREATE INDEX IF NOT EXISTS max_sequence on eventstore.events (aggregate_type, aggregate_id, event_sequence DESC); diff --git a/migrations/cockroach/V1.42__assets.sql b/migrations/cockroach/V1.42__assets.sql deleted file mode 100644 index 7f865c327e..0000000000 --- a/migrations/cockroach/V1.42__assets.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE eventstore.assets ( - id TEXT, - asset TEXT, - PRIMARY KEY (id) -); - -GRANT DELETE ON TABLE eventstore.assets to eventstore; diff --git a/migrations/cockroach/V1.43__additional_origins.sql b/migrations/cockroach/V1.43__additional_origins.sql deleted file mode 100644 index 0aac4c4749..0000000000 --- a/migrations/cockroach/V1.43__additional_origins.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE auth.applications ADD COLUMN additional_origins TEXT ARRAY; -ALTER TABLE authz.applications ADD COLUMN additional_origins TEXT ARRAY; -ALTER TABLE management.applications ADD COLUMN additional_origins TEXT ARRAY; \ No newline at end of file diff --git a/migrations/cockroach/V1.44__refresh_tokens.sql b/migrations/cockroach/V1.44__refresh_tokens.sql deleted file mode 100644 index 0227d12f30..0000000000 --- a/migrations/cockroach/V1.44__refresh_tokens.sql +++ /dev/null @@ -1,21 +0,0 @@ -CREATE TABLE auth.refresh_tokens ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - token TEXT, - client_id TEXT, - user_agent_id TEXT, - user_id TEXT, - auth_time TIMESTAMPTZ, - idle_expiration TIMESTAMPTZ, - expiration TIMESTAMPTZ, - sequence BIGINT, - scopes TEXT ARRAY, - audience TEXT ARRAY, - amr TEXT ARRAY, - - PRIMARY KEY (client_id, user_agent_id, user_id) -); diff --git a/migrations/cockroach/V1.45__refresh_tokens.sql b/migrations/cockroach/V1.45__refresh_tokens.sql deleted file mode 100644 index 9097112b2a..0000000000 --- a/migrations/cockroach/V1.45__refresh_tokens.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE auth.refresh_tokens ALTER COLUMN id SET NOT NULL; -ALTER TABLE auth.refresh_tokens ALTER PRIMARY KEY USING COLUMNS(id); \ No newline at end of file diff --git a/migrations/cockroach/V1.46__password_reset.sql b/migrations/cockroach/V1.46__password_reset.sql deleted file mode 100644 index 48c9746466..0000000000 --- a/migrations/cockroach/V1.46__password_reset.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN login_policy_password_reset BOOLEAN; -ALTER TABLE auth.features ADD COLUMN login_policy_password_reset BOOLEAN; -ALTER TABLE authz.features ADD COLUMN login_policy_password_reset BOOLEAN; -ALTER TABLE management.features ADD COLUMN login_policy_password_reset BOOLEAN; - - -ALTER TABLE auth.login_policies ADD COLUMN hide_password_reset BOOLEAN; -ALTER TABLE adminapi.login_policies ADD COLUMN hide_password_reset BOOLEAN; -ALTER TABLE management.login_policies ADD COLUMN hide_password_reset BOOLEAN; diff --git a/migrations/cockroach/V1.47__label_policy.sql b/migrations/cockroach/V1.47__label_policy.sql deleted file mode 100644 index a3f8ec5a08..0000000000 --- a/migrations/cockroach/V1.47__label_policy.sql +++ /dev/null @@ -1,105 +0,0 @@ -ALTER TABLE management.label_policies ALTER COLUMN label_policy_state SET DEFAULT 0; -ALTER TABLE management.label_policies ALTER COLUMN label_policy_state SET NOT NULL; -ALTER TABLE management.label_policies RENAME COLUMN secondary_color TO background_color; -ALTER TABLE management.label_policies ADD COLUMN warn_color TEXT; -ALTER TABLE management.label_policies ADD COLUMN font_color TEXT; -ALTER TABLE management.label_policies ADD COLUMN primary_color_dark TEXT; -ALTER TABLE management.label_policies ADD COLUMN background_color_dark TEXT; -ALTER TABLE management.label_policies ADD COLUMN warn_color_dark TEXT; -ALTER TABLE management.label_policies ADD COLUMN font_color_dark TEXT; -ALTER TABLE management.label_policies ADD COLUMN logo_url TEXT; -ALTER TABLE management.label_policies ADD COLUMN icon_url TEXT; -ALTER TABLE management.label_policies ADD COLUMN logo_dark_url TEXT; -ALTER TABLE management.label_policies ADD COLUMN icon_dark_url TEXT; -ALTER TABLE management.label_policies ADD COLUMN font_url TEXT; -ALTER TABLE management.label_policies ADD COLUMN err_msg_popup BOOLEAN; -ALTER TABLE management.label_policies ADD COLUMN disable_watermark BOOLEAN; - -ALTER TABLE adminapi.label_policies ALTER COLUMN label_policy_state SET DEFAULT 0; -ALTER TABLE adminapi.label_policies ALTER COLUMN label_policy_state SET NOT NULL; -ALTER TABLE adminapi.label_policies RENAME COLUMN secondary_color TO background_color; -ALTER TABLE adminapi.label_policies ADD COLUMN warn_color TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN font_color TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN primary_color_dark TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN background_color_dark TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN warn_color_dark TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN font_color_dark TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN logo_url TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN icon_url TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN logo_dark_url TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN icon_dark_url TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN font_url TEXT; -ALTER TABLE adminapi.label_policies ADD COLUMN err_msg_popup BOOLEAN; -ALTER TABLE adminapi.label_policies ADD COLUMN disable_watermark BOOLEAN; - -ALTER TABLE auth.label_policies ALTER COLUMN label_policy_state SET DEFAULT 0; -ALTER TABLE auth.label_policies ALTER COLUMN label_policy_state SET NOT NULL; -ALTER TABLE auth.label_policies RENAME COLUMN secondary_color TO background_color; -ALTER TABLE auth.label_policies ADD COLUMN warn_color TEXT; -ALTER TABLE auth.label_policies ADD COLUMN font_color TEXT; -ALTER TABLE auth.label_policies ADD COLUMN primary_color_dark TEXT; -ALTER TABLE auth.label_policies ADD COLUMN background_color_dark TEXT; -ALTER TABLE auth.label_policies ADD COLUMN warn_color_dark TEXT; -ALTER TABLE auth.label_policies ADD COLUMN font_color_dark TEXT; -ALTER TABLE auth.label_policies ADD COLUMN logo_url TEXT; -ALTER TABLE auth.label_policies ADD COLUMN icon_url TEXT; -ALTER TABLE auth.label_policies ADD COLUMN logo_dark_url TEXT; -ALTER TABLE auth.label_policies ADD COLUMN icon_dark_url TEXT; -ALTER TABLE auth.label_policies ADD COLUMN font_url TEXT; -ALTER TABLE auth.label_policies ADD COLUMN err_msg_popup BOOLEAN; -ALTER TABLE auth.label_policies ADD COLUMN disable_watermark BOOLEAN; - - -BEGIN; -ALTER TABLE management.label_policies DROP CONSTRAINT "primary"; -ALTER TABLE management.label_policies ADD CONSTRAINT "primary" PRIMARY KEY (aggregate_id, label_policy_state); -ALTER TABLE adminapi.label_policies DROP CONSTRAINT "primary"; -ALTER TABLE adminapi.label_policies ADD CONSTRAINT "primary" PRIMARY KEY (aggregate_id, label_policy_state); -ALTER TABLE auth.label_policies DROP CONSTRAINT "primary"; -ALTER TABLE auth.label_policies ADD CONSTRAINT "primary" PRIMARY KEY (aggregate_id, label_policy_state); -COMMIT; - - -ALTER TABLE management.users ADD COLUMN avatar_key TEXT; -ALTER TABLE auth.users ADD COLUMN avatar_key TEXT; -ALTER TABLE adminapi.users ADD COLUMN avatar_key TEXT; - -ALTER TABLE auth.user_sessions ADD COLUMN avatar_key TEXT; - -CREATE TABLE adminapi.styling ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - label_policy_state SMALLINT NOT NULL DEFAULT 0, - sequence BIGINT, - - primary_color TEXT, - background_color TEXT, - warn_color TEXT, - font_color TEXT, - primary_color_dark TEXT, - background_color_dark TEXT, - warn_color_dark TEXT, - font_color_dark TEXT, - logo_url TEXT, - icon_url TEXT, - logo_dark_url TEXT, - icon_dark_url TEXT, - font_url TEXT, - - err_msg_popup BOOLEAN, - disable_watermark BOOLEAN, - hide_login_name_suffix BOOLEAN, - - PRIMARY KEY (aggregate_id, label_policy_state) -); - -ALTER TABLE adminapi.features RENAME COLUMN label_policy TO label_policy_private_label; -ALTER TABLE adminapi.features ADD COLUMN label_policy_watermark BOOLEAN; -ALTER TABLE auth.features RENAME COLUMN label_policy TO label_policy_private_label; -ALTER TABLE auth.features ADD COLUMN label_policy_watermark BOOLEAN; -ALTER TABLE authz.features RENAME COLUMN label_policy TO label_policy_private_label; -ALTER TABLE authz.features ADD COLUMN label_policy_watermark BOOLEAN; -ALTER TABLE management.features RENAME COLUMN label_policy TO label_policy_private_label; -ALTER TABLE management.features ADD COLUMN label_policy_watermark BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.48__custom_text.sql b/migrations/cockroach/V1.48__custom_text.sql deleted file mode 100644 index 756b638a88..0000000000 --- a/migrations/cockroach/V1.48__custom_text.sql +++ /dev/null @@ -1,53 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN custom_text BOOLEAN; -ALTER TABLE auth.features ADD COLUMN custom_text BOOLEAN; -ALTER TABLE authz.features ADD COLUMN custom_text BOOLEAN; -ALTER TABLE management.features ADD COLUMN custom_text BOOLEAN; - -CREATE TABLE adminapi.message_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - message_text_state SMALLINT, - sequence BIGINT, - - message_text_type TEXT, - language TEXT, - title TEXT, - pre_header TEXT, - subject TEXT, - greeting TEXT, - text TEXT, - button_text TEXT, - footer_text TEXT, - - PRIMARY KEY (aggregate_id, message_text_type, language) -); - - -CREATE TABLE management.message_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - message_text_state SMALLINT, - sequence BIGINT, - - message_text_type TEXT, - language TEXT, - title TEXT, - pre_header TEXT, - subject TEXT, - greeting TEXT, - text TEXT, - button_text TEXT, - footer_text TEXT, - - PRIMARY KEY (aggregate_id, message_text_type, language) -); - -GRANT SELECT ON TABLE adminapi.message_texts TO notification; -GRANT SELECT ON TABLE management.message_texts TO notification; -ALTER TABLE management.message_texts OWNER TO admin; -ALTER TABLE adminapi.message_texts OWNER TO admin; - diff --git a/migrations/cockroach/V1.49__avatar.sql b/migrations/cockroach/V1.49__avatar.sql deleted file mode 100644 index c734e5ade8..0000000000 --- a/migrations/cockroach/V1.49__avatar.sql +++ /dev/null @@ -1,16 +0,0 @@ -ALTER TABLE adminapi.iam_members ADD COLUMN avatar_key TEXT; -ALTER TABLE auth.user_grants ADD COLUMN avatar_key TEXT; -ALTER TABLE authz.user_grants ADD COLUMN avatar_key TEXT; -ALTER TABLE management.org_members ADD COLUMN avatar_key TEXT; -ALTER TABLE management.project_members ADD COLUMN avatar_key TEXT; -ALTER TABLE management.project_grant_members ADD COLUMN avatar_key TEXT; -ALTER TABLE management.user_grants ADD COLUMN avatar_key TEXT; - -ALTER TABLE adminapi.iam_members ADD COLUMN user_resource_owner TEXT; -ALTER TABLE management.org_members ADD COLUMN user_resource_owner TEXT; -ALTER TABLE management.project_members ADD COLUMN user_resource_owner TEXT; -ALTER TABLE management.project_grant_members ADD COLUMN user_resource_owner TEXT; - -ALTER TABLE auth.user_grants ADD COLUMN user_resource_owner TEXT; -ALTER TABLE authz.user_grants ADD COLUMN user_resource_owner TEXT; -ALTER TABLE management.user_grants ADD COLUMN user_resource_owner TEXT; \ No newline at end of file diff --git a/migrations/cockroach/V1.4__compliance.sql b/migrations/cockroach/V1.4__compliance.sql deleted file mode 100644 index cec2e77ede..0000000000 --- a/migrations/cockroach/V1.4__compliance.sql +++ /dev/null @@ -1,18 +0,0 @@ -BEGIN; - -ALTER TABLE management.applications ADD COLUMN oidc_version SMALLINT; -ALTER TABLE management.applications ADD COLUMN none_compliant BOOLEAN; -ALTER TABLE management.applications ADD COLUMN compliance_problems TEXT ARRAY; -ALTER TABLE management.applications ADD COLUMN dev_mode BOOLEAN; - -ALTER TABLE auth.applications ADD COLUMN oidc_version SMALLINT; -ALTER TABLE auth.applications ADD COLUMN none_compliant BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN compliance_problems TEXT ARRAY; -ALTER TABLE auth.applications ADD COLUMN dev_mode BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN oidc_version SMALLINT; -ALTER TABLE authz.applications ADD COLUMN none_compliant BOOLEAN; -ALTER TABLE authz.applications ADD COLUMN compliance_problems TEXT ARRAY; -ALTER TABLE authz.applications ADD COLUMN dev_mode BOOLEAN; - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.50__changes_idx.sql b/migrations/cockroach/V1.50__changes_idx.sql deleted file mode 100644 index 307041c4af..0000000000 --- a/migrations/cockroach/V1.50__changes_idx.sql +++ /dev/null @@ -1,6 +0,0 @@ -BEGIN; - -SET experimental_enable_hash_sharded_indexes=on; -CREATE INDEX changes_idx ON eventstore.events (aggregate_type, aggregate_id, creation_date) USING HASH WITH BUCKET_COUNT = 10; - -COMMIT; diff --git a/migrations/cockroach/V1.51__drop_changes_idx.sql b/migrations/cockroach/V1.51__drop_changes_idx.sql deleted file mode 100644 index 5ecbb742ab..0000000000 --- a/migrations/cockroach/V1.51__drop_changes_idx.sql +++ /dev/null @@ -1,3 +0,0 @@ -use eventstore; - -drop index events@changes_idx; diff --git a/migrations/cockroach/V1.52__privacy_policy.sql b/migrations/cockroach/V1.52__privacy_policy.sql deleted file mode 100644 index 6ecec46135..0000000000 --- a/migrations/cockroach/V1.52__privacy_policy.sql +++ /dev/null @@ -1,46 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN privacy_policy BOOLEAN; -ALTER TABLE auth.features ADD COLUMN privacy_policy BOOLEAN; -ALTER TABLE authz.features ADD COLUMN privacy_policy BOOLEAN; -ALTER TABLE management.features ADD COLUMN privacy_policy BOOLEAN; - -CREATE TABLE auth.privacy_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - state SMALLINT, - sequence BIGINT, - - tos_link STRING, - privacy_link STRING, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.privacy_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - state SMALLINT, - sequence BIGINT, - - tos_link STRING, - privacy_link STRING, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE management.privacy_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - state SMALLINT, - sequence BIGINT, - - tos_link STRING, - privacy_link STRING, - - PRIMARY KEY (aggregate_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.53__custom_login_text.sql b/migrations/cockroach/V1.53__custom_login_text.sql deleted file mode 100644 index 07677ad95c..0000000000 --- a/migrations/cockroach/V1.53__custom_login_text.sql +++ /dev/null @@ -1,44 +0,0 @@ -CREATE TABLE adminapi.custom_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - template TEXT, - language TEXT, - key TEXT, - text TEXT, - - PRIMARY KEY (aggregate_id, template, key, language) -); - -CREATE TABLE management.custom_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - template TEXT, - language TEXT, - key TEXT, - text TEXT, - - PRIMARY KEY (aggregate_id, template, key, language) -); - -CREATE TABLE auth.custom_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - template TEXT, - language TEXT, - key TEXT, - text TEXT, - - PRIMARY KEY (aggregate_id, template, key, language) -); diff --git a/migrations/cockroach/V1.54__oauth_idp.sql b/migrations/cockroach/V1.54__oauth_idp.sql deleted file mode 100644 index cfbccd9ddf..0000000000 --- a/migrations/cockroach/V1.54__oauth_idp.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE auth.idp_configs ADD COLUMN oauth_authorization_endpoint TEXT; -ALTER TABLE adminapi.idp_configs ADD COLUMN oauth_authorization_endpoint TEXT; -ALTER TABLE management.idp_configs ADD COLUMN oauth_authorization_endpoint TEXT; - -ALTER TABLE auth.idp_configs ADD COLUMN oauth_token_endpoint TEXT; -ALTER TABLE adminapi.idp_configs ADD COLUMN oauth_token_endpoint TEXT; -ALTER TABLE management.idp_configs ADD COLUMN oauth_token_endpoint TEXT; \ No newline at end of file diff --git a/migrations/cockroach/V1.55__custom_text.sql b/migrations/cockroach/V1.55__custom_text.sql deleted file mode 100644 index 99b078f972..0000000000 --- a/migrations/cockroach/V1.55__custom_text.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE notification.custom_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - template TEXT, - language TEXT, - key TEXT, - text TEXT, - - PRIMARY KEY (aggregate_id, template, key, language) -); diff --git a/migrations/cockroach/V1.56__token_idx.sql b/migrations/cockroach/V1.56__token_idx.sql deleted file mode 100644 index 9f52f4cdbe..0000000000 --- a/migrations/cockroach/V1.56__token_idx.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX IF NOT EXISTS user_user_agent_idx ON auth.tokens (user_id, user_agent_id); \ No newline at end of file diff --git a/migrations/cockroach/V1.57__passwordless_init.sql b/migrations/cockroach/V1.57__passwordless_init.sql deleted file mode 100644 index 7801e483db..0000000000 --- a/migrations/cockroach/V1.57__passwordless_init.sql +++ /dev/null @@ -1,12 +0,0 @@ -ALTER TABLE adminapi.users ADD COLUMN passwordless_init_required boolean; -ALTER TABLE auth.users ADD COLUMN passwordless_init_required boolean; -ALTER TABLE management.users ADD COLUMN passwordless_init_required boolean; - -ALTER TABLE adminapi.users ADD COLUMN password_init_required BOOLEAN; -UPDATE adminapi.users set password_init_required = NOT password_set; - -ALTER TABLE auth.users ADD COLUMN password_init_required BOOLEAN; -UPDATE auth.users set password_init_required = NOT password_set; - -ALTER TABLE management.users ADD COLUMN password_init_required BOOLEAN; -UPDATE management.users set password_init_required = NOT password_set; diff --git a/migrations/cockroach/V1.58__metadata.sql b/migrations/cockroach/V1.58__metadata.sql deleted file mode 100644 index beed6852ce..0000000000 --- a/migrations/cockroach/V1.58__metadata.sql +++ /dev/null @@ -1,27 +0,0 @@ -CREATE TABLE auth.metadata ( - aggregate_id TEXT, - - key TEXT, - value BYTES, - - resource_owner TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (aggregate_id, key) -); - -CREATE TABLE management.metadata ( - aggregate_id TEXT, - - key TEXT, - value BYTES, - - resource_owner TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - PRIMARY KEY (aggregate_id, key) -); diff --git a/migrations/cockroach/V1.59__user_lock.sql b/migrations/cockroach/V1.59__user_lock.sql deleted file mode 100644 index db32b431ae..0000000000 --- a/migrations/cockroach/V1.59__user_lock.sql +++ /dev/null @@ -1,45 +0,0 @@ -CREATE TABLE management.lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_password_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_password_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE auth.lockout_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - lockout_policy_state SMALLINT, - sequence BIGINT, - - max_password_attempts BIGINT, - show_lockout_failures BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -DROP TABLE management.password_lockout_policies; -DROP TABLE adminapi.password_lockout_policies; -DROP TABLE auth.password_lockout_policies; \ No newline at end of file diff --git a/migrations/cockroach/V1.5__orgdomain_validationtype.sql b/migrations/cockroach/V1.5__orgdomain_validationtype.sql deleted file mode 100644 index 271451b1d4..0000000000 --- a/migrations/cockroach/V1.5__orgdomain_validationtype.sql +++ /dev/null @@ -1,44 +0,0 @@ -BEGIN; - -ALTER TABLE management.org_domains ADD COLUMN validation_type SMALLINT; - -CREATE TABLE adminapi.users ( - id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - - resource_owner TEXT, - user_state SMALLINT, - last_login TIMESTAMPTZ, - password_change TIMESTAMPTZ, - user_name TEXT, - login_names TEXT ARRAY, - preferred_login_name TEXT, - first_name TEXT, - last_name TEXT, - nick_Name TEXT, - display_name TEXT, - preferred_language TEXT, - gender SMALLINT, - email TEXT, - is_email_verified BOOLEAN, - phone TEXT, - is_phone_verified BOOLEAN, - country TEXT, - locality TEXT, - postal_code TEXT, - region TEXT, - street_address TEXT, - otp_state SMALLINT, - sequence BIGINT, - password_set BOOLEAN, - password_change_required BOOLEAN, - mfa_max_set_up SMALLINT, - mfa_init_skipped TIMESTAMPTZ, - init_required BOOLEAN, - - PRIMARY KEY (id) -); - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.60__user_meta_data_feature.sql b/migrations/cockroach/V1.60__user_meta_data_feature.sql deleted file mode 100644 index 30190b5baa..0000000000 --- a/migrations/cockroach/V1.60__user_meta_data_feature.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN metadata_user BOOLEAN; -ALTER TABLE auth.features ADD COLUMN metadata_user BOOLEAN; -ALTER TABLE authz.features ADD COLUMN metadata_user BOOLEAN; -ALTER TABLE management.features ADD COLUMN metadata_user BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.61__has_project.sql b/migrations/cockroach/V1.61__has_project.sql deleted file mode 100644 index 056d90933d..0000000000 --- a/migrations/cockroach/V1.61__has_project.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE management.projects ADD COLUMN has_project_check BOOLEAN; - -ALTER TABLE authz.applications ADD COLUMN has_project_check BOOLEAN; -ALTER TABLE auth.applications ADD COLUMN has_project_check BOOLEAN; -ALTER TABLE management.applications ADD COLUMN has_project_check BOOLEAN; - -CREATE TABLE auth.org_project_mapping ( - org_id TEXT, - project_id TEXT, - project_grant_id TEXT, - - PRIMARY KEY (org_id, project_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.62__custom_text_feature.sql b/migrations/cockroach/V1.62__custom_text_feature.sql deleted file mode 100644 index 51256c4fb9..0000000000 --- a/migrations/cockroach/V1.62__custom_text_feature.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE adminapi.features RENAME COLUMN custom_text TO custom_text_message; -ALTER TABLE auth.features RENAME COLUMN custom_text TO custom_text_message; -ALTER TABLE authz.features RENAME COLUMN custom_text TO custom_text_message; -ALTER TABLE management.features RENAME COLUMN custom_text TO custom_text_message; - -ALTER TABLE adminapi.features ADD COLUMN custom_text_login BOOLEAN; -ALTER TABLE auth.features ADD COLUMN custom_text_login BOOLEAN; -ALTER TABLE authz.features ADD COLUMN custom_text_login BOOLEAN; -ALTER TABLE management.features ADD COLUMN custom_text_login BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.64__first_projections.sql b/migrations/cockroach/V1.64__first_projections.sql deleted file mode 100644 index 1e27be7878..0000000000 --- a/migrations/cockroach/V1.64__first_projections.sql +++ /dev/null @@ -1,60 +0,0 @@ -CREATE TABLE zitadel.projections.orgs ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - org_state SMALLINT, - sequence BIGINT, - - domain TEXT, - name TEXT, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.org_owners_orgs ( - id TEXT, - name TEXT, - creation_date TIMESTAMPTZ, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.org_owners_users ( - org_id TEXT, - owner_id TEXT, - language VARCHAR(10), - email TEXT, - first_name TEXT, - last_name TEXT, - gender INT2, - - PRIMARY KEY (owner_id, org_id), - CONSTRAINT fk_org FOREIGN KEY (org_id) REFERENCES projections.org_owners_orgs (id) ON DELETE CASCADE -); - -CREATE VIEW zitadel.projections.org_owners AS ( - SELECT o.id AS org_id, - o.name AS org_name, - o.creation_date, - u.owner_id, - u.language, - u.email, - u.first_name, - u.last_name, - u.gender - FROM projections.org_owners_orgs o - JOIN projections.org_owners_users u ON o.id = u.org_id -); - -CREATE TABLE zitadel.projections.projects ( - id TEXT, - name TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - owner_id TEXT, - creator_id TEXT, - state INT2, - - PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.65__project_private_labeling.sql b/migrations/cockroach/V1.65__project_private_labeling.sql deleted file mode 100644 index 13cf69c237..0000000000 --- a/migrations/cockroach/V1.65__project_private_labeling.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE management.projects ADD COLUMN private_labeling_setting SMALLINT; - -ALTER TABLE authz.applications ADD COLUMN private_labeling_setting SMALLINT; -ALTER TABLE auth.applications ADD COLUMN private_labeling_setting SMALLINT; -ALTER TABLE management.applications ADD COLUMN private_labeling_setting SMALLINT; diff --git a/migrations/cockroach/V1.66__events_cols.sql b/migrations/cockroach/V1.66__events_cols.sql deleted file mode 100644 index 5871d7f67b..0000000000 --- a/migrations/cockroach/V1.66__events_cols.sql +++ /dev/null @@ -1,8 +0,0 @@ -BEGIN; - -ALTER TABLE eventstore.events - RENAME COLUMN previous_sequence TO previous_aggregate_sequence, - ADD COLUMN previous_aggregate_type_sequence INT8, - ADD CONSTRAINT prev_agg_type_seq_unique UNIQUE(previous_aggregate_type_sequence); - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.67__update_events.sql b/migrations/cockroach/V1.67__update_events.sql deleted file mode 100644 index 5a27f8be80..0000000000 --- a/migrations/cockroach/V1.67__update_events.sql +++ /dev/null @@ -1 +0,0 @@ -GRANT UPDATE ON TABLE eventstore.events TO eventstore; \ No newline at end of file diff --git a/migrations/cockroach/V1.68__agg_type_idx.sql b/migrations/cockroach/V1.68__agg_type_idx.sql deleted file mode 100644 index 556b415c31..0000000000 --- a/migrations/cockroach/V1.68__agg_type_idx.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE INDEX agg_type ON eventstore.events (aggregate_type); \ No newline at end of file diff --git a/migrations/cockroach/V1.69__lockout_policy_feature.sql b/migrations/cockroach/V1.69__lockout_policy_feature.sql deleted file mode 100644 index 7ab1f850d7..0000000000 --- a/migrations/cockroach/V1.69__lockout_policy_feature.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE adminapi.features ADD COLUMN lockout_policy BOOLEAN; -ALTER TABLE auth.features ADD COLUMN lockout_policy BOOLEAN; -ALTER TABLE authz.features ADD COLUMN lockout_policy BOOLEAN; -ALTER TABLE management.features ADD COLUMN lockout_policy BOOLEAN; \ No newline at end of file diff --git a/migrations/cockroach/V1.6__origin_allow_list.sql b/migrations/cockroach/V1.6__origin_allow_list.sql deleted file mode 100644 index 7589e8cb9f..0000000000 --- a/migrations/cockroach/V1.6__origin_allow_list.sql +++ /dev/null @@ -1,15 +0,0 @@ -BEGIN; - -ALTER TABLE management.applications ADD COLUMN origin_allow_list TEXT ARRAY; -ALTER TABLE auth.applications ADD COLUMN origin_allow_list TEXT ARRAY; -ALTER TABLE authz.applications ADD COLUMN origin_allow_list TEXT ARRAY; - -TRUNCATE TABLE management.applications; -TRUNCATE TABLE auth.applications; -TRUNCATE TABLE authz.applications; - -UPDATE management.current_sequences set current_sequence = 0 where view_name = 'management.applications'; -UPDATE auth.current_sequences set current_sequence = 0 where view_name = 'auth.applications'; -UPDATE authz.current_sequences set current_sequence = 0 where view_name = 'authz.applications'; - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.70__idp.sql b/migrations/cockroach/V1.70__idp.sql deleted file mode 100644 index 798c2696a8..0000000000 --- a/migrations/cockroach/V1.70__idp.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE management.idp_configs ADD COLUMN auto_register BOOLEAN; -ALTER TABLE adminapi.idp_configs ADD COLUMN auto_register BOOLEAN; -ALTER TABLE auth.idp_configs ADD COLUMN auto_register BOOLEAN; diff --git a/migrations/cockroach/V1.71__jwt_idp.sql b/migrations/cockroach/V1.71__jwt_idp.sql deleted file mode 100644 index fcd56c0989..0000000000 --- a/migrations/cockroach/V1.71__jwt_idp.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE auth.idp_configs ADD COLUMN jwt_endpoint TEXT; -ALTER TABLE auth.idp_configs ADD COLUMN jwt_keys_endpoint TEXT; -ALTER TABLE auth.idp_configs ADD COLUMN jwt_header_name TEXT; - -ALTER TABLE adminapi.idp_configs ADD COLUMN jwt_endpoint TEXT; -ALTER TABLE adminapi.idp_configs ADD COLUMN jwt_keys_endpoint TEXT; -ALTER TABLE adminapi.idp_configs ADD COLUMN jwt_header_name TEXT; - -ALTER TABLE management.idp_configs ADD COLUMN jwt_endpoint TEXT; -ALTER TABLE management.idp_configs ADD COLUMN jwt_keys_endpoint TEXT; -ALTER TABLE management.idp_configs ADD COLUMN jwt_header_name TEXT; diff --git a/migrations/cockroach/V1.72__actions.sql b/migrations/cockroach/V1.72__actions.sql deleted file mode 100644 index d8512b2954..0000000000 --- a/migrations/cockroach/V1.72__actions.sql +++ /dev/null @@ -1,63 +0,0 @@ -CREATE TABLE zitadel.projections.actions ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - action_state SMALLINT, - sequence BIGINT, - - name TEXT, - script TEXT, - timeout BIGINT, - allowed_to_fail BOOLEAN, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.flows_actions ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - sequence BIGINT, - - name TEXT, - script TEXT, - timeout BIGINT, - allowed_to_fail BOOLEAN, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.flows_triggers ( - flow_type SMALLINT, - trigger_type SMALLINT, - resource_owner TEXT, - action_id TEXT, - trigger_sequence SMALLINT, - - PRIMARY KEY (flow_type, trigger_type, resource_owner, action_id), - CONSTRAINT fk_action FOREIGN KEY (action_id) REFERENCES zitadel.projections.flows_actions (id) ON DELETE CASCADE -); - -CREATE VIEW zitadel.projections.flows_actions_triggers AS ( - SELECT a.id AS action_id, - a.name, - a.creation_date, - a.resource_owner, - a.sequence, - a.change_date, - a.script, - a.timeout, - a.allowed_to_fail, - t.flow_type, - t.trigger_type, - t.trigger_sequence - FROM zitadel.projections.flows_triggers t - JOIN zitadel.projections.flows_actions a ON t.action_id = a.id - ); - -ALTER TABLE auth.features ADD COLUMN actions BOOLEAN; -ALTER TABLE authz.features ADD COLUMN actions BOOLEAN; -ALTER TABLE adminapi.features ADD COLUMN actions BOOLEAN; -ALTER TABLE management.features ADD COLUMN actions BOOLEAN; diff --git a/migrations/cockroach/V1.73__auth_request_times.sql b/migrations/cockroach/V1.73__auth_request_times.sql deleted file mode 100644 index 10b70ae9f9..0000000000 --- a/migrations/cockroach/V1.73__auth_request_times.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE auth.auth_requests ADD COLUMN creation_date TIMESTAMPTZ; -ALTER TABLE auth.auth_requests ADD COLUMN change_date TIMESTAMPTZ; diff --git a/migrations/cockroach/V1.74__fix_projections.sql b/migrations/cockroach/V1.74__fix_projections.sql deleted file mode 100644 index bbe5939649..0000000000 --- a/migrations/cockroach/V1.74__fix_projections.sql +++ /dev/null @@ -1,9 +0,0 @@ -ALTER TABLE zitadel.projections.orgs RENAME COLUMN domain TO primary_domain; - -DROP VIEW zitadel.projections.flows_actions_triggers; -ALTER TABLE zitadel.projections.flows_triggers DROP CONSTRAINT fk_action; -DROP TABLE zitadel.projections.flows_actions; -DELETE FROM zitadel.projections.current_sequences where projection_name in ( - 'zitadel.projections.actions', - 'zitadel.projections.flows_actions', - 'zitadel.projections.flows_triggers'); diff --git a/migrations/cockroach/V1.75__project_projections.sql b/migrations/cockroach/V1.75__project_projections.sql deleted file mode 100644 index d58af27269..0000000000 --- a/migrations/cockroach/V1.75__project_projections.sql +++ /dev/null @@ -1,37 +0,0 @@ -ALTER TABLE zitadel.projections.projects ADD COLUMN project_role_assertion BOOLEAN; -ALTER TABLE zitadel.projections.projects ADD COLUMN project_role_check BOOLEAN; -ALTER TABLE zitadel.projections.projects ADD COLUMN has_project_check BOOLEAN; -ALTER TABLE zitadel.projections.projects ADD COLUMN private_labeling_setting SMALLINT; -ALTER TABLE zitadel.projections.projects ADD COLUMN sequence BIGINT; -ALTER TABLE zitadel.projections.projects RENAME COLUMN owner_id TO resource_owner; - -CREATE TABLE zitadel.projections.project_grants ( - project_id TEXT, - grant_id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - state INT2, - sequence BIGINT, - - granted_org_id TEXT, - granted_role_keys TEXT Array, - creator_id TEXT, - - PRIMARY KEY (grant_id) -); - -CREATE TABLE zitadel.projections.project_roles ( - project_id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner TEXT, - sequence BIGINT, - - role_key TEXT, - display_name TEXT, - group_name TEXT, - creator_id TEXT, - - PRIMARY KEY (project_id, role_key) -); diff --git a/migrations/cockroach/V1.76__fix_projection_projections.sql b/migrations/cockroach/V1.76__fix_projection_projections.sql deleted file mode 100644 index d51e0ebdaf..0000000000 --- a/migrations/cockroach/V1.76__fix_projection_projections.sql +++ /dev/null @@ -1,2 +0,0 @@ -TRUNCATE TABLE zitadel.projections.projects; -DELETE FROM zitadel.projections.current_sequences where projection_name = 'zitadel.projections.projects'; diff --git a/migrations/cockroach/V1.77__org_domains_projection.sql b/migrations/cockroach/V1.77__org_domains_projection.sql deleted file mode 100644 index 56ef51fbef..0000000000 --- a/migrations/cockroach/V1.77__org_domains_projection.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE zitadel.projections.org_domains ( - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - domain TEXT, - org_id TEXT, - is_verified BOOLEAN, - is_primary BOOLEAN, - validation_type SMALLINT, - - PRIMARY KEY (org_id, domain) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.78__login_policies_projection.sql b/migrations/cockroach/V1.78__login_policies_projection.sql deleted file mode 100644 index d8cf482dc1..0000000000 --- a/migrations/cockroach/V1.78__login_policies_projection.sql +++ /dev/null @@ -1,20 +0,0 @@ -CREATE TABLE zitadel.projections.login_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - allow_register BOOLEAN, - allow_username_password BOOLEAN, - allow_external_idps BOOLEAN, - - force_mfa BOOLEAN, - second_factors SMALLINT ARRAY, - multi_factors SMALLINT ARRAY, - passwordless_type SMALLINT, - is_default BOOLEAN, - hide_password_reset BOOLEAN, - - PRIMARY KEY (aggregate_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.79__idp_projections.sql b/migrations/cockroach/V1.79__idp_projections.sql deleted file mode 100644 index 0db991cb98..0000000000 --- a/migrations/cockroach/V1.79__idp_projections.sql +++ /dev/null @@ -1,41 +0,0 @@ -CREATE TABLE zitadel.projections.idps ( - id TEXT, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - resource_owner TEXT, - - state SMALLINT, - name TEXT, - styling_type SMALLINT, - owner_type SMALLINT, - auto_register BOOLEAN, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.idps_oidc_config ( - idp_id TEXT REFERENCES zitadel.projections.idps (id) ON DELETE CASCADE, - - client_id TEXT, - client_secret JSONB, - issuer TEXT, - scopes STRING[], - display_name_mapping SMALLINT, - username_mapping SMALLINT, - authorization_endpoint TEXT, - token_endpoint TEXT, - - PRIMARY KEY (idp_id) -); - -CREATE TABLE zitadel.projections.idps_jwt_config ( - idp_id TEXT REFERENCES zitadel.projections.idps (id) ON DELETE CASCADE, - - issuer TEXT, - keys_endpoint TEXT, - header_name TEXT, - endpoint TEXT, - - PRIMARY KEY (idp_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.7__idps.sql b/migrations/cockroach/V1.7__idps.sql deleted file mode 100644 index 0650b3d3c7..0000000000 --- a/migrations/cockroach/V1.7__idps.sql +++ /dev/null @@ -1,105 +0,0 @@ - -CREATE TABLE adminapi.idp_configs ( - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - aggregate_id TEXT, - name TEXT, - logo_src BYTES, - idp_state SMALLINT, - idp_provider_type SMALLINT, - - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_client_secret JSONB, - oidc_issuer TEXT, - oidc_scopes TEXT ARRAY, - - PRIMARY KEY (idp_config_id) -); - - -CREATE TABLE management.idp_configs ( - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - aggregate_id TEXT, - name TEXT, - logo_src BYTES, - idp_state SMALLINT, - idp_provider_type SMALLINT, - - is_oidc BOOLEAN, - oidc_client_id TEXT, - oidc_client_secret JSONB, - oidc_issuer TEXT, - oidc_scopes TEXT ARRAY, - - PRIMARY KEY (idp_config_id) -); - - -CREATE TABLE adminapi.login_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - login_policy_state SMALLINT, - sequence BIGINT, - - allow_register BOOLEAN, - allow_username_password BOOLEAN, - allow_external_idp BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - - -CREATE TABLE management.login_policies ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - login_policy_state SMALLINT, - sequence BIGINT, - - allow_register BOOLEAN, - allow_username_password BOOLEAN, - allow_external_idp BOOLEAN, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE adminapi.idp_providers ( - aggregate_id TEXT, - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - name string, - idp_config_type SMALLINT, - idp_provider_type SMALLINT, - - PRIMARY KEY (aggregate_id, idp_config_id) -); - -CREATE TABLE management.idp_providers ( - aggregate_id TEXT, - idp_config_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - - name string, - idp_config_type SMALLINT, - idp_provider_type SMALLINT, - - PRIMARY KEY (aggregate_id, idp_config_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.80__password_complexity_policy.sql b/migrations/cockroach/V1.80__password_complexity_policy.sql deleted file mode 100644 index 26b49a829b..0000000000 --- a/migrations/cockroach/V1.80__password_complexity_policy.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE zitadel.projections.password_complexity_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - state INT2 NULL, - resource_owner TEXT, - - is_default BOOLEAN, - min_length INT8 NULL, - has_lowercase BOOL NULL, - has_uppercase BOOL NULL, - has_symbol BOOL NULL, - has_number BOOL NULL, - - PRIMARY KEY (id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.81__password_age_policy.sql b/migrations/cockroach/V1.81__password_age_policy.sql deleted file mode 100644 index 54f78c29d6..0000000000 --- a/migrations/cockroach/V1.81__password_age_policy.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE zitadel.projections.password_age_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - state INT2 NULL, - resource_owner TEXT, - - is_default BOOLEAN, - max_age_days INT8 NULL, - expire_warn_days INT8 NULL, - - PRIMARY KEY (id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.82__lockout_policy.sql b/migrations/cockroach/V1.82__lockout_policy.sql deleted file mode 100644 index 2cb36fa0c2..0000000000 --- a/migrations/cockroach/V1.82__lockout_policy.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE zitadel.projections.lockout_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - state INT2 NULL, - resource_owner TEXT, - - is_default BOOLEAN, - max_password_attempts INT8 NULL, - show_failure BOOLEAN NULL, - - PRIMARY KEY (id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.83__privacy_policy.sql b/migrations/cockroach/V1.83__privacy_policy.sql deleted file mode 100644 index 2df3fbea63..0000000000 --- a/migrations/cockroach/V1.83__privacy_policy.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE zitadel.projections.privacy_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - state INT2 NULL, - resource_owner TEXT, - - is_default BOOLEAN, - privacy_link TEXT, - tos_link TEXT, - - PRIMARY KEY (id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.84__org_iam_policy.sql b/migrations/cockroach/V1.84__org_iam_policy.sql deleted file mode 100644 index 1a19175810..0000000000 --- a/migrations/cockroach/V1.84__org_iam_policy.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE zitadel.projections.org_iam_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - state INT2 NULL, - resource_owner TEXT, - - is_default BOOLEAN, - user_login_must_be_domain BOOLEAN, - - PRIMARY KEY (id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.85__messages.sql b/migrations/cockroach/V1.85__messages.sql deleted file mode 100644 index cd448faa98..0000000000 --- a/migrations/cockroach/V1.85__messages.sql +++ /dev/null @@ -1,50 +0,0 @@ -CREATE TABLE zitadel.projections.mail_templates ( - aggregate_id TEXT NOT NULL, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - state SMALLINT, - sequence BIGINT, - is_default BOOLEAN, - - template BYTES, - - PRIMARY KEY (aggregate_id) -); - -CREATE TABLE zitadel.projections.message_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - state SMALLINT, - sequence BIGINT, - - type TEXT, - language TEXT, - title TEXT, - pre_header TEXT, - subject TEXT, - greeting TEXT, - text TEXT, - button_text TEXT, - footer_text TEXT, - - PRIMARY KEY (aggregate_id, type, language) -); - -CREATE TABLE zitadel.projections.custom_texts ( - aggregate_id TEXT, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence BIGINT, - is_default BOOLEAN, - - template TEXT, - language TEXT, - key TEXT, - text TEXT, - - PRIMARY KEY (aggregate_id, template, key, language) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.86__features.sql b/migrations/cockroach/V1.86__features.sql deleted file mode 100644 index 9b890dff6e..0000000000 --- a/migrations/cockroach/V1.86__features.sql +++ /dev/null @@ -1,32 +0,0 @@ -CREATE TABLE zitadel.projections.features -( - aggregate_id TEXT NOT NULL, - creation_date TIMESTAMPTZ NULL, - change_date TIMESTAMPTZ NULL, - sequence INT8 NULL, - is_default BOOLEAN, - - tier_name TEXT, - tier_description TEXT, - state INT2 NULL, - state_description TEXT, - audit_log_retention BIGINT, - login_policy_factors BOOLEAN, - login_policy_idp BOOLEAN, - login_policy_passwordless BOOLEAN, - login_policy_registration BOOLEAN, - login_policy_username_login BOOLEAN, - login_policy_password_reset BOOLEAN, - password_complexity_policy BOOLEAN, - label_policy_private_label BOOLEAN, - label_policy_watermark BOOLEAN, - custom_domain BOOLEAN, - privacy_policy BOOLEAN, - metadata_user BOOLEAN, - custom_text_message BOOLEAN, - custom_text_login BOOLEAN, - lockout_policy BOOLEAN, - actions BOOLEAN, - - PRIMARY KEY (aggregate_id) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.87__app.sql b/migrations/cockroach/V1.87__app.sql deleted file mode 100644 index f798e963ca..0000000000 --- a/migrations/cockroach/V1.87__app.sql +++ /dev/null @@ -1,47 +0,0 @@ -CREATE TABLE zitadel.projections.apps( - id STRING, - project_id STRING NOT NULL, - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - resource_owner STRING NOT NULL, - state INT2, - sequence INT8, - - name STRING, - - PRIMARY KEY (id), - INDEX idx_project_id (project_id) -); - -CREATE TABLE zitadel.projections.apps_api_configs( - app_id STRING REFERENCES zitadel.projections.apps (id) ON DELETE CASCADE, - - client_id STRING NOT NULL, - client_secret JSONB, - auth_method INT2, - - PRIMARY KEY (app_id) -); - -CREATE TABLE zitadel.projections.apps_oidc_configs( - app_id STRING REFERENCES zitadel.projections.apps (id) ON DELETE CASCADE, - - version STRING NOT NULL, - client_id STRING NOT NULL, - client_secret JSONB, - redirect_uris STRING[], - response_types INT2[], - grant_types INT2[], - application_type INT2, - auth_method_type INT2, - post_logout_redirect_uris STRING[], - is_dev_mode BOOLEAN, - access_token_type INT2, - access_token_role_assertion BOOLEAN, - id_token_role_assertion BOOLEAN, - id_token_userinfo_assertion BOOLEAN, - clock_skew INT8, - additional_origins STRING[], - - PRIMARY KEY (app_id) -); diff --git a/migrations/cockroach/V1.88__user_idp_link.sql b/migrations/cockroach/V1.88__user_idp_link.sql deleted file mode 100644 index d74589285f..0000000000 --- a/migrations/cockroach/V1.88__user_idp_link.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE zitadel.projections.idp_user_links( - idp_id STRING, - user_id STRING, - external_user_id STRING, - display_name STRING, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence INT8, - resource_owner STRING, - - PRIMARY KEY (idp_id, external_user_id), - INDEX idx_user (user_id) -); diff --git a/migrations/cockroach/V1.89__idp_login_policy_link.sql b/migrations/cockroach/V1.89__idp_login_policy_link.sql deleted file mode 100644 index 9278ad1613..0000000000 --- a/migrations/cockroach/V1.89__idp_login_policy_link.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE zitadel.projections.idp_login_policy_links( - idp_id STRING, - aggregate_id STRING, - provider_type INT2, - - creation_date TIMESTAMPTZ, - change_date TIMESTAMPTZ, - sequence INT8, - resource_owner STRING, - - PRIMARY KEY (aggregate_id, idp_id) -); diff --git a/migrations/cockroach/V1.8__username_change.sql b/migrations/cockroach/V1.8__username_change.sql deleted file mode 100644 index c8440a2092..0000000000 --- a/migrations/cockroach/V1.8__username_change.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; - -ALTER TABLE management.users ADD COLUMN username_change_required BOOLEAN; -ALTER TABLE auth.users ADD COLUMN username_change_required BOOLEAN; -ALTER TABLE adminapi.users ADD COLUMN username_change_required BOOLEAN; - -COMMIT; \ No newline at end of file diff --git a/migrations/cockroach/V1.90__token_refresh_id.sql b/migrations/cockroach/V1.90__token_refresh_id.sql deleted file mode 100644 index c6bd19d8b2..0000000000 --- a/migrations/cockroach/V1.90__token_refresh_id.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE auth.tokens ADD COLUMN refresh_token_id TEXT; diff --git a/migrations/cockroach/V1.91__change_app.sql b/migrations/cockroach/V1.91__change_app.sql deleted file mode 100644 index 1ca568c367..0000000000 --- a/migrations/cockroach/V1.91__change_app.sql +++ /dev/null @@ -1,3 +0,0 @@ -SET enable_experimental_alter_column_type_general = true; - -ALTER TABLE zitadel.projections.apps_oidc_configs ALTER version TYPE INT2 USING version::INT2; \ No newline at end of file diff --git a/migrations/cockroach/V1.92__features_not_null.sql b/migrations/cockroach/V1.92__features_not_null.sql deleted file mode 100644 index 06eeaccb34..0000000000 --- a/migrations/cockroach/V1.92__features_not_null.sql +++ /dev/null @@ -1,64 +0,0 @@ -alter table zitadel.projections.features - drop column creation_date, - alter column is_default set default false, - alter column state set default 0, - alter column audit_log_retention set default 0, - alter column login_policy_factors set default false, - alter column login_policy_idp set default false, - alter column login_policy_passwordless set default false, - alter column login_policy_registration set default false, - alter column login_policy_username_login set default false, - alter column login_policy_password_reset set default false, - alter column password_complexity_policy set default false, - alter column label_policy_private_label set default false, - alter column label_policy_watermark set default false, - alter column custom_domain set default false, - alter column privacy_policy set default false, - alter column metadata_user set default false, - alter column custom_text_message set default false, - alter column custom_text_login set default false, - alter column lockout_policy set default false, - alter column actions set default false; - -update zitadel.projections.features set is_default = default where is_default is null; -update zitadel.projections.features set state = 0 where state is null; -update zitadel.projections.features set audit_log_retention = 0 where audit_log_retention is null; -update zitadel.projections.features set login_policy_factors = default where login_policy_factors is null; -update zitadel.projections.features set login_policy_idp = default where login_policy_idp is null; -update zitadel.projections.features set login_policy_passwordless = default where login_policy_passwordless is null; -update zitadel.projections.features set login_policy_registration = default where login_policy_registration is null; -update zitadel.projections.features set login_policy_username_login = default where login_policy_username_login is null; -update zitadel.projections.features set login_policy_password_reset = default where login_policy_password_reset is null; -update zitadel.projections.features set password_complexity_policy = default where password_complexity_policy is null; -update zitadel.projections.features set label_policy_private_label = default where label_policy_private_label is null; -update zitadel.projections.features set label_policy_watermark = default where label_policy_watermark is null; -update zitadel.projections.features set custom_domain = default where custom_domain is null; -update zitadel.projections.features set privacy_policy = default where privacy_policy is null; -update zitadel.projections.features set metadata_user = default where metadata_user is null; -update zitadel.projections.features set custom_text_message = default where custom_text_message is null; -update zitadel.projections.features set custom_text_login = default where custom_text_login is null; -update zitadel.projections.features set lockout_policy = default where lockout_policy is null; -update zitadel.projections.features set actions = default where actions is null; - -alter table zitadel.projections.features - alter column change_date set not null, - alter column sequence set not null, - alter column is_default set not null, - alter column state set not null, - alter column audit_log_retention set not null, - alter column login_policy_factors set not null, - alter column login_policy_idp set not null, - alter column login_policy_passwordless set not null, - alter column login_policy_registration set not null, - alter column login_policy_username_login set not null, - alter column login_policy_password_reset set not null, - alter column password_complexity_policy set not null, - alter column label_policy_private_label set not null, - alter column label_policy_watermark set not null, - alter column custom_domain set not null, - alter column privacy_policy set not null, - alter column metadata_user set not null, - alter column custom_text_message set not null, - alter column custom_text_login set not null, - alter column lockout_policy set not null, - alter column actions set not null; diff --git a/migrations/cockroach/V1.93__login_names.sql b/migrations/cockroach/V1.93__login_names.sql deleted file mode 100644 index a02ed5052e..0000000000 --- a/migrations/cockroach/V1.93__login_names.sql +++ /dev/null @@ -1,54 +0,0 @@ -CREATE TABLE zitadel.projections.login_names_users ( - id STRING NOT NULL - , user_name STRING NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (id) - , INDEX idx_ro (resource_owner) -); - -CREATE TABLE zitadel.projections.login_names_domains ( - name STRING NOT NULL - , is_primary BOOLEAN NOT NULL DEFAULT false - , resource_owner STRING NOT NULL - - , PRIMARY KEY (resource_owner, name) -); - -CREATE TABLE zitadel.projections.login_names_policies ( - must_be_domain BOOLEAN NOT NULL - , is_default BOOLEAN NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (resource_owner) - , INDEX idx_is_default (resource_owner, is_default) -); - -CREATE VIEW zitadel.projections.login_names -AS SELECT - user_id - , IF( - must_be_domain - , CONCAT(user_name, '@', domain) - , user_name - ) AS login_name - , IFNULL(is_primary, true) AS is_primary -- is_default is null on additional verified domain and policy with must_be_domain=false -FROM ( -SELECT - policy_users.user_id - , policy_users.user_name - , policy_users.resource_owner - , policy_users.must_be_domain - , domains.name AS domain - , domains.is_primary -FROM ( - SELECT - users.id as user_id - , users.user_name - , users.resource_owner - , IFNULL(policy_custom.must_be_domain, policy_default.must_be_domain) AS must_be_domain - FROM zitadel.projections.login_names_users users - LEFT JOIN zitadel.projections.login_names_policies policy_custom on policy_custom.resource_owner = users.resource_owner - LEFT JOIN zitadel.projections.login_names_policies policy_default on policy_default.is_default = true) policy_users -LEFT JOIN zitadel.projections.login_names_domains domains ON policy_users.must_be_domain AND policy_users.resource_owner = domains.resource_owner -); diff --git a/migrations/cockroach/V1.94__label_policy.sql b/migrations/cockroach/V1.94__label_policy.sql deleted file mode 100644 index 0cc728b54a..0000000000 --- a/migrations/cockroach/V1.94__label_policy.sql +++ /dev/null @@ -1,28 +0,0 @@ -CREATE TABLE zitadel.projections.label_policies ( - id STRING NOT NULL, - creation_date TIMESTAMPTZ NOT NULL, - change_date TIMESTAMPTZ NOT NULL, - sequence INT8 NOT NULL, - state INT2 NOT NULL, - resource_owner TEXT NOT NULL, - - is_default BOOLEAN NOT NULL DEFAULT false, - hide_login_name_suffix BOOLEAN NOT NULL DEFAULT false, - font_url STRING, - watermark_disabled BOOLEAN NOT NULL DEFAULT false, - should_error_popup BOOLEAN NOT NULL DEFAULT false, - light_primary_color STRING, - light_warn_color STRING, - light_background_color STRING, - light_font_color STRING, - light_logo_url STRING, - light_icon_url STRING, - dark_primary_color STRING, - dark_warn_color STRING, - dark_background_color STRING, - dark_font_color STRING, - dark_logo_url STRING, - dark_icon_url STRING, - - PRIMARY KEY (id, state) -); \ No newline at end of file diff --git a/migrations/cockroach/V1.95__user.sql b/migrations/cockroach/V1.95__user.sql deleted file mode 100644 index 8258017210..0000000000 --- a/migrations/cockroach/V1.95__user.sql +++ /dev/null @@ -1,45 +0,0 @@ -CREATE TABLE zitadel.projections.users( - id STRING - , creation_date TIMESTAMPTZ - , change_date TIMESTAMPTZ - , resource_owner STRING NOT NULL - , state INT2 - , sequence INT8 - - , username STRING - - , PRIMARY KEY (id) - , INDEX idx_username (username) -); - -CREATE TABLE zitadel.projections.users_machines( - user_id STRING REFERENCES zitadel.projections.users (id) ON DELETE CASCADE - - , name STRING NOT NULL - , description STRING - - , PRIMARY KEY (user_id) -); - -CREATE TABLE zitadel.projections.users_humans( - user_id STRING REFERENCES zitadel.projections.users (id) ON DELETE CASCADE - - --profile - , first_name STRING NOT NULL - , last_name STRING NOT NULL - , nick_name STRING - , display_name STRING - , preferred_language VARCHAR(10) - , gender INT2 - , avater_key STRING - - --email - , email STRING NOT NULL - , is_email_verified BOOLEAN NOT NULL DEFAULT false - - --phone - , phone STRING - , is_phone_verified BOOLEAN - - , PRIMARY KEY (user_id) -); diff --git a/migrations/cockroach/V1.96__members.sql b/migrations/cockroach/V1.96__members.sql deleted file mode 100644 index 1d1e51c7b7..0000000000 --- a/migrations/cockroach/V1.96__members.sql +++ /dev/null @@ -1,56 +0,0 @@ -CREATE TABLE zitadel.projections.org_members ( - org_id STRING NOT NULL - , user_id STRING NOT NULL - , roles STRING[] - - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (org_id, user_id) - , INDEX idx_user (user_id) -); - -CREATE TABLE zitadel.projections.iam_members ( - iam_id STRING NOT NULL - , user_id STRING NOT NULL - , roles STRING[] - - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (iam_id, user_id) - , INDEX idx_user (user_id) -); - -CREATE TABLE zitadel.projections.project_members ( - project_id STRING NOT NULL - , user_id STRING NOT NULL - , roles STRING[] - - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (project_id, user_id) - , INDEX idx_user (user_id) -); - -CREATE TABLE zitadel.projections.project_grant_members ( - project_id STRING NOT NULL - , user_id STRING NOT NULL - , grant_id STRING - , roles STRING[] - - , creation_date TIMESTAMPTZ NOT NULL - , change_date TIMESTAMPTZ NOT NULL - , sequence INT8 NOT NULL - , resource_owner STRING NOT NULL - - , PRIMARY KEY (project_id, grant_id, user_id) - , INDEX idx_user (user_id) -); diff --git a/migrations/cockroach/V1.97__delete_apps.sql b/migrations/cockroach/V1.97__delete_apps.sql deleted file mode 100644 index b478e157b5..0000000000 --- a/migrations/cockroach/V1.97__delete_apps.sql +++ /dev/null @@ -1,6 +0,0 @@ -DELETE FROM zitadel.projections.apps -WHERE project_id IN ( - SELECT aggregate_id - FROM eventstore.events - WHERE aggregate_type = 'project' AND event_type = 'project.removed' -); diff --git a/migrations/cockroach/V1.98__keys.sql b/migrations/cockroach/V1.98__keys.sql deleted file mode 100644 index cdd934fa11..0000000000 --- a/migrations/cockroach/V1.98__keys.sql +++ /dev/null @@ -1,27 +0,0 @@ -CREATE TABLE zitadel.projections.keys ( - id STRING, - creation_date TIMESTAMPTZ NOT NULL, - change_date TIMESTAMPTZ NOT NULL, - resource_owner STRING NOT NULL, - sequence INT8 NOT NULL, - algorithm STRING DEFAULT '' NOT NULL, - use STRING DEFAULT '' NOT NULL, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.keys_private( - id STRING REFERENCES zitadel.projections.keys ON DELETE NO ACTION, - expiry TIMESTAMPTZ NOT NULL, - key JSONB NOT NULL, - - PRIMARY KEY (id) -); - -CREATE TABLE zitadel.projections.keys_public ( - id STRING REFERENCES zitadel.projections.keys ON DELETE NO ACTION, - expiry TIMESTAMPTZ NOT NULL, - key BYTES NOT NULL, - - PRIMARY KEY (id) -); diff --git a/migrations/cockroach/V1.99__reset_user_projections.sql b/migrations/cockroach/V1.99__reset_user_projections.sql deleted file mode 100644 index 0e7ed009b4..0000000000 --- a/migrations/cockroach/V1.99__reset_user_projections.sql +++ /dev/null @@ -1,2 +0,0 @@ -truncate zitadel.projections.users cascade; -update zitadel.projections.current_sequences set current_sequence = 0 where projection_name = 'zitadel.projections.users'; diff --git a/migrations/cockroach/V1.9__token.sql b/migrations/cockroach/V1.9__token.sql deleted file mode 100644 index 33424018e4..0000000000 --- a/migrations/cockroach/V1.9__token.sql +++ /dev/null @@ -1,2 +0,0 @@ - -ALTER TABLE auth.tokens ADD COLUMN preferred_language TEXT; \ No newline at end of file diff --git a/migrations/cockroach/migrate_local.go b/migrations/cockroach/migrate_local.go deleted file mode 100644 index ee973661ee..0000000000 --- a/migrations/cockroach/migrate_local.go +++ /dev/null @@ -1,5 +0,0 @@ -//+build ignore - -package migrations - -//go:generate flyway -url=jdbc:postgresql://localhost:26257/defaultdb -user=root -password= -locations=filesystem:./ -placeholders.eventstorepassword=NULL -placeholders.managementpassword=NULL -placeholders.adminapipassword=NULL -placeholders.authpassword=NULL -placeholders.notificationpassword=NULL -placeholders.authzpassword=NULL -placeholders.queriespassword=NULL migrate diff --git a/migrations/testfiles/1.2__not.sql b/migrations/testfiles/1.2__not.sql deleted file mode 100644 index 3f32d01b57..0000000000 --- a/migrations/testfiles/1.2__not.sql +++ /dev/null @@ -1 +0,0 @@ -not \ No newline at end of file diff --git a/migrations/testfiles/V1.1__test.sql b/migrations/testfiles/V1.1__test.sql deleted file mode 100644 index 30d74d2584..0000000000 --- a/migrations/testfiles/V1.1__test.sql +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/migrations/testfiles/V1.2__test2.sql b/migrations/testfiles/V1.2__test2.sql deleted file mode 100644 index d606037cb2..0000000000 --- a/migrations/testfiles/V1.2__test2.sql +++ /dev/null @@ -1 +0,0 @@ -test2 \ No newline at end of file diff --git a/migrations/use_cases/login_names.sql b/migrations/use_cases/login_names.sql deleted file mode 100644 index 557d435792..0000000000 --- a/migrations/use_cases/login_names.sql +++ /dev/null @@ -1,322 +0,0 @@ --- -------------------------------------------------------- --- only default domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - ('org-ch.localhost', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') -; - -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- default and additional domain verified --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - ('org-ch.localhost', true, 'org') - , ('custom.ch', false, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') -; - --- default and custom login name => 4 login names default is primary -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- default and additional domain verified and primary --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - ('org-ch.localhost', false, 'org') - , ('custom.ch', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') -; - --- default and custom login name => 2 login names default is primary -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=false) no domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- only default for org - ('org-ch.localhost', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (false, false, 'org') -; - --- default and custom login name => 1 login name machine=user_name human=user_name(=email) -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=false) verified domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- default and unverified for org - ('org-ch.localhost', true, 'org') - , ('custom.ch', false, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (false, false, 'org') -; - --- 1 login name machine=user_name human=user_name(=email) -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=false) verified, primary domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- default and unverified for org - ('org-ch.localhost', false, 'org') - , ('custom.ch', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (false, false, 'org') -; - --- 1 login name machine=user_name human=user_name(=email) -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=true) no domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- only default for org - ('org-ch.localhost', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (true, false, 'org') -; - --- one login per user -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=true) verified domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- default and unverified for org - ('org-ch.localhost', true, 'org') - , ('custom.ch', false, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (true, false, 'org') -; - --- 2 login names per user -SELECT * FROM zitadel.projections.login_names WHERE user_id IN ('h', 'm'); -ROLLBACK; - --- -------------------------------------------------------- --- custom policy (must_be_domain=true) verified, primary domain --- -------------------------------------------------------- -BEGIN; - -INSERT INTO zitadel.projections.login_names_users ( - id - , user_name - , resource_owner -) VALUES - ('h', 'human', 'org') - , ('m', 'machine', 'org') -; - -INSERT INTO zitadel.projections.login_names_domains ( - name - , is_primary - , resource_owner -) VALUES - -- default and unverified for org - ('org-ch.localhost', false, 'org') - , ('custom.ch', true, 'org') -; - -INSERT INTO zitadel.projections.login_names_policies ( - must_be_domain - , is_default - , resource_owner -) VALUES - (true, true, 'IAM') - , (true, false, 'org') -; - --- 2 login names per user -explain analyze SELECT * FROM zitadel.projections.login_names WHERE user_id = 'h'; -ROLLBACK;