feat: remove org (#4148)

* feat(command): remove org

* refactor: imports, unused code, error handling

* reduce org removed in action

* add org deletion to projections

* add org removal to projections

* add org removal to projections

* org removed projection

* lint import

* projections

* fix: table names in tests

* fix: table names in tests

* logging

* add org state

* fix(domain): add Owner removed to object details

* feat(ListQuery): add with owner removed

* fix(org-delete): add bool to functions to select with owner removed

* fix(org-delete): add bools to user grants with events to determine if dependencies lost owner

* fix(org-delete): add unit tests for owner removed and org removed events

* fix(org-delete): add handling of org remove for grants and members

* fix(org-delete): correction of unit tests for owner removed

* fix(org-delete): update projections, unit tests and get functions

* fix(org-delete): add change date to authnkeys and owner removed to org metadata

* fix(org-delete): include owner removed for login names

* fix(org-delete): some column fixes in projections and build for queries with owner removed

* indexes

* fix(org-delete): include review changes

* fix(org-delete): change user projection name after merge

* fix(org-delete): include review changes for project grant where no project owner is necessary

* fix(org-delete): include auth and adminapi tables with owner removed information

* fix(org-delete): cleanup username and orgdomain uniqueconstraints when org is removed

* fix(org-delete): add permissions for org.remove

* remove unnecessary unique constraints

* fix column order in primary keys

* fix(org-delete): include review changes

* fix(org-delete): add owner removed indexes and chang setup step to create tables

* fix(org-delete): move PK order of instance_id and change added user_grant from review

* fix(org-delete): no params for prepareUserQuery

* change to step 6

* merge main

* fix(org-delete): OldUserName rename to private

* fix linting

* cleanup

* fix: remove org test

* create prerelease

* chore: delete org-delete as prerelease

Co-authored-by: Stefan Benz <[email protected]>
Co-authored-by: Livio Spring <[email protected]>
Co-authored-by: Fabi <[email protected]>
Co-authored-by: Stefan Benz <[email protected]>
This commit is contained in:
Silvan
2022-11-30 17:01:17 +01:00
committed by GitHub
co-authored by Stefan Benz Livio Spring Fabi Stefan Benz
parent 21a4e73bb6
commit f3e6f3b23b
304 changed files with 7293 additions and 3286 deletions
+35 -3
View File
@@ -10,10 +10,11 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/action"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
)
const (
ActionTable = "projections.actions2"
ActionTable = "projections.actions3"
ActionIDCol = "id"
ActionCreationDateCol = "creation_date"
ActionChangeDateCol = "change_date"
@@ -25,6 +26,7 @@ const (
ActionScriptCol = "script"
ActionTimeoutCol = "timeout"
ActionAllowedToFailCol = "allowed_to_fail"
ActionOwnerRemovedCol = "owner_removed"
)
type actionProjection struct {
@@ -48,9 +50,11 @@ func newActionProjection(ctx context.Context, config crdb.StatementHandlerConfig
crdb.NewColumn(ActionScriptCol, crdb.ColumnTypeText, crdb.Default("")),
crdb.NewColumn(ActionTimeoutCol, crdb.ColumnTypeInt64, crdb.Default(0)),
crdb.NewColumn(ActionAllowedToFailCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(ActionOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ActionInstanceIDCol, ActionIDCol),
crdb.WithIndex(crdb.NewIndex("actions_ro_idx", []string{ActionResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{ActionResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{ActionOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -84,6 +88,15 @@ func (p *actionProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -172,7 +185,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 {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-hwdqa", "reduce.wrong.event.type% s", action.ReactivatedEventType)
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-hwdqa", "reduce.wrong.event.type %s", action.ReactivatedEventType)
}
return crdb.NewUpdateStatement(
e,
@@ -201,3 +214,22 @@ func (p *actionProjection) reduceActionRemoved(event eventstore.Event) (*handler
},
), nil
}
func (p *actionProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-mSmWM", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(ActionChangeDateCol, e.CreationDate()),
handler.NewCol(ActionSequenceCol, e.Sequence()),
handler.NewCol(ActionOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(ActionInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(ActionResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
+37 -6
View File
@@ -11,6 +11,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/action"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
)
func TestActionProjection_reduces(t *testing.T) {
@@ -40,7 +41,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.actions2 (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)",
expectedStmt: "INSERT INTO projections.actions3 (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{},
@@ -76,7 +77,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.actions3 SET (change_date, sequence, name, script) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -107,7 +108,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.actions3 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -137,7 +138,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions2 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.actions3 SET (change_date, sequence, action_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -167,7 +168,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.actions2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.actions3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -177,6 +178,36 @@ func TestActionProjection_reduces(t *testing.T) {
},
},
},
{
name: "reduceOwnerRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&actionProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.actions3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "reduceInstanceRemoved",
args: args{
@@ -194,7 +225,7 @@ func TestActionProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.actions2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.actions3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+41 -9
View File
@@ -10,11 +10,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
const (
AppProjectionTable = "projections.apps3"
AppProjectionTable = "projections.apps4"
AppAPITable = AppProjectionTable + "_" + appAPITableSuffix
AppOIDCTable = AppProjectionTable + "_" + appOIDCTableSuffix
AppSAMLTable = AppProjectionTable + "_" + appSAMLTableSuffix
@@ -28,6 +29,7 @@ const (
AppColumnInstanceID = "instance_id"
AppColumnState = "state"
AppColumnSequence = "sequence"
AppColumnOwnerRemoved = "owner_removed"
appAPITableSuffix = "api_configs"
AppAPIConfigColumnAppID = "app_id"
@@ -83,10 +85,11 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(AppColumnInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(AppColumnState, crdb.ColumnTypeEnum),
crdb.NewColumn(AppColumnSequence, crdb.ColumnTypeInt64),
crdb.NewColumn(AppColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(AppColumnInstanceID, AppColumnID),
crdb.WithIndex(crdb.NewIndex("app3_project_id_idx", []string{AppColumnProjectID})),
crdb.WithConstraint(crdb.NewConstraint("app3_id_unique", []string{AppColumnID})),
crdb.WithIndex(crdb.NewIndex("project_id", []string{AppColumnProjectID})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{AppColumnOwnerRemoved})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AppAPIConfigColumnAppID, crdb.ColumnTypeText),
@@ -97,8 +100,8 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
},
crdb.NewPrimaryKey(AppAPIConfigColumnInstanceID, AppAPIConfigColumnAppID),
appAPITableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_api_ref_apps3")),
crdb.WithIndex(crdb.NewIndex("api_client_id3_idx", []string{AppAPIConfigColumnClientID})),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
crdb.WithIndex(crdb.NewIndex("client_id", []string{AppAPIConfigColumnClientID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AppOIDCConfigColumnAppID, crdb.ColumnTypeText),
@@ -122,8 +125,8 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
},
crdb.NewPrimaryKey(AppOIDCConfigColumnInstanceID, AppOIDCConfigColumnAppID),
appOIDCTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_oidc_ref_apps3")),
crdb.WithIndex(crdb.NewIndex("oidc_client_id_idx3", []string{AppOIDCConfigColumnClientID})),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
crdb.WithIndex(crdb.NewIndex("client_id", []string{AppOIDCConfigColumnClientID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(AppSAMLConfigColumnAppID, crdb.ColumnTypeText),
@@ -134,8 +137,8 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
},
crdb.NewPrimaryKey(AppSAMLConfigColumnInstanceID, AppSAMLConfigColumnAppID),
appSAMLTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_saml_ref_apps3")),
crdb.WithIndex(crdb.NewIndex("saml_entity_id_idx3", []string{AppSAMLConfigColumnEntityID})),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
crdb.WithIndex(crdb.NewIndex("entity_id", []string{AppSAMLConfigColumnEntityID})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -205,6 +208,15 @@ func (p *appProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -574,6 +586,26 @@ func (p *appProjection) reduceOIDCConfigSecretChanged(event eventstore.Event) (*
), nil
}
func (p *appProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Hyd1f", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(AppColumnChangeDate, e.CreationDate()),
handler.NewCol(AppColumnSequence, e.Sequence()),
handler.NewCol(AppColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(AppColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(AppColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
func (p *appProjection) reduceSAMLConfigAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.SAMLConfigAddedEvent)
if !ok {
+50 -19
View File
@@ -11,6 +11,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
@@ -44,7 +45,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps3 (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.apps4 (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",
@@ -81,7 +82,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps4 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
"my-app",
anyArg{},
@@ -113,7 +114,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps4 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateInactive,
anyArg{},
@@ -145,7 +146,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps4 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateActive,
anyArg{},
@@ -177,7 +178,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps3 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps4 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -204,7 +205,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps3 WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps4 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -231,7 +232,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.apps4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -262,7 +263,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps3_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.apps4_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -272,7 +273,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -306,7 +307,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
domain.APIAuthMethodTypePrivateKeyJWT,
@@ -315,7 +316,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -368,7 +369,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3_api_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps4_api_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -376,7 +377,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -423,7 +424,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps3_oidc_configs (app_id, instance_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, $18)",
expectedStmt: "INSERT INTO projections.apps4_oidc_configs (app_id, instance_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, $18)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -446,7 +447,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -491,7 +492,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3_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) AND (instance_id = $16)",
expectedStmt: "UPDATE projections.apps4_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) AND (instance_id = $16)",
expectedArgs: []interface{}{
domain.OIDCVersionV1,
database.StringArray{"redirect.one.ch", "redirect.two.ch"},
@@ -512,7 +513,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -565,7 +566,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps3_oidc_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps4_oidc_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -573,7 +574,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -585,6 +586,36 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
},
{
name: "project.reduceOwnerRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&appProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+64 -20
View File
@@ -10,14 +10,16 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
AuthNKeyTable = "projections.authn_keys"
AuthNKeyTable = "projections.authn_keys2"
AuthNKeyIDCol = "id"
AuthNKeyCreationDateCol = "creation_date"
AuthNKeyChangeDateCol = "change_date"
AuthNKeyResourceOwnerCol = "resource_owner"
AuthNKeyInstanceIDCol = "instance_id"
AuthNKeyAggregateIDCol = "aggregate_id"
@@ -28,6 +30,7 @@ const (
AuthNKeyPublicKeyCol = "public_key"
AuthNKeyTypeCol = "type"
AuthNKeyEnabledCol = "enabled"
AuthNKeyOwnerRemovedCol = "owner_removed"
)
type authNKeyProjection struct {
@@ -42,6 +45,7 @@ func newAuthNKeyProjection(ctx context.Context, config crdb.StatementHandlerConf
crdb.NewTable([]*crdb.Column{
crdb.NewColumn(AuthNKeyIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AuthNKeyCreationDateCol, crdb.ColumnTypeTimestamp),
crdb.NewColumn(AuthNKeyChangeDateCol, crdb.ColumnTypeTimestamp),
crdb.NewColumn(AuthNKeyResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(AuthNKeyInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AuthNKeyAggregateIDCol, crdb.ColumnTypeText),
@@ -52,10 +56,12 @@ func newAuthNKeyProjection(ctx context.Context, config crdb.StatementHandlerConf
crdb.NewColumn(AuthNKeyPublicKeyCol, crdb.ColumnTypeBytes),
crdb.NewColumn(AuthNKeyEnabledCol, crdb.ColumnTypeBool, crdb.Default(true)),
crdb.NewColumn(AuthNKeyTypeCol, crdb.ColumnTypeEnum, crdb.Default(0)),
crdb.NewColumn(AuthNKeyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(AuthNKeyInstanceIDCol, AuthNKeyIDCol),
crdb.WithIndex(crdb.NewIndex("enabled_idx", []string{AuthNKeyEnabledCol})),
crdb.WithIndex(crdb.NewIndex("identifier_idx", []string{AuthNKeyIdentifierCol})),
crdb.WithIndex(crdb.NewIndex("enabled", []string{AuthNKeyEnabledCol})),
crdb.WithIndex(crdb.NewIndex("identifier", []string{AuthNKeyIdentifierCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{AuthNKeyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -110,6 +116,15 @@ func (p *authNKeyProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -152,29 +167,30 @@ func (p *authNKeyProjection) reduceAuthNKeyAdded(event eventstore.Event) (*handl
default:
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Dgb32", "reduce.wrong.event.type %v", []eventstore.EventType{project.ApplicationKeyAddedEventType, user.MachineKeyAddedEventType})
}
return crdb.NewMultiStatement(
return crdb.NewCreateStatement(
&authNKeyEvent,
crdb.AddCreateStatement(
[]handler.Column{
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),
handler.NewCol(AuthNKeyExpirationCol, authNKeyEvent.expiration),
handler.NewCol(AuthNKeyIdentifierCol, authNKeyEvent.identifier),
handler.NewCol(AuthNKeyPublicKeyCol, authNKeyEvent.publicKey),
handler.NewCol(AuthNKeyTypeCol, authNKeyEvent.keyType),
},
),
[]handler.Column{
handler.NewCol(AuthNKeyIDCol, authNKeyEvent.keyID),
handler.NewCol(AuthNKeyCreationDateCol, authNKeyEvent.CreationDate()),
handler.NewCol(AuthNKeyChangeDateCol, 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),
handler.NewCol(AuthNKeyExpirationCol, authNKeyEvent.expiration),
handler.NewCol(AuthNKeyIdentifierCol, authNKeyEvent.identifier),
handler.NewCol(AuthNKeyPublicKeyCol, authNKeyEvent.publicKey),
handler.NewCol(AuthNKeyTypeCol, authNKeyEvent.keyType),
},
), nil
}
func (p *authNKeyProjection) reduceAuthNKeyEnabledChanged(event eventstore.Event) (*handler.Statement, error) {
var appID string
var enabled bool
var changeDate time.Time
var sequence uint64
switch e := event.(type) {
case *project.APIConfigChangedEvent:
if e.AuthMethodType == nil {
@@ -182,18 +198,26 @@ func (p *authNKeyProjection) reduceAuthNKeyEnabledChanged(event eventstore.Event
}
appID = e.AppID
enabled = *e.AuthMethodType == domain.APIAuthMethodTypePrivateKeyJWT
changeDate = e.CreationDate()
sequence = e.Sequence()
case *project.OIDCConfigChangedEvent:
if e.AuthMethodType == nil {
return crdb.NewNoOpStatement(event), nil
}
appID = e.AppID
enabled = *e.AuthMethodType == domain.OIDCAuthMethodTypePrivateKeyJWT
changeDate = e.CreationDate()
sequence = e.Sequence()
default:
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Dbrt1", "reduce.wrong.event.type %v", []eventstore.EventType{project.APIConfigChangedType, project.OIDCConfigChangedType})
}
return crdb.NewUpdateStatement(
event,
[]handler.Column{handler.NewCol(AuthNKeyEnabledCol, enabled)},
[]handler.Column{
handler.NewCol(AuthNKeyChangeDateCol, changeDate),
handler.NewCol(AuthNKeySequenceCol, sequence),
handler.NewCol(AuthNKeyEnabledCol, enabled),
},
[]handler.Condition{
handler.NewCond(AuthNKeyObjectIDCol, appID),
handler.NewCond(AuthNKeyInstanceIDCol, event.Aggregate().InstanceID),
@@ -225,3 +249,23 @@ func (p *authNKeyProjection) reduceAuthNKeyRemoved(event eventstore.Event) (*han
},
), nil
}
func (p *authNKeyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Hyd1f", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(AuthNKeyChangeDateCol, e.CreationDate()),
handler.NewCol(AuthNKeySequenceCol, e.Sequence()),
handler.NewCol(AuthNKeyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(AuthNKeyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(AuthNKeyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
+55 -14
View File
@@ -9,6 +9,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -40,10 +41,11 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.authn_keys2 (id, creation_date, change_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, $12)",
expectedArgs: []interface{}{
"keyId",
anyArg{},
anyArg{},
"ro-id",
"instance-id",
"agg-id",
@@ -76,10 +78,11 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.authn_keys2 (id, creation_date, change_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, $12)",
expectedArgs: []interface{}{
"keyId",
anyArg{},
anyArg{},
"ro-id",
"instance-id",
"agg-id",
@@ -112,7 +115,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"keyId",
"instance-id",
@@ -158,8 +161,10 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, enabled) = ($1, $2, $3) WHERE (object_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
false,
"appId",
"instance-id",
@@ -186,8 +191,10 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, enabled) = ($1, $2, $3) WHERE (object_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"appId",
"instance-id",
@@ -214,7 +221,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"keyId",
"instance-id",
@@ -241,7 +248,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -286,8 +293,10 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, enabled) = ($1, $2, $3) WHERE (object_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
false,
"appId",
"instance-id",
@@ -314,8 +323,10 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, enabled) = ($1, $2, $3) WHERE (object_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"appId",
"instance-id",
@@ -342,7 +353,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"keyId",
"instance-id",
@@ -369,7 +380,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (object_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (object_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"appId",
"instance-id",
@@ -396,7 +407,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -423,7 +434,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"keyId",
"instance-id",
@@ -450,7 +461,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.authn_keys WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.authn_keys2 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -460,6 +471,36 @@ func TestAuthNKeyProjection_reduces(t *testing.T) {
},
},
},
{
name: "reduceOwnerRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&authNKeyProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.authn_keys2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -13,7 +13,7 @@ import (
)
const (
CustomTextTable = "projections.custom_texts"
CustomTextTable = "projections.custom_texts2"
CustomTextAggregateIDCol = "aggregate_id"
CustomTextInstanceIDCol = "instance_id"
@@ -25,6 +25,7 @@ const (
CustomTextLanguageCol = "language"
CustomTextKeyCol = "key"
CustomTextTextCol = "text"
CustomTextOwnerRemovedCol = "owner_removed"
)
type customTextProjection struct {
@@ -47,8 +48,10 @@ func newCustomTextProjection(ctx context.Context, config crdb.StatementHandlerCo
crdb.NewColumn(CustomTextLanguageCol, crdb.ColumnTypeText),
crdb.NewColumn(CustomTextKeyCol, crdb.ColumnTypeText),
crdb.NewColumn(CustomTextTextCol, crdb.ColumnTypeText),
crdb.NewColumn(CustomTextOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(CustomTextInstanceIDCol, CustomTextAggregateIDCol, CustomTextTemplateCol, CustomTextKeyCol, CustomTextLanguageCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{CustomTextOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -72,6 +75,10 @@ func (p *customTextProjection) reducers() []handler.AggregateReducer {
Event: org.CustomTextTemplateRemovedEventType,
Reduce: p.reduceTemplateRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -174,3 +181,23 @@ func (p *customTextProjection) reduceTemplateRemoved(event eventstore.Event) (*h
handler.NewCond(CustomTextInstanceIDCol, customTextEvent.Aggregate().InstanceID),
}), nil
}
func (p *customTextProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-V2T3z", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(CustomTextChangeDateCol, e.CreationDate()),
handler.NewCol(CustomTextSequenceCol, e.Sequence()),
handler.NewCol(CustomTextOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(CustomTextInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(CustomTextAggregateIDCol, e.Aggregate().ID),
},
), nil
}
+37 -7
View File
@@ -43,7 +43,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedStmt: "INSERT INTO projections.custom_texts2 (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) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -82,7 +82,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4) AND (instance_id = $5)",
expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
"agg-id",
"InitCode",
@@ -116,7 +116,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"agg-id",
"InitCode",
@@ -145,7 +145,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.custom_texts WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -176,7 +176,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedStmt: "INSERT INTO projections.custom_texts2 (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) ON CONFLICT (instance_id, aggregate_id, template, key, language) DO UPDATE SET (creation_date, change_date, sequence, is_default, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.is_default, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -215,7 +215,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4) AND (instance_id = $5)",
expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (aggregate_id = $1) AND (template = $2) AND (key = $3) AND (language = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
"agg-id",
"InitCode",
@@ -249,7 +249,7 @@ func TestCustomTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.custom_texts WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.custom_texts2 WHERE (aggregate_id = $1) AND (template = $2) AND (language = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"agg-id",
"InitCode",
@@ -261,6 +261,36 @@ func TestCustomTextProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&customTextProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.custom_texts2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
DomainPolicyTable = "projections.domain_policies"
DomainPolicyTable = "projections.domain_policies2"
DomainPolicyIDCol = "id"
DomainPolicyCreationDateCol = "creation_date"
@@ -27,6 +27,7 @@ const (
DomainPolicyIsDefaultCol = "is_default"
DomainPolicyResourceOwnerCol = "resource_owner"
DomainPolicyInstanceIDCol = "instance_id"
DomainPolicyOwnerRemovedCol = "owner_removed"
)
type domainPolicyProjection struct {
@@ -50,8 +51,10 @@ func newDomainPolicyProjection(ctx context.Context, config crdb.StatementHandler
crdb.NewColumn(DomainPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(DomainPolicyResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(DomainPolicyInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(DomainPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(DomainPolicyInstanceIDCol, DomainPolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{DomainPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -75,6 +78,10 @@ func (p *domainPolicyProjection) reducers() []handler.AggregateReducer {
Event: org.DomainPolicyRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -171,3 +178,23 @@ func (p *domainPolicyProjection) reduceRemoved(event eventstore.Event) (*handler
handler.NewCond(DomainPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
}), nil
}
func (p *domainPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-JYD2K", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(DomainPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(DomainPolicySequenceCol, e.Sequence()),
handler.NewCol(DomainPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(DomainPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(DomainPolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -43,7 +43,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.domain_policies2 (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -83,7 +83,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.domain_policies2 SET (change_date, sequence, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -115,7 +115,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.domain_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.domain_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -142,7 +142,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.domain_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.domain_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -172,7 +172,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.domain_policies2 (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -212,7 +212,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.domain_policies2 SET (change_date, sequence, user_login_must_be_domain, validate_org_domains, smtp_sender_address_matches_instance_domain) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -227,6 +227,36 @@ func TestDomainPolicyProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&domainPolicyProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.domain_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -12,7 +12,7 @@ import (
)
const (
FlowTriggerTable = "projections.flows_triggers"
FlowTriggerTable = "projections.flow_triggers2"
FlowTypeCol = "flow_type"
FlowChangeDateCol = "change_date"
FlowSequenceCol = "sequence"
@@ -21,6 +21,7 @@ const (
FlowInstanceIDCol = "instance_id"
FlowActionTriggerSequenceCol = "trigger_sequence"
FlowActionIDCol = "action_id"
FlowOwnerRemovedCol = "owner_removed"
)
type flowProjection struct {
@@ -41,8 +42,10 @@ func newFlowProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(FlowInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(FlowActionTriggerSequenceCol, crdb.ColumnTypeInt64),
crdb.NewColumn(FlowActionIDCol, crdb.ColumnTypeText),
crdb.NewColumn(FlowOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(FlowInstanceIDCol, FlowTypeCol, FlowTriggerTypeCol, FlowResourceOwnerCol, FlowActionIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{FlowOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -62,6 +65,10 @@ func (p *flowProjection) reducers() []handler.AggregateReducer {
Event: org.FlowClearedEventType,
Reduce: p.reduceFlowClearedEventType,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -121,3 +128,23 @@ func (p *flowProjection) reduceFlowClearedEventType(event eventstore.Event) (*ha
},
), nil
}
func (p *flowProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Yd7WC", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(FlowChangeDateCol, e.CreationDate()),
handler.NewCol(FlowSequenceCol, e.Sequence()),
handler.NewCol(FlowOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(FlowInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(FlowResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
+35 -5
View File
@@ -39,7 +39,7 @@ func TestFlowProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (trigger_type = $2) AND (resource_owner = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.flow_triggers2 WHERE (flow_type = $1) AND (trigger_type = $2) AND (resource_owner = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
domain.FlowTypeExternalAuthentication,
domain.TriggerTypePostAuthentication,
@@ -48,7 +48,7 @@ func TestFlowProjection_reduces(t *testing.T) {
},
},
{
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)",
expectedStmt: "INSERT INTO projections.flow_triggers2 (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",
@@ -61,7 +61,7 @@ func TestFlowProjection_reduces(t *testing.T) {
},
},
{
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)",
expectedStmt: "INSERT INTO projections.flow_triggers2 (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",
@@ -94,7 +94,7 @@ func TestFlowProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (flow_type = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.flow_triggers2 WHERE (flow_type = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
domain.FlowTypeExternalAuthentication,
"ro-id",
@@ -105,6 +105,36 @@ func TestFlowProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&flowProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.flow_triggers2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -122,7 +152,7 @@ func TestFlowProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.flows_triggers WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.flow_triggers2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+31 -5
View File
@@ -15,7 +15,7 @@ import (
)
const (
IDPTable = "projections.idps2"
IDPTable = "projections.idps3"
IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix
IDPJWTTable = IDPTable + "_" + IDPJWTSuffix
@@ -34,6 +34,7 @@ const (
IDPOwnerTypeCol = "owner_type"
IDPAutoRegisterCol = "auto_register"
IDPTypeCol = "type"
IDPOwnerRemovedCol = "owner_removed"
OIDCConfigIDPIDCol = "idp_id"
OIDCConfigInstanceIDCol = "instance_id"
@@ -76,10 +77,11 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(IDPOwnerTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(IDPAutoRegisterCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(IDPTypeCol, crdb.ColumnTypeEnum, crdb.Nullable()),
crdb.NewColumn(IDPOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(IDPInstanceIDCol, IDPIDCol),
crdb.WithIndex(crdb.NewIndex("idp_ro_idx", []string{IDPResourceOwnerCol})),
crdb.WithConstraint(crdb.NewConstraint("idp_id_unique", []string{IDPIDCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{IDPResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPOwnerRemovedCol})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(OIDCConfigIDPIDCol, crdb.ColumnTypeText),
@@ -95,7 +97,7 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
},
crdb.NewPrimaryKey(OIDCConfigInstanceIDCol, OIDCConfigIDPIDCol),
IDPOIDCSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_oidc_ref_idp")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(JWTConfigIDPIDCol, crdb.ColumnTypeText),
@@ -107,7 +109,7 @@ func newIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
},
crdb.NewPrimaryKey(JWTConfigInstanceIDCol, JWTConfigIDPIDCol),
IDPJWTSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_jwt_ref_idp")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -200,6 +202,10 @@ func (p *idpProjection) reducers() []handler.AggregateReducer {
Event: org.IDPJWTConfigChangedEventType,
Reduce: p.reduceJWTConfigChanged,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
}
@@ -541,3 +547,23 @@ func (p *idpProjection) reduceJWTConfigChanged(event eventstore.Event) (*handler
),
), nil
}
func (p *idpProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-YsbQC", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(IDPChangeDateCol, e.CreationDate()),
handler.NewCol(IDPSequenceCol, e.Sequence()),
handler.NewCol(IDPOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(IDPInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(IDPResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -14,7 +14,7 @@ import (
)
const (
IDPLoginPolicyLinkTable = "projections.idp_login_policy_links3"
IDPLoginPolicyLinkTable = "projections.idp_login_policy_links4"
IDPLoginPolicyLinkIDPIDCol = "idp_id"
IDPLoginPolicyLinkAggregateIDCol = "aggregate_id"
@@ -24,6 +24,7 @@ const (
IDPLoginPolicyLinkResourceOwnerCol = "resource_owner"
IDPLoginPolicyLinkInstanceIDCol = "instance_id"
IDPLoginPolicyLinkProviderTypeCol = "provider_type"
IDPLoginPolicyLinkOwnerRemovedCol = "owner_removed"
)
type idpLoginPolicyLinkProjection struct {
@@ -44,9 +45,11 @@ func newIDPLoginPolicyLinkProjection(ctx context.Context, config crdb.StatementH
crdb.NewColumn(IDPLoginPolicyLinkResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPLoginPolicyLinkInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPLoginPolicyLinkProviderTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(IDPLoginPolicyLinkOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(IDPLoginPolicyLinkInstanceIDCol, IDPLoginPolicyLinkAggregateIDCol, IDPLoginPolicyLinkIDPIDCol),
crdb.WithIndex(crdb.NewIndex("link_ro_idx", []string{IDPLoginPolicyLinkResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{IDPLoginPolicyLinkResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPLoginPolicyLinkOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -74,14 +77,14 @@ func (p *idpLoginPolicyLinkProjection) reducers() []handler.AggregateReducer {
Event: org.LoginPolicyRemovedEventType,
Reduce: p.reducePolicyRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOrgRemoved,
},
{
Event: org.IDPConfigRemovedEventType,
Reduce: p.reduceIDPConfigRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -206,19 +209,6 @@ func (p *idpLoginPolicyLinkProjection) reduceIDPConfigRemoved(event eventstore.E
), nil
}
func (p *idpLoginPolicyLinkProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-QSoSe", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewDeleteStatement(e,
[]handler.Condition{
handler.NewCond(IDPLoginPolicyLinkResourceOwnerCol, e.Aggregate().ID),
handler.NewCond(IDPLoginPolicyLinkInstanceIDCol, event.Aggregate().InstanceID),
},
), nil
}
func (p *idpLoginPolicyLinkProjection) reducePolicyRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.LoginPolicyRemovedEvent)
if !ok {
@@ -231,3 +221,23 @@ func (p *idpLoginPolicyLinkProjection) reducePolicyRemoved(event eventstore.Even
},
), nil
}
func (p *idpLoginPolicyLinkProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-YbhOv", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(IDPLoginPolicyLinkChangeDateCol, e.CreationDate()),
handler.NewCol(IDPLoginPolicyLinkSequenceCol, e.Sequence()),
handler.NewCol(IDPLoginPolicyLinkOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(IDPLoginPolicyLinkInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(IDPLoginPolicyLinkResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -42,7 +42,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_login_policy_links3 (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.idp_login_policy_links4 (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",
@@ -78,7 +78,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -109,7 +109,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -140,7 +140,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_login_policy_links3 (idp_id, aggregate_id, creation_date, change_date, sequence, resource_owner, instance_id, provider_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.idp_login_policy_links4 (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",
@@ -176,7 +176,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -204,7 +204,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -233,7 +233,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (aggregate_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -244,33 +244,6 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
},
},
},
{
name: "reduceOrgRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
[]byte(`{}`),
), org.OrgRemovedEventMapper),
},
reduce: (&idpLoginPolicyLinkProjection{}).reduceOrgRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (resource_owner = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
},
},
},
},
},
},
{
name: "reducePolicyRemoved",
args: args{
@@ -288,7 +261,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -317,7 +290,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
@@ -347,7 +320,7 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_login_policy_links3 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_login_policy_links4 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
@@ -358,6 +331,36 @@ func TestIDPLoginPolicyLinkProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&idpLoginPolicyLinkProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idp_login_policy_links4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+57 -27
View File
@@ -46,7 +46,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idps2 (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)",
expectedStmt: "INSERT INTO projections.idps3 (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{},
@@ -87,7 +87,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.idps3 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
"custom-zitadel-instance",
domain.IDPConfigStylingTypeGoogle,
@@ -121,7 +121,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateInactive,
anyArg{},
@@ -153,7 +153,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateActive,
anyArg{},
@@ -185,7 +185,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idps2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idps3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -212,7 +212,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idps2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.idps3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -252,7 +252,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -262,7 +262,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps2_oidc_config (idp_id, instance_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, $10)",
expectedStmt: "INSERT INTO projections.idps3_oidc_config (idp_id, instance_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, $10)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -311,7 +311,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -320,7 +320,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps2_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) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.idps3_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) AND (instance_id = $10)",
expectedArgs: []interface{}{
"client-id",
anyArg{},
@@ -380,7 +380,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -390,7 +390,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps2_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedStmt: "INSERT INTO projections.idps3_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -427,7 +427,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -436,7 +436,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps2_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.idps3_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
"https://api.zitadel.ch/jwt",
"issuer",
@@ -492,7 +492,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idps2 (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)",
expectedStmt: "INSERT INTO projections.idps3 (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{},
@@ -533,7 +533,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.idps3 SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
"custom-zitadel-instance",
domain.IDPConfigStylingTypeGoogle,
@@ -567,7 +567,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateInactive,
anyArg{},
@@ -599,7 +599,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.IDPConfigStateActive,
anyArg{},
@@ -631,7 +631,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idps2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idps3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -672,7 +672,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -682,7 +682,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps2_oidc_config (idp_id, instance_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, $10)",
expectedStmt: "INSERT INTO projections.idps3_oidc_config (idp_id, instance_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, $10)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -731,7 +731,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -740,7 +740,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps2_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) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.idps3_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) AND (instance_id = $10)",
expectedArgs: []interface{}{
"client-id",
anyArg{},
@@ -800,7 +800,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, type) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -810,7 +810,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.idps2_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedStmt: "INSERT INTO projections.idps3_jwt_config (idp_id, instance_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5, $6)",
expectedArgs: []interface{}{
"idp-config-id",
"instance-id",
@@ -847,7 +847,7 @@ func TestIDPProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -856,7 +856,7 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.idps2_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.idps3_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
"https://api.zitadel.ch/jwt",
"issuer",
@@ -889,6 +889,36 @@ func TestIDPProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&idpProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.idps3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+15 -6
View File
@@ -13,7 +13,7 @@ import (
)
const (
IDPUserLinkTable = "projections.idp_user_links2"
IDPUserLinkTable = "projections.idp_user_links3"
IDPUserLinkIDPIDCol = "idp_id"
IDPUserLinkUserIDCol = "user_id"
IDPUserLinkExternalUserIDCol = "external_user_id"
@@ -23,6 +23,7 @@ const (
IDPUserLinkResourceOwnerCol = "resource_owner"
IDPUserLinkInstanceIDCol = "instance_id"
IDPUserLinkDisplayNameCol = "display_name"
IDPUserLinkOwnerRemovedCol = "owner_removed"
)
type idpUserLinkProjection struct {
@@ -44,9 +45,11 @@ func newIDPUserLinkProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(IDPUserLinkResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPUserLinkInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPUserLinkDisplayNameCol, crdb.ColumnTypeText),
crdb.NewColumn(IDPUserLinkOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(IDPUserLinkInstanceIDCol, IDPUserLinkIDPIDCol, IDPUserLinkExternalUserIDCol),
crdb.WithIndex(crdb.NewIndex("idp_user_idx", []string{IDPUserLinkUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{IDPUserLinkUserIDCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{IDPUserLinkOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -85,7 +88,7 @@ func (p *idpUserLinkProjection) reducers() []handler.AggregateReducer {
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOrgRemoved,
Reduce: p.reduceOwnerRemoved,
},
},
},
@@ -158,13 +161,19 @@ func (p *idpUserLinkProjection) reduceCascadeRemoved(event eventstore.Event) (*h
), nil
}
func (p *idpUserLinkProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *idpUserLinkProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-AZmfJ", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-PGiAY", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewDeleteStatement(e,
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(IDPUserLinkChangeDateCol, e.CreationDate()),
handler.NewCol(IDPUserLinkSequenceCol, e.Sequence()),
handler.NewCol(IDPUserLinkOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(IDPUserLinkResourceOwnerCol, e.Aggregate().ID),
handler.NewCond(IDPUserLinkInstanceIDCol, e.Aggregate().InstanceID),
+13 -10
View File
@@ -43,7 +43,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.idp_user_links2 (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)",
expectedStmt: "INSERT INTO projections.idp_user_links3 (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",
@@ -80,7 +80,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -112,7 +112,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (idp_id = $1) AND (user_id = $2) AND (external_user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"idp-config-id",
"agg-id",
@@ -125,7 +125,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
},
},
{
name: "reduceOrgRemoved",
name: "reduceOwnerRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
@@ -133,7 +133,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
[]byte(`{}`),
), org.OrgRemovedEventMapper),
},
reduce: (&idpUserLinkProjection{}).reduceOrgRemoved,
reduce: (&idpUserLinkProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
@@ -141,8 +141,11 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (resource_owner = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.idp_user_links3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (resource_owner = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"agg-id",
"instance-id",
},
@@ -168,7 +171,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -194,7 +197,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -223,7 +226,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
@@ -253,7 +256,7 @@ func TestIDPUserLinkProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.idp_user_links2 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.idp_user_links3 WHERE (idp_id = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"idp-config-id",
"ro-id",
+27 -3
View File
@@ -8,11 +8,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
InstanceMemberProjectionTable = "projections.instance_members2"
InstanceMemberProjectionTable = "projections.instance_members3"
InstanceMemberIAMIDCol = "id"
)
@@ -29,7 +30,8 @@ func newInstanceMemberProjection(ctx context.Context, config crdb.StatementHandl
crdb.NewTable(
append(memberColumns, crdb.NewColumn(InstanceColumnID, crdb.ColumnTypeText)),
crdb.NewPrimaryKey(MemberInstanceID, InstanceColumnID, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("inst_memb_user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_owner_removed", []string{MemberUserOwnerRemoved})),
),
)
@@ -64,6 +66,15 @@ func (p *instanceMemberProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceUserOwnerRemoved,
},
},
},
{
Aggregate: user.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -81,7 +92,12 @@ func (p *instanceMemberProjection) reduceAdded(event eventstore.Event) (*handler
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-pGNCu", "reduce.wrong.event.type %s", instance.MemberAddedEventType)
}
return reduceMemberAdded(e.MemberAddedEvent, withMemberCol(InstanceMemberIAMIDCol, e.Aggregate().ID))
ctx := setMemberContext(e.Aggregate())
userOwner, err := getResourceOwnerOfUser(ctx, p.Eventstore, e.Aggregate().InstanceID, e.UserID)
if err != nil {
return nil, err
}
return reduceMemberAdded(e.MemberAddedEvent, userOwner, withMemberCol(InstanceMemberIAMIDCol, e.Aggregate().ID))
}
func (p *instanceMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) {
@@ -115,3 +131,11 @@ func (p *instanceMemberProjection) reduceUserRemoved(event eventstore.Event) (*h
}
return reduceMemberRemoved(e, withMemberCond(MemberUserIDCol, e.Aggregate().ID))
}
func (p *instanceMemberProjection) reduceUserOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-mkDHa", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return reduceMemberUserOwnerRemoved(e)
}
@@ -1,14 +1,19 @@
package projection
import (
"context"
"testing"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -34,7 +39,21 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
}`),
), instance.MemberAddedEventMapper),
},
reduce: (&instanceMemberProjection{}).reduceAdded,
reduce: (&instanceMemberProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: instance.AggregateType,
sequence: 15,
@@ -42,15 +61,18 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.instance_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.instance_members3 (user_id, user_resource_owner, user_owner_removed, roles, creation_date, change_date, sequence, resource_owner, instance_id, owner_removed, id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"user-id",
"org1",
false,
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
"ro-id",
"instance-id",
false,
"agg-id",
},
},
@@ -78,7 +100,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.instance_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5)",
expectedStmt: "UPDATE projections.instance_members3 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5)",
expectedArgs: []interface{}{
database.StringArray{"role", "changed"},
anyArg{},
@@ -110,7 +132,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.instance_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -139,7 +161,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.instance_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -166,7 +188,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.instance_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -176,6 +198,36 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.OrgRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&instanceMemberProjection{}).reduceUserOwnerRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.instance_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -193,7 +245,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.instance_members2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.instance_members3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+4 -5
View File
@@ -14,7 +14,7 @@ import (
)
const (
KeyProjectionTable = "projections.keys3"
KeyProjectionTable = "projections.keys4"
KeyPrivateTable = KeyProjectionTable + "_" + privateKeyTableSuffix
KeyPublicTable = KeyProjectionTable + "_" + publicKeyTableSuffix
CertificateTable = KeyProjectionTable + "_" + certificateTableSuffix
@@ -69,7 +69,6 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
crdb.NewColumn(KeyColumnUse, crdb.ColumnTypeEnum, crdb.Default(0)),
},
crdb.NewPrimaryKey(KeyColumnInstanceID, KeyColumnID),
crdb.WithConstraint(crdb.NewConstraint("key3_id_unique", []string{KeyColumnID})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(KeyPrivateColumnID, crdb.ColumnTypeText),
@@ -79,7 +78,7 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
},
crdb.NewPrimaryKey(KeyPrivateColumnInstanceID, KeyPrivateColumnID),
privateKeyTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_private_ref_keys3")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(KeyPublicColumnID, crdb.ColumnTypeText),
@@ -89,7 +88,7 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
},
crdb.NewPrimaryKey(KeyPublicColumnInstanceID, KeyPublicColumnID),
publicKeyTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_public_ref_keys3")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(CertificateColumnID, crdb.ColumnTypeText),
@@ -99,7 +98,7 @@ func newKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, k
},
crdb.NewPrimaryKey(CertificateColumnInstanceID, CertificateColumnID),
certificateTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_certificate_ref_keys3")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
)
p.encryptionAlgorithm = keyEncryptionAlgorithm
+5 -5
View File
@@ -44,7 +44,7 @@ func TestKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.keys3 (id, creation_date, change_date, resource_owner, instance_id, sequence, algorithm, use) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.keys4 (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{},
@@ -57,7 +57,7 @@ func TestKeyProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.keys3_private (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.keys4_private (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -71,7 +71,7 @@ func TestKeyProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.keys3_public (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.keys4_public (id, instance_id, expiry, key) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -117,7 +117,7 @@ func TestKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.keys3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.keys4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -143,7 +143,7 @@ func TestKeyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.keys3_certificate (id, instance_id, expiry, certificate) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.keys4_certificate (id, instance_id, expiry, certificate) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
LabelPolicyTable = "projections.label_policies"
LabelPolicyTable = "projections.label_policies2"
LabelPolicyIDCol = "id"
LabelPolicyCreationDateCol = "creation_date"
@@ -28,6 +28,7 @@ const (
LabelPolicyWatermarkDisabledCol = "watermark_disabled"
LabelPolicyShouldErrorPopupCol = "should_error_popup"
LabelPolicyFontURLCol = "font_url"
LabelPolicyOwnerRemovedCol = "owner_removed"
LabelPolicyLightPrimaryColorCol = "light_primary_color"
LabelPolicyLightWarnColorCol = "light_warn_color"
@@ -78,8 +79,10 @@ func newLabelPolicyProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(LabelPolicyDarkFontColorCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(LabelPolicyDarkLogoURLCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(LabelPolicyDarkIconURLCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(LabelPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LabelPolicyInstanceIDCol, LabelPolicyIDCol, LabelPolicyStateCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LabelPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -151,6 +154,10 @@ func (p *labelPolicyProjection) reducers() []handler.AggregateReducer {
Event: org.LabelPolicyAssetsRemovedEventType,
Reduce: p.reduceAssetsRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -593,3 +600,23 @@ func (p *labelPolicyProjection) reduceAssetsRemoved(event eventstore.Event) (*ha
handler.NewCond(LabelPolicyInstanceIDCol, event.Aggregate().InstanceID),
}), nil
}
func (p *labelPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Su6pX", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(LabelPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(LabelPolicySequenceCol, e.Sequence()),
handler.NewCol(LabelPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LabelPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LabelPolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
+60 -30
View File
@@ -39,7 +39,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.label_policies2 (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{},
@@ -83,7 +83,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.label_policies2 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) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -117,7 +117,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.label_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.label_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -144,7 +144,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.label_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.label_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -170,7 +170,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, 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, instance_id, 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 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, 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) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedStmt: "INSERT INTO projections.label_policies2 (change_date, sequence, state, creation_date, resource_owner, instance_id, 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, instance_id, 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_policies2 AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, 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) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -201,7 +201,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -232,7 +232,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -263,7 +263,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -294,7 +294,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -325,7 +325,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -356,7 +356,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -387,7 +387,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -418,7 +418,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -449,7 +449,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -480,7 +480,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -511,7 +511,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.label_policies2 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) AND (instance_id = $10)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -546,7 +546,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.label_policies2 (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{},
@@ -590,7 +590,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $16)",
expectedStmt: "UPDATE projections.label_policies2 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) AND (instance_id = $16)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -631,7 +631,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.label_policies (change_date, sequence, state, creation_date, resource_owner, instance_id, 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, instance_id, 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 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, 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) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedStmt: "INSERT INTO projections.label_policies2 (change_date, sequence, state, creation_date, resource_owner, instance_id, 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, instance_id, 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_policies2 AS copy_table WHERE copy_table.id = $4 AND copy_table.state = $5 AND copy_table.instance_id = $6 ON CONFLICT (instance_id, id, state) DO UPDATE SET (change_date, sequence, state, creation_date, resource_owner, instance_id, 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) = ($1, $2, $3, EXCLUDED.creation_date, EXCLUDED.resource_owner, EXCLUDED.instance_id, EXCLUDED.id, EXCLUDED.is_default, EXCLUDED.hide_login_name_suffix, EXCLUDED.font_url, EXCLUDED.watermark_disabled, EXCLUDED.should_error_popup, EXCLUDED.light_primary_color, EXCLUDED.light_warn_color, EXCLUDED.light_background_color, EXCLUDED.light_font_color, EXCLUDED.light_logo_url, EXCLUDED.light_icon_url, EXCLUDED.dark_primary_color, EXCLUDED.dark_warn_color, EXCLUDED.dark_background_color, EXCLUDED.dark_font_color, EXCLUDED.dark_logo_url, EXCLUDED.dark_icon_url)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -662,7 +662,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -693,7 +693,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -724,7 +724,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -755,7 +755,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -786,7 +786,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -817,7 +817,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_logo_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -848,7 +848,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, light_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -879,7 +879,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, dark_icon_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -910,7 +910,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -941,7 +941,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, font_url) = ($1, $2, $3) WHERE (id = $4) AND (state = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -972,7 +972,7 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $10)",
expectedStmt: "UPDATE projections.label_policies2 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) AND (instance_id = $10)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -990,6 +990,36 @@ func TestLabelPolicyProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&labelPolicyProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.label_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
LockoutPolicyTable = "projections.lockout_policies"
LockoutPolicyTable = "projections.lockout_policies2"
LockoutPolicyIDCol = "id"
LockoutPolicyCreationDateCol = "creation_date"
@@ -26,6 +26,7 @@ const (
LockoutPolicyInstanceIDCol = "instance_id"
LockoutPolicyMaxPasswordAttemptsCol = "max_password_attempts"
LockoutPolicyShowLockOutFailuresCol = "show_failure"
LockoutPolicyOwnerRemovedCol = "owner_removed"
)
type lockoutPolicyProjection struct {
@@ -48,8 +49,10 @@ func newLockoutPolicyProjection(ctx context.Context, config crdb.StatementHandle
crdb.NewColumn(LockoutPolicyInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(LockoutPolicyMaxPasswordAttemptsCol, crdb.ColumnTypeInt64),
crdb.NewColumn(LockoutPolicyShowLockOutFailuresCol, crdb.ColumnTypeBool),
crdb.NewColumn(LockoutPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LockoutPolicyInstanceIDCol, LockoutPolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LockoutPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -73,6 +76,10 @@ func (p *lockoutPolicyProjection) reducers() []handler.AggregateReducer {
Event: org.LockoutPolicyRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -165,3 +172,23 @@ func (p *lockoutPolicyProjection) reduceRemoved(event eventstore.Event) (*handle
handler.NewCond(LabelPolicyInstanceIDCol, event.Aggregate().InstanceID),
}), nil
}
func (p *lockoutPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-IoW0x", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(LockoutPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(LockoutPolicySequenceCol, e.Sequence()),
handler.NewCol(LockoutPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LockoutPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LockoutPolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -42,7 +42,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.lockout_policies2 (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{},
@@ -80,7 +80,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -111,7 +111,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.lockout_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -138,7 +138,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.lockout_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.lockout_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -167,7 +167,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.lockout_policies2 (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{},
@@ -205,7 +205,7 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.lockout_policies SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, max_password_attempts, show_failure) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -219,6 +219,36 @@ func TestLockoutPolicyProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&lockoutPolicyProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.lockout_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+183 -46
View File
@@ -2,7 +2,9 @@ package projection
import (
"context"
"fmt"
"strings"
sq "github.com/Masterminds/squirrel"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -15,76 +17,160 @@ import (
)
const (
LoginNameProjectionTable = "projections.login_names"
LoginNameTableAlias = "login_names2"
LoginNameProjectionTable = "projections." + LoginNameTableAlias
LoginNameUserProjectionTable = LoginNameProjectionTable + "_" + loginNameUserSuffix
LoginNamePolicyProjectionTable = LoginNameProjectionTable + "_" + loginNamePolicySuffix
LoginNameDomainProjectionTable = LoginNameProjectionTable + "_" + loginNameDomainSuffix
LoginNameCol = "login_name"
LoginNameCol = "login_name"
LoginNameUserCol = "user_id"
LoginNameIsPrimaryCol = "is_primary"
LoginNameInstanceIDCol = "instance_id"
LoginNameOwnerRemovedUserCol = "user_owner_removed"
LoginNameOwnerRemovedPolicyCol = "policy_owner_removed"
LoginNameOwnerRemovedDomainCol = "domain_owner_removed"
usersAlias = "users"
policyCustomAlias = "policy_custom"
policyDefaultAlias = "policy_default"
policyUsersAlias = "policy_users"
domainsAlias = "domains"
domainAlias = "domain"
loginNameUserSuffix = "users"
LoginNameUserIDCol = "id"
LoginNameUserUserNameCol = "user_name"
LoginNameUserResourceOwnerCol = "resource_owner"
LoginNameUserInstanceIDCol = "instance_id"
LoginNameUserOwnerRemovedCol = "owner_removed"
loginNameDomainSuffix = "domains"
LoginNameDomainNameCol = "name"
LoginNameDomainIsPrimaryCol = "is_primary"
LoginNameDomainResourceOwnerCol = "resource_owner"
LoginNameDomainInstanceIDCol = "instance_id"
LoginNameDomainOwnerRemovedCol = "owner_removed"
loginNamePolicySuffix = "policies"
LoginNamePoliciesMustBeDomainCol = "must_be_domain"
LoginNamePoliciesIsDefaultCol = "is_default"
LoginNamePoliciesResourceOwnerCol = "resource_owner"
LoginNamePoliciesInstanceIDCol = "instance_id"
LoginNamePoliciesOwnerRemovedCol = "owner_removed"
)
var (
viewStmt = fmt.Sprintf("SELECT"+
" user_id"+
" , (CASE WHEN %[1]s THEN CONCAT(%[2]s, '@', domain) ELSE %[2]s END) AS login_name"+
" , COALESCE(%[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"+
" , COALESCE(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 AND policy_default.%[10]s = users.%[4]s) 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"+
") AS login_names;",
LoginNamePoliciesMustBeDomainCol,
LoginNameUserUserNameCol,
LoginNameDomainIsPrimaryCol,
LoginNameUserInstanceIDCol,
LoginNameUserResourceOwnerCol,
LoginNameDomainNameCol,
LoginNameUserProjectionTable,
LoginNamePolicyProjectionTable,
LoginNamePoliciesResourceOwnerCol,
LoginNamePoliciesInstanceIDCol,
LoginNamePoliciesIsDefaultCol,
LoginNameDomainProjectionTable,
LoginNameDomainResourceOwnerCol,
LoginNameDomainInstanceIDCol,
)
policyUsers = sq.Select(
alias(
col(usersAlias, LoginNameUserIDCol),
LoginNameUserCol,
),
col(usersAlias, LoginNameUserUserNameCol),
col(usersAlias, LoginNameUserInstanceIDCol),
col(usersAlias, LoginNameUserResourceOwnerCol),
alias(
coalesce(col(policyCustomAlias, LoginNamePoliciesMustBeDomainCol), col(policyDefaultAlias, LoginNamePoliciesMustBeDomainCol)),
LoginNamePoliciesMustBeDomainCol,
),
alias(col(usersAlias, LoginNameUserOwnerRemovedCol),
LoginNameOwnerRemovedUserCol),
alias(coalesce(col(policyCustomAlias, LoginNamePoliciesOwnerRemovedCol), "false"),
LoginNameOwnerRemovedPolicyCol),
).From(alias(LoginNameUserProjectionTable, usersAlias)).
LeftJoin(
leftJoin(LoginNamePolicyProjectionTable, policyCustomAlias,
eq(col(policyCustomAlias, LoginNamePoliciesResourceOwnerCol), col(usersAlias, LoginNameUserResourceOwnerCol)),
eq(col(policyCustomAlias, LoginNamePoliciesInstanceIDCol), col(usersAlias, LoginNameUserInstanceIDCol)),
),
).
LeftJoin(
leftJoin(LoginNamePolicyProjectionTable, policyDefaultAlias,
eq(col(policyDefaultAlias, LoginNamePoliciesIsDefaultCol), "true"),
eq(col(policyDefaultAlias, LoginNamePoliciesInstanceIDCol), col(usersAlias, LoginNameUserInstanceIDCol)),
),
)
loginNamesTable = sq.Select(
col(policyUsersAlias, LoginNameUserCol),
col(policyUsersAlias, LoginNameUserUserNameCol),
col(policyUsersAlias, LoginNameUserResourceOwnerCol),
alias(col(policyUsersAlias, LoginNameUserInstanceIDCol),
LoginNameInstanceIDCol),
col(policyUsersAlias, LoginNamePoliciesMustBeDomainCol),
alias(col(domainsAlias, LoginNameDomainNameCol),
domainAlias),
col(domainsAlias, LoginNameDomainIsPrimaryCol),
col(policyUsersAlias, LoginNameOwnerRemovedUserCol),
col(policyUsersAlias, LoginNameOwnerRemovedPolicyCol),
alias(coalesce(col(domainsAlias, LoginNameDomainOwnerRemovedCol), "false"),
LoginNameOwnerRemovedDomainCol),
).FromSelect(policyUsers, policyUsersAlias).
LeftJoin(
leftJoin(LoginNameDomainProjectionTable, domainsAlias,
col(policyUsersAlias, LoginNamePoliciesMustBeDomainCol),
eq(col(policyUsersAlias, LoginNameUserResourceOwnerCol), col(domainsAlias, LoginNameDomainResourceOwnerCol)),
eq(col(policyUsersAlias, LoginNamePoliciesInstanceIDCol), col(domainsAlias, LoginNameDomainInstanceIDCol)),
),
)
viewStmt, _ = sq.Select(
LoginNameUserCol,
alias(
whenThenElse(
LoginNamePoliciesMustBeDomainCol,
concat(LoginNameUserUserNameCol, "'@'", domainAlias),
LoginNameUserUserNameCol),
LoginNameCol),
alias(coalesce(LoginNameDomainIsPrimaryCol, "true"),
LoginNameIsPrimaryCol),
LoginNameInstanceIDCol,
LoginNameOwnerRemovedUserCol,
LoginNameOwnerRemovedPolicyCol,
LoginNameOwnerRemovedDomainCol,
).FromSelect(loginNamesTable, LoginNameTableAlias).MustSql()
)
func col(table, name string) string {
return table + "." + name
}
func alias(col, alias string) string {
return col + " AS " + alias
}
func coalesce(values ...string) string {
str := "COALESCE("
for i, value := range values {
if i > 0 {
str += ", "
}
str += value
}
str += ")"
return str
}
func eq(first, second string) string {
return first + " = " + second
}
func leftJoin(table, alias, on string, and ...string) string {
st := table + " " + alias + " ON " + on
for _, a := range and {
st += " AND " + a
}
return st
}
func concat(strs ...string) string {
return "CONCAT(" + strings.Join(strs, ", ") + ")"
}
func whenThenElse(when, then, el string) string {
return "(CASE WHEN " + when + " THEN " + then + " ELSE " + el + " END)"
}
type loginNameProjection struct {
crdb.StatementHandler
}
@@ -100,29 +186,35 @@ func newLoginNameProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewColumn(LoginNameUserUserNameCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameUserResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameUserInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameUserOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LoginNameUserInstanceIDCol, LoginNameUserIDCol),
loginNameUserSuffix,
crdb.WithIndex(crdb.NewIndex("ro_idx", []string{LoginNameUserResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{LoginNameUserResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LoginNameUserOwnerRemovedCol})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(LoginNameDomainNameCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameDomainIsPrimaryCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(LoginNameDomainResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameDomainInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameDomainOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LoginNameDomainInstanceIDCol, LoginNameDomainResourceOwnerCol, LoginNameDomainNameCol),
loginNameDomainSuffix,
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LoginNameDomainOwnerRemovedCol})),
),
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.NewColumn(LoginNamePoliciesOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LoginNamePoliciesInstanceIDCol, LoginNamePoliciesResourceOwnerCol),
loginNamePolicySuffix,
crdb.WithIndex(crdb.NewIndex("is_default_idx", []string{LoginNamePoliciesResourceOwnerCol, LoginNamePoliciesIsDefaultCol})),
crdb.WithIndex(crdb.NewIndex("is_default", []string{LoginNamePoliciesResourceOwnerCol, LoginNamePoliciesIsDefaultCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LoginNamePoliciesOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -198,6 +290,10 @@ func (p *loginNameProjection) reducers() []handler.AggregateReducer {
Event: org.OrgDomainVerifiedEventType,
Reduce: p.reduceDomainVerified,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -469,3 +565,44 @@ func (p *loginNameProjection) reduceInstanceRemoved(event eventstore.Event) (*ha
),
), nil
}
func (p *loginNameProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-px02mo", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewMultiStatement(
event,
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(LoginNameDomainOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LoginNameDomainInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LoginNameDomainResourceOwnerCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNameDomainSuffix),
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(LoginNamePoliciesOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LoginNamePoliciesInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LoginNamePoliciesResourceOwnerCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNamePolicySuffix),
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(LoginNameUserOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LoginNameUserInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LoginNameUserResourceOwnerCol, e.Aggregate().ID),
},
crdb.WithTableSuffix(loginNameUserSuffix),
),
), nil
}
+62 -18
View File
@@ -41,7 +41,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.login_names2_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"human-added",
@@ -72,7 +72,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.login_names2_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"human-registered",
@@ -103,7 +103,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.login_names2_users (id, user_name, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"machine-added",
@@ -132,7 +132,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_names_users WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.login_names2_users WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -161,7 +161,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names_users SET user_name = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.login_names2_users SET user_name = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"changed",
"agg-id",
@@ -191,7 +191,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names_users SET user_name = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.login_names2_users SET user_name = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"claimed",
"agg-id",
@@ -221,7 +221,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.login_names2_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
true,
false,
@@ -252,7 +252,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names_policies SET must_be_domain = $1 WHERE (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.login_names2_policies SET must_be_domain = $1 WHERE (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
false,
"ro-id",
@@ -299,7 +299,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_names_policies WHERE (resource_owner = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.login_names2_policies WHERE (resource_owner = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"ro-id",
"instance-id",
@@ -328,7 +328,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_domains (name, resource_owner, instance_id) VALUES ($1, $2, $3)",
expectedStmt: "INSERT INTO projections.login_names2_domains (name, resource_owner, instance_id) VALUES ($1, $2, $3)",
expectedArgs: []interface{}{
"verified",
"ro-id",
@@ -358,7 +358,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_names_domains WHERE (name = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.login_names2_domains WHERE (name = $1) AND (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"remove",
"ro-id",
@@ -388,7 +388,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names_domains SET is_primary = $1 WHERE (resource_owner = $2) AND (is_primary = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.login_names2_domains SET is_primary = $1 WHERE (resource_owner = $2) AND (is_primary = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
false,
"ro-id",
@@ -397,7 +397,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.login_names_domains SET is_primary = $1 WHERE (name = $2) AND (resource_owner = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.login_names2_domains SET is_primary = $1 WHERE (name = $2) AND (resource_owner = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
true,
"primary",
@@ -428,7 +428,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_names_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.login_names2_policies (must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
true,
true,
@@ -459,7 +459,7 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names_policies SET must_be_domain = $1 WHERE (resource_owner = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.login_names2_policies SET must_be_domain = $1 WHERE (resource_owner = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
false,
"ro-id",
@@ -506,19 +506,19 @@ func TestLoginNameProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_names_domains WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.login_names2_domains WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.login_names_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.login_names2_policies WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
},
{
expectedStmt: "DELETE FROM projections.login_names_users WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.login_names2_users WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -527,6 +527,50 @@ func TestLoginNameProjection_reduces(t *testing.T) {
},
},
},
{
name: "instance.reduceOwnerRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
[]byte(`{"name": "Name"}`),
), org.OrgRemovedEventMapper),
},
reduce: (&loginNameProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_names2_domains SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)",
expectedArgs: []interface{}{
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.login_names2_policies SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)",
expectedArgs: []interface{}{
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.login_names2_users SET owner_removed = $1 WHERE (instance_id = $2) AND (resource_owner = $3)",
expectedArgs: []interface{}{
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -13,7 +13,7 @@ import (
)
const (
LoginPolicyTable = "projections.login_policies3"
LoginPolicyTable = "projections.login_policies4"
LoginPolicyIDCol = "aggregate_id"
LoginPolicyInstanceIDCol = "instance_id"
@@ -39,6 +39,7 @@ const (
MFAInitSkipLifetimeCol = "mfa_init_skip_lifetime"
SecondFactorCheckLifetimeCol = "second_factor_check_lifetime"
MultiFactorCheckLifetimeCol = "multi_factor_check_lifetime"
LoginPolicyOwnerRemovedCol = "owner_removed"
)
type loginPolicyProjection struct {
@@ -75,8 +76,10 @@ func newLoginPolicyProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(MFAInitSkipLifetimeCol, crdb.ColumnTypeInt64),
crdb.NewColumn(SecondFactorCheckLifetimeCol, crdb.ColumnTypeInt64),
crdb.NewColumn(MultiFactorCheckLifetimeCol, crdb.ColumnTypeInt64),
crdb.NewColumn(LoginPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(LoginPolicyInstanceIDCol, LoginPolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{LoginPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -116,6 +119,10 @@ func (p *loginPolicyProjection) reducers() []handler.AggregateReducer {
Event: org.LoginPolicySecondFactorRemovedEventType,
Reduce: p.reduce2FARemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -381,3 +388,23 @@ func (p *loginPolicyProjection) reduce2FARemoved(event eventstore.Event) (*handl
},
), nil
}
func (p *loginPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-B8NZW", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(LoginPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(LoginPolicySequenceCol, e.Sequence()),
handler.NewCol(LoginPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(LoginPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(LoginPolicyIDCol, e.Aggregate().ID),
},
), nil
}
+44 -14
View File
@@ -57,7 +57,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_policies3 (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, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $18, $19, $20, $21, $22)",
expectedStmt: "INSERT INTO projections.login_policies4 (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, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $18, $19, $20, $21, $22)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -121,7 +121,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $14, $15, $16, $17, $18) WHERE (aggregate_id = $19) AND (instance_id = $20)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $14, $15, $16, $17, $18) WHERE (aggregate_id = $19) AND (instance_id = $20)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -168,7 +168,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -200,7 +200,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -230,7 +230,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_policies3 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.login_policies4 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -259,7 +259,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -291,7 +291,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -338,7 +338,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.login_policies3 (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, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $18, $19, $20, $21, $22)",
expectedStmt: "INSERT INTO projections.login_policies4 (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, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri, 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, $18, $19, $20, $21, $22)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -397,7 +397,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (aggregate_id = $14) AND (instance_id = $15)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, allow_register, allow_username_password, allow_external_idps, force_mfa, passwordless_type, hide_password_reset, ignore_unknown_usernames, allow_domain_discovery, disable_login_with_email, disable_login_with_phone, default_redirect_uri) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) WHERE (aggregate_id = $14) AND (instance_id = $15)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -439,7 +439,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, multi_factors) = ($1, $2, array_append(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -471,7 +471,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, multi_factors) = ($1, $2, array_remove(multi_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -503,7 +503,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, second_factors) = ($1, $2, array_append(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -535,7 +535,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies3 SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, second_factors) = ($1, $2, array_remove(second_factors, $3)) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -548,6 +548,36 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&loginPolicyProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.login_policies4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -565,7 +595,7 @@ func TestLoginPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.login_policies3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.login_policies4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
MailTemplateTable = "projections.mail_templates"
MailTemplateTable = "projections.mail_templates2"
MailTemplateAggregateIDCol = "aggregate_id"
MailTemplateInstanceIDCol = "instance_id"
@@ -24,6 +24,7 @@ const (
MailTemplateStateCol = "state"
MailTemplateIsDefaultCol = "is_default"
MailTemplateTemplateCol = "template"
MailTemplateOwnerRemovedCol = "owner_removed"
)
type mailTemplateProjection struct {
@@ -44,8 +45,10 @@ func newMailTemplateProjection(ctx context.Context, config crdb.StatementHandler
crdb.NewColumn(MailTemplateStateCol, crdb.ColumnTypeEnum),
crdb.NewColumn(MailTemplateIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(MailTemplateTemplateCol, crdb.ColumnTypeBytes),
crdb.NewColumn(MailTemplateOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(MailTemplateInstanceIDCol, MailTemplateAggregateIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{MailTemplateOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -69,6 +72,10 @@ func (p *mailTemplateProjection) reducers() []handler.AggregateReducer {
Event: org.MailTemplateRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -156,3 +163,23 @@ func (p *mailTemplateProjection) reduceRemoved(event eventstore.Event) (*handler
handler.NewCond(MailTemplateInstanceIDCol, policyEvent.Aggregate().InstanceID),
}), nil
}
func (p *mailTemplateProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-CThXR", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(MailTemplateChangeDateCol, e.CreationDate()),
handler.NewCol(MailTemplateSequenceCol, e.Sequence()),
handler.NewCol(MailTemplateOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(MailTemplateInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(MailTemplateAggregateIDCol, e.Aggregate().ID),
},
), nil
}
+42 -12
View File
@@ -23,7 +23,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
want wantReduce
}{
{
name: "org reduceAdded",
name: "org.reduceAdded",
args: args{
event: getEvent(testEvent(
repository.EventType(org.MailTemplateAddedEventType),
@@ -41,7 +41,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.mail_templates2 (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",
@@ -58,7 +58,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
{
name: "org reduceChanged",
name: "org.reduceChanged",
reduce: (&mailTemplateProjection{}).reduceChanged,
args: args{
event: getEvent(testEvent(
@@ -76,7 +76,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.mail_templates2 SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -90,7 +90,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
{
name: "org reduceRemoved",
name: "org.reduceRemoved",
reduce: (&mailTemplateProjection{}).reduceRemoved,
args: args{
event: getEvent(testEvent(
@@ -106,7 +106,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.mail_templates WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.mail_templates2 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -117,7 +117,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
{
name: "instance reduceInstanceRemoved",
name: "instance.reduceInstanceRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(instance.InstanceRemovedEventType),
@@ -133,7 +133,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.mail_templates WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.mail_templates2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -143,7 +143,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
{
name: "instance reduceAdded",
name: "instance.reduceAdded",
reduce: (&mailTemplateProjection{}).reduceAdded,
args: args{
event: getEvent(testEvent(
@@ -161,7 +161,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.mail_templates2 (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",
@@ -178,7 +178,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
{
name: "instance reduceChanged",
name: "instance.reduceChanged",
reduce: (&mailTemplateProjection{}).reduceChanged,
args: args{
event: getEvent(testEvent(
@@ -196,7 +196,7 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.mail_templates SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.mail_templates2 SET (change_date, sequence, template) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -209,6 +209,36 @@ func TestMailTemplateProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&mailTemplateProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.mail_templates2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+61
View File
@@ -0,0 +1,61 @@
package projection
import (
"database/sql"
"testing"
"time"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/eventstore/repository/mock"
action_repo "github.com/zitadel/zitadel/internal/repository/action"
iam_repo "github.com/zitadel/zitadel/internal/repository/instance"
key_repo "github.com/zitadel/zitadel/internal/repository/keypair"
"github.com/zitadel/zitadel/internal/repository/org"
proj_repo "github.com/zitadel/zitadel/internal/repository/project"
usr_repo "github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/repository/usergrant"
)
type expect func(mockRepository *mock.MockRepository)
func eventstoreExpect(t *testing.T, expects ...expect) *eventstore.Eventstore {
m := mock.NewRepo(t)
for _, e := range expects {
e(m)
}
es := eventstore.NewEventstore(m)
iam_repo.RegisterEventMappers(es)
org.RegisterEventMappers(es)
usr_repo.RegisterEventMappers(es)
proj_repo.RegisterEventMappers(es)
usergrant.RegisterEventMappers(es)
key_repo.RegisterEventMappers(es)
action_repo.RegisterEventMappers(es)
return es
}
func expectFilter(events ...*repository.Event) expect {
return func(m *mock.MockRepository) {
m.ExpectFilterEvents(events...)
}
}
func eventFromEventPusher(event eventstore.Command) *repository.Event {
data, _ := eventstore.EventData(event)
return &repository.Event{
ID: "",
Sequence: 0,
PreviousAggregateSequence: 0,
PreviousAggregateTypeSequence: 0,
CreationDate: time.Time{},
Type: repository.EventType(event.Type()),
Data: data,
EditorService: event.EditorService(),
EditorUser: event.EditorUser(),
Version: repository.Version(event.Aggregate().Version),
AggregateID: event.Aggregate().ID,
AggregateType: repository.AggregateType(event.Aggregate().Type),
ResourceOwner: sql.NullString{String: event.Aggregate().ResourceOwner, Valid: event.Aggregate().ResourceOwner != ""},
}
}
+77 -3
View File
@@ -1,6 +1,9 @@
package projection
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -9,14 +12,17 @@ import (
)
const (
MemberUserIDCol = "user_id"
MemberRolesCol = "roles"
MemberUserIDCol = "user_id"
MemberRolesCol = "roles"
MemberUserResourceOwner = "user_resource_owner"
MemberUserOwnerRemoved = "user_owner_removed"
MemberCreationDate = "creation_date"
MemberChangeDate = "change_date"
MemberSequence = "sequence"
MemberResourceOwner = "resource_owner"
MemberInstanceID = "instance_id"
MemberOwnerRemoved = "owner_removed"
)
var (
@@ -24,10 +30,13 @@ var (
crdb.NewColumn(MemberCreationDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(MemberChangeDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(MemberUserIDCol, crdb.ColumnTypeText),
crdb.NewColumn(MemberUserResourceOwner, crdb.ColumnTypeText),
crdb.NewColumn(MemberUserOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(MemberRolesCol, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(MemberSequence, crdb.ColumnTypeInt64),
crdb.NewColumn(MemberResourceOwner, crdb.ColumnTypeText),
crdb.NewColumn(MemberInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(MemberOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
}
)
@@ -52,16 +61,19 @@ func withMemberCond(cond string, value interface{}) reduceMemberOpt {
}
}
func reduceMemberAdded(e member.MemberAddedEvent, opts ...reduceMemberOpt) (*handler.Statement, error) {
func reduceMemberAdded(e member.MemberAddedEvent, userResourceOwner string, opts ...reduceMemberOpt) (*handler.Statement, error) {
config := reduceMemberConfig{
cols: []handler.Column{
handler.NewCol(MemberUserIDCol, e.UserID),
handler.NewCol(MemberUserResourceOwner, userResourceOwner),
handler.NewCol(MemberUserOwnerRemoved, false),
handler.NewCol(MemberRolesCol, database.StringArray(e.Roles)),
handler.NewCol(MemberCreationDate, e.CreationDate()),
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
handler.NewCol(MemberResourceOwner, e.Aggregate().ResourceOwner),
handler.NewCol(MemberInstanceID, e.Aggregate().InstanceID),
handler.NewCol(MemberOwnerRemoved, false),
}}
for _, opt := range opts {
@@ -115,3 +127,65 @@ func reduceMemberRemoved(e eventstore.Event, opts ...reduceMemberOpt) (*handler.
}
return crdb.NewDeleteStatement(e, config.conds), nil
}
func multiReduceMemberOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) func(eventstore.Event) crdb.Exec {
config := reduceMemberConfig{
conds: []handler.Condition{
handler.NewCond(MemberInstanceID, e.Aggregate().InstanceID),
handler.NewCond(MemberResourceOwner, e.Aggregate().ID),
},
}
for _, opt := range opts {
config = opt(config)
}
return crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
handler.NewCol(MemberOwnerRemoved, true),
},
config.conds,
)
}
func memberUserOwnerRemovedConds(e eventstore.Event, opts ...reduceMemberOpt) []handler.Condition {
config := reduceMemberConfig{
conds: []handler.Condition{
handler.NewCond(MemberInstanceID, e.Aggregate().InstanceID),
handler.NewCond(MemberUserResourceOwner, e.Aggregate().ID),
},
}
for _, opt := range opts {
config = opt(config)
}
return config.conds
}
func memberUserOwnerRemovedCols(e eventstore.Event) []handler.Column {
return []handler.Column{
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
handler.NewCol(MemberUserOwnerRemoved, true),
}
}
func reduceMemberUserOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) (*handler.Statement, error) {
return crdb.NewUpdateStatement(
e,
memberUserOwnerRemovedCols(e),
memberUserOwnerRemovedConds(e, opts...),
), nil
}
func multiReduceMemberUserOwnerRemoved(e eventstore.Event, opts ...reduceMemberOpt) func(eventstore.Event) crdb.Exec {
return crdb.AddUpdateStatement(
memberUserOwnerRemovedCols(e),
memberUserOwnerRemovedConds(e, opts...),
)
}
func setMemberContext(event eventstore.Aggregate) context.Context {
return authz.WithInstanceID(context.Background(), event.InstanceID)
}
+48 -18
View File
@@ -44,7 +44,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -83,7 +83,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, pre_header) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.pre_header)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, pre_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, pre_header) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.pre_header)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -122,7 +122,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, subject) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.subject)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, subject) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, subject) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.subject)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -161,7 +161,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, greeting) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.greeting)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, greeting) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, greeting) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.greeting)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -200,7 +200,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.text)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -239,7 +239,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, button_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.button_text)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, button_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, button_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.button_text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -278,7 +278,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, footer_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.footer_text)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, footer_text) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, footer_text) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.footer_text)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -316,7 +316,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -348,7 +348,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.message_texts WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.message_texts2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -378,7 +378,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, pre_header) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, pre_header) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -414,7 +414,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, subject) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, subject) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -450,7 +450,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, greeting) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, greeting) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -486,7 +486,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -522,7 +522,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, button_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, button_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -558,7 +558,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, footer_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, footer_text) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -594,7 +594,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.message_texts WHERE (aggregate_id = $1) AND (type = $2) AND (language = $3) AND (instance_id = $4)",
expectedStmt: "DELETE FROM projections.message_texts2 WHERE (aggregate_id = $1) AND (type = $2) AND (language = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"agg-id",
"InitCode",
@@ -628,7 +628,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT 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) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedStmt: "INSERT INTO projections.message_texts2 (aggregate_id, instance_id, creation_date, change_date, sequence, state, type, language, title) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) ON CONFLICT (instance_id, aggregate_id, type, language) DO UPDATE SET (creation_date, change_date, sequence, state, title) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.title)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -666,7 +666,7 @@ func TestMessageTextProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, title) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (type = $5) AND (language = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -681,6 +681,36 @@ func TestMessageTextProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&messageTextProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.message_texts2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (aggregate_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
MessageTextTable = "projections.message_texts"
MessageTextTable = "projections.message_texts2"
MessageTextAggregateIDCol = "aggregate_id"
MessageTextInstanceIDCol = "instance_id"
@@ -31,6 +31,7 @@ const (
MessageTextTextCol = "text"
MessageTextButtonTextCol = "button_text"
MessageTextFooterCol = "footer_text"
MessageTextOwnerRemovedCol = "owner_removed"
)
type messageTextProjection struct {
@@ -58,8 +59,10 @@ func newMessageTextProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(MessageTextTextCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextButtonTextCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextFooterCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(MessageTextInstanceIDCol, MessageTextAggregateIDCol, MessageTextTypeCol, MessageTextLanguageCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{MessageTextOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -83,6 +86,10 @@ func (p *messageTextProjection) reducers() []handler.AggregateReducer {
Event: org.CustomTextTemplateRemovedEventType,
Reduce: p.reduceTemplateRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -240,6 +247,26 @@ func (p *messageTextProjection) reduceTemplateRemoved(event eventstore.Event) (*
), nil
}
func (p *messageTextProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-mLsQw", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(MessageTextChangeDateCol, e.CreationDate()),
handler.NewCol(MessageTextSequenceCol, e.Sequence()),
handler.NewCol(MessageTextOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(MessageTextInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(MessageTextAggregateIDCol, e.Aggregate().ID),
},
), nil
}
func isMessageTemplate(template string) bool {
return template == domain.InitCodeMessageType ||
template == domain.PasswordResetMessageType ||
+25 -2
View File
@@ -47,8 +47,8 @@ func newOrgProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(OrgColumnDomain, crdb.ColumnTypeText, crdb.Default("")),
},
crdb.NewPrimaryKey(OrgColumnInstanceID, OrgColumnID),
crdb.WithIndex(crdb.NewIndex("domain_idx", []string{OrgColumnDomain})),
crdb.WithIndex(crdb.NewIndex("name_idx", []string{OrgColumnName})),
crdb.WithIndex(crdb.NewIndex("domain", []string{OrgColumnDomain})),
crdb.WithIndex(crdb.NewIndex("name", []string{OrgColumnName})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -76,6 +76,10 @@ func (p *orgProjection) reducers() []handler.AggregateReducer {
Event: org.OrgReactivatedEventType,
Reduce: p.reduceOrgReactivated,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOrgRemoved,
},
{
Event: org.OrgDomainPrimarySetEventType,
Reduce: p.reducePrimaryDomainSet,
@@ -192,3 +196,22 @@ func (p *orgProjection) reducePrimaryDomainSet(event eventstore.Event) (*handler
},
), nil
}
func (p *orgProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-DgMSg", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(OrgColumnChangeDate, e.CreationDate()),
handler.NewCol(OrgColumnSequence, e.Sequence()),
handler.NewCol(OrgColumnState, domain.OrgStateRemoved),
},
[]handler.Condition{
handler.NewCond(OrgColumnID, e.Aggregate().ID),
handler.NewCond(OrgColumnInstanceID, e.Aggregate().InstanceID),
},
), nil
}
+28 -1
View File
@@ -13,7 +13,7 @@ import (
)
const (
OrgDomainTable = "projections.org_domains"
OrgDomainTable = "projections.org_domains2"
OrgDomainOrgIDCol = "org_id"
OrgDomainInstanceIDCol = "instance_id"
@@ -24,6 +24,7 @@ const (
OrgDomainIsVerifiedCol = "is_verified"
OrgDomainIsPrimaryCol = "is_primary"
OrgDomainValidationTypeCol = "validation_type"
OrgDomainOwnerRemovedCol = "owner_removed"
)
type orgDomainProjection struct {
@@ -45,8 +46,10 @@ func newOrgDomainProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewColumn(OrgDomainIsVerifiedCol, crdb.ColumnTypeBool),
crdb.NewColumn(OrgDomainIsPrimaryCol, crdb.ColumnTypeBool),
crdb.NewColumn(OrgDomainValidationTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(OrgDomainOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(OrgDomainOrgIDCol, OrgDomainDomainCol, OrgDomainInstanceIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{OrgDomainOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -78,6 +81,10 @@ func (p *orgDomainProjection) reducers() []handler.AggregateReducer {
Event: org.OrgDomainRemovedEventType,
Reduce: p.reduceDomainRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -201,3 +208,23 @@ func (p *orgDomainProjection) reduceDomainRemoved(event eventstore.Event) (*hand
},
), nil
}
func (p *orgDomainProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-dMUKJ", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(OrgDomainChangeDateCol, e.CreationDate()),
handler.NewCol(OrgDomainSequenceCol, e.Sequence()),
handler.NewCol(OrgDomainOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(OrgDomainInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(OrgDomainOrgIDCol, e.Aggregate().ID),
},
), nil
}
+37 -7
View File
@@ -39,7 +39,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.org_domains2 (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{},
@@ -73,7 +73,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, validation_type) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, validation_type) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -104,7 +104,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_verified) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, is_verified) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -135,7 +135,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (org_id = $4) AND (is_primary = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (org_id = $4) AND (is_primary = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -146,7 +146,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.org_domains SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, is_primary) = ($1, $2, $3) WHERE (domain = $4) AND (org_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -177,7 +177,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_domains WHERE (domain = $1) AND (org_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.org_domains2 WHERE (domain = $1) AND (org_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"domain.new",
"agg-id",
@@ -188,6 +188,36 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&orgDomainProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_domains2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (org_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -205,7 +235,7 @@ func TestOrgDomainProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_domains WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.org_domains2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+15 -8
View File
@@ -13,7 +13,7 @@ import (
)
const (
OrgMemberProjectionTable = "projections.org_members2"
OrgMemberProjectionTable = "projections.org_members3"
OrgMemberOrgIDCol = "org_id"
)
@@ -29,7 +29,9 @@ func newOrgMemberProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewTable(
append(memberColumns, crdb.NewColumn(OrgMemberOrgIDCol, crdb.ColumnTypeText)),
crdb.NewPrimaryKey(MemberInstanceID, OrgMemberOrgIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("org_memb_user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{MemberOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("user_owner_removed", []string{MemberUserOwnerRemoved})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -89,7 +91,12 @@ func (p *orgMemberProjection) reduceAdded(event eventstore.Event) (*handler.Stat
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-uYq4r", "reduce.wrong.event.type %s", org.MemberAddedEventType)
}
return reduceMemberAdded(e.MemberAddedEvent, withMemberCol(OrgMemberOrgIDCol, e.Aggregate().ID))
ctx := setMemberContext(e.Aggregate())
userOwner, err := getResourceOwnerOfUser(ctx, p.Eventstore, e.Aggregate().InstanceID, e.UserID)
if err != nil {
return nil, err
}
return reduceMemberAdded(e.MemberAddedEvent, userOwner, withMemberCol(OrgMemberOrgIDCol, e.Aggregate().ID))
}
func (p *orgMemberProjection) reduceChanged(event eventstore.Event) (*handler.Statement, error) {
@@ -128,13 +135,13 @@ func (p *orgMemberProjection) reduceUserRemoved(event eventstore.Event) (*handle
}
func (p *orgMemberProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
//TODO: as soon as org deletion is implemented:
// Case: The user has resource owner A and an org has resource owner B
// if org B deleted it works
// if org A is deleted, the membership wouldn't be deleted
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-jnGAV", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return reduceMemberRemoved(e, withMemberCond(OrgMemberOrgIDCol, e.Aggregate().ID))
return crdb.NewMultiStatement(
e,
multiReduceMemberOwnerRemoved(e),
multiReduceMemberUserOwnerRemoved(e),
), nil
}
+42 -8
View File
@@ -1,9 +1,13 @@
package projection
import (
"context"
"testing"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -35,7 +39,21 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
}`),
), org.MemberAddedEventMapper),
},
reduce: (&orgMemberProjection{}).reduceAdded,
reduce: (&orgMemberProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
@@ -43,15 +61,18 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.org_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.org_members3 (user_id, user_resource_owner, user_owner_removed, roles, creation_date, change_date, sequence, resource_owner, instance_id, owner_removed, org_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"user-id",
"org1",
false,
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
"ro-id",
"instance-id",
false,
"agg-id",
},
},
@@ -79,7 +100,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.org_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (org_id = $6)",
expectedStmt: "UPDATE projections.org_members3 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (org_id = $6)",
expectedArgs: []interface{}{
database.StringArray{"role", "changed"},
anyArg{},
@@ -112,7 +133,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (org_id = $3)",
expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (org_id = $3)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -142,7 +163,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (org_id = $3)",
expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (org_id = $3)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -170,7 +191,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -197,8 +218,21 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members2 WHERE (instance_id = $1) AND (org_id = $2)",
expectedStmt: "UPDATE projections.org_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.org_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
@@ -224,7 +258,7 @@ func TestOrgMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_members2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.org_members3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+25 -2
View File
@@ -12,7 +12,7 @@ import (
)
const (
OrgMetadataProjectionTable = "projections.org_metadata"
OrgMetadataProjectionTable = "projections.org_metadata2"
OrgMetadataColumnOrgID = "org_id"
OrgMetadataColumnCreationDate = "creation_date"
@@ -22,6 +22,7 @@ const (
OrgMetadataColumnInstanceID = "instance_id"
OrgMetadataColumnKey = "key"
OrgMetadataColumnValue = "value"
OrgMetadataColumnOwnerRemoved = "owner_removed"
)
type orgMetadataProjection struct {
@@ -42,8 +43,10 @@ func newOrgMetadataProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(OrgMetadataColumnInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(OrgMetadataColumnKey, crdb.ColumnTypeText),
crdb.NewColumn(OrgMetadataColumnValue, crdb.ColumnTypeBytes, crdb.Nullable()),
crdb.NewColumn(OrgMetadataColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(OrgMetadataColumnInstanceID, OrgMetadataColumnOrgID, OrgMetadataColumnKey),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{OrgMetadataColumnOwnerRemoved})),
),
)
@@ -70,7 +73,7 @@ func (p *orgMetadataProjection) reducers() []handler.AggregateReducer {
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceMetadataRemovedAll,
Reduce: p.reduceOwnerRemoved,
},
},
},
@@ -142,3 +145,23 @@ func (p *orgMetadataProjection) reduceMetadataRemovedAll(event eventstore.Event)
},
), nil
}
func (p *orgMetadataProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-Hkd1f", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(OrgMetadataColumnChangeDate, e.CreationDate()),
handler.NewCol(OrgMetadataColumnSequence, e.Sequence()),
handler.NewCol(OrgMetadataColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(OrgMetadataColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(OrgMetadataColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
+11 -8
View File
@@ -41,7 +41,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.org_metadata (instance_id, org_id, key, resource_owner, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (instance_id, org_id, key) DO UPDATE SET (resource_owner, creation_date, change_date, sequence, value) = (EXCLUDED.resource_owner, EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedStmt: "INSERT INTO projections.org_metadata2 (instance_id, org_id, key, resource_owner, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (instance_id, org_id, key) DO UPDATE SET (resource_owner, creation_date, change_date, sequence, value) = (EXCLUDED.resource_owner, EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -76,7 +76,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_metadata WHERE (org_id = $1) AND (key = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.org_metadata2 WHERE (org_id = $1) AND (key = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"agg-id",
"key",
@@ -104,7 +104,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_metadata WHERE (org_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.org_metadata2 WHERE (org_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -115,7 +115,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
},
},
{
name: "reduceMetadataRemovedAll (org removed)",
name: "reduceOwnerRemoved(org removed)",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
@@ -123,7 +123,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&orgMetadataProjection{}).reduceMetadataRemovedAll,
reduce: (&orgMetadataProjection{}).reduceOwnerRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
@@ -131,10 +131,13 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_metadata WHERE (org_id = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.org_metadata2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
@@ -158,7 +161,7 @@ func TestOrgMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.org_metadata WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.org_metadata2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+30
View File
@@ -192,6 +192,36 @@ func TestOrgProjection_reduces(t *testing.T) {
},
},
},
{
name: "reduceOrgRemoved",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
reduce: (&orgProjection{}).reduceOrgRemoved,
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.orgs SET (change_date, sequence, org_state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
domain.OrgStateRemoved,
"agg-id",
"instance-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -14,7 +14,7 @@ import (
)
const (
PasswordAgeTable = "projections.password_age_policies"
PasswordAgeTable = "projections.password_age_policies2"
AgePolicyIDCol = "id"
AgePolicyCreationDateCol = "creation_date"
@@ -26,6 +26,7 @@ const (
AgePolicyInstanceIDCol = "instance_id"
AgePolicyExpireWarnDaysCol = "expire_warn_days"
AgePolicyMaxAgeDaysCol = "max_age_days"
AgePolicyOwnerRemovedCol = "owner_removed"
)
type passwordAgeProjection struct {
@@ -48,8 +49,10 @@ func newPasswordAgeProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(AgePolicyInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(AgePolicyExpireWarnDaysCol, crdb.ColumnTypeInt64),
crdb.NewColumn(AgePolicyMaxAgeDaysCol, crdb.ColumnTypeInt64),
crdb.NewColumn(AgePolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(AgePolicyInstanceIDCol, AgePolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{AgePolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -73,6 +76,10 @@ func (p *passwordAgeProjection) reducers() []handler.AggregateReducer {
Event: org.PasswordAgePolicyRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -165,3 +172,23 @@ func (p *passwordAgeProjection) reduceRemoved(event eventstore.Event) (*handler.
handler.NewCond(AgePolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
}), nil
}
func (p *passwordAgeProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-edLs2", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(AgePolicyChangeDateCol, e.CreationDate()),
handler.NewCol(AgePolicySequenceCol, e.Sequence()),
handler.NewCol(AgePolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(AgePolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(AgePolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -42,7 +42,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.password_age_policies2 (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{},
@@ -80,7 +80,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.password_age_policies2 SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -111,7 +111,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.password_age_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.password_age_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -138,7 +138,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.password_age_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.password_age_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -167,7 +167,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.password_age_policies2 (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{},
@@ -205,7 +205,7 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.password_age_policies SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.password_age_policies2 SET (change_date, sequence, expire_warn_days, max_age_days) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -219,6 +219,36 @@ func TestPasswordAgeProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&passwordAgeProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.password_age_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -14,7 +14,7 @@ import (
)
const (
PasswordComplexityTable = "projections.password_complexity_policies"
PasswordComplexityTable = "projections.password_complexity_policies2"
ComplexityPolicyIDCol = "id"
ComplexityPolicyCreationDateCol = "creation_date"
@@ -29,6 +29,7 @@ const (
ComplexityPolicyHasUppercaseCol = "has_uppercase"
ComplexityPolicyHasSymbolCol = "has_symbol"
ComplexityPolicyHasNumberCol = "has_number"
ComplexityPolicyOwnerRemovedCol = "owner_removed"
)
type passwordComplexityProjection struct {
@@ -54,8 +55,10 @@ func newPasswordComplexityProjection(ctx context.Context, config crdb.StatementH
crdb.NewColumn(ComplexityPolicyHasUppercaseCol, crdb.ColumnTypeBool),
crdb.NewColumn(ComplexityPolicyHasSymbolCol, crdb.ColumnTypeBool),
crdb.NewColumn(ComplexityPolicyHasNumberCol, crdb.ColumnTypeBool),
crdb.NewColumn(ComplexityPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ComplexityPolicyInstanceIDCol, ComplexityPolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{ComplexityPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -79,6 +82,10 @@ func (p *passwordComplexityProjection) reducers() []handler.AggregateReducer {
Event: org.PasswordComplexityPolicyRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -183,3 +190,23 @@ func (p *passwordComplexityProjection) reduceRemoved(event eventstore.Event) (*h
handler.NewCond(ComplexityPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
}), nil
}
func (p *passwordComplexityProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-pGTz9", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(ComplexityPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(ComplexityPolicySequenceCol, e.Sequence()),
handler.NewCol(ComplexityPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(ComplexityPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(ComplexityPolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -45,7 +45,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.password_complexity_policies2 (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{},
@@ -89,7 +89,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.password_complexity_policies2 SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -123,7 +123,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.password_complexity_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.password_complexity_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -150,7 +150,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.password_complexity_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.password_complexity_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -182,7 +182,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.password_complexity_policies2 (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{},
@@ -226,7 +226,7 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.password_complexity_policies2 SET (change_date, sequence, min_length, has_lowercase, has_uppercase, has_symbol, has_number) = ($1, $2, $3, $4, $5, $6, $7) WHERE (id = $8) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -243,6 +243,36 @@ func TestPasswordComplexityProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&passwordComplexityProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.password_complexity_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+28 -1
View File
@@ -14,7 +14,7 @@ import (
)
const (
PrivacyPolicyTable = "projections.privacy_policies"
PrivacyPolicyTable = "projections.privacy_policies2"
PrivacyPolicyIDCol = "id"
PrivacyPolicyCreationDateCol = "creation_date"
@@ -27,6 +27,7 @@ const (
PrivacyPolicyPrivacyLinkCol = "privacy_link"
PrivacyPolicyTOSLinkCol = "tos_link"
PrivacyPolicyHelpLinkCol = "help_link"
PrivacyPolicyOwnerRemovedCol = "owner_removed"
)
type privacyPolicyProjection struct {
@@ -50,8 +51,10 @@ func newPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandle
crdb.NewColumn(PrivacyPolicyPrivacyLinkCol, crdb.ColumnTypeText),
crdb.NewColumn(PrivacyPolicyTOSLinkCol, crdb.ColumnTypeText),
crdb.NewColumn(PrivacyPolicyHelpLinkCol, crdb.ColumnTypeText),
crdb.NewColumn(PrivacyPolicyOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(PrivacyPolicyInstanceIDCol, PrivacyPolicyIDCol),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{PrivacyPolicyOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -75,6 +78,10 @@ func (p *privacyPolicyProjection) reducers() []handler.AggregateReducer {
Event: org.PrivacyPolicyRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
@@ -171,3 +178,23 @@ func (p *privacyPolicyProjection) reduceRemoved(event eventstore.Event) (*handle
handler.NewCond(PrivacyPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID),
}), nil
}
func (p *privacyPolicyProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-bxJCY", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(PrivacyPolicyChangeDateCol, e.CreationDate()),
handler.NewCol(PrivacyPolicySequenceCol, e.Sequence()),
handler.NewCol(PrivacyPolicyOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(PrivacyPolicyInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(PrivacyPolicyResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -43,7 +43,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.privacy_policies2 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -83,7 +83,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -115,7 +115,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.privacy_policies WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.privacy_policies2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -141,7 +141,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.privacy_policies WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.privacy_policies2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -171,7 +171,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.privacy_policies (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedStmt: "INSERT INTO projections.privacy_policies2 (creation_date, change_date, sequence, id, state, privacy_link, tos_link, help_link, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
anyArg{},
anyArg{},
@@ -211,7 +211,7 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.privacy_policies SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, privacy_link, tos_link, help_link) = ($1, $2, $3, $4, $5) WHERE (id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -226,6 +226,36 @@ func TestPrivacyPolicyProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&privacyPolicyProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.privacy_policies2 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+35 -2
View File
@@ -9,11 +9,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
const (
ProjectProjectionTable = "projections.projects2"
ProjectProjectionTable = "projections.projects3"
ProjectColumnID = "id"
ProjectColumnCreationDate = "creation_date"
@@ -27,6 +28,7 @@ const (
ProjectColumnProjectRoleCheck = "project_role_check"
ProjectColumnHasProjectCheck = "has_project_check"
ProjectColumnPrivateLabelingSetting = "private_labeling_setting"
ProjectColumnOwnerRemoved = "owner_removed"
)
type projectProjection struct {
@@ -51,9 +53,11 @@ func newProjectProjection(ctx context.Context, config crdb.StatementHandlerConfi
crdb.NewColumn(ProjectColumnProjectRoleCheck, crdb.ColumnTypeBool),
crdb.NewColumn(ProjectColumnHasProjectCheck, crdb.ColumnTypeBool),
crdb.NewColumn(ProjectColumnPrivateLabelingSetting, crdb.ColumnTypeEnum),
crdb.NewColumn(ProjectColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ProjectColumnInstanceID, ProjectColumnID),
crdb.WithIndex(crdb.NewIndex("project_ro_idx", []string{ProjectColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{ProjectColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{ProjectColumnOwnerRemoved})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -87,6 +91,15 @@ func (p *projectProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -211,3 +224,23 @@ func (p *projectProjection) reduceProjectRemoved(event eventstore.Event) (*handl
},
), nil
}
func (p *projectProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-sbgru", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(ProjectColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectColumnSequence, e.Sequence()),
handler.NewCol(ProjectColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(ProjectColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(ProjectColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
+62 -13
View File
@@ -10,22 +10,25 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
const (
ProjectGrantProjectionTable = "projections.project_grants2"
ProjectGrantProjectionTable = "projections.project_grants3"
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"
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"
ProjectGrantColumnOwnerRemoved = "owner_removed"
ProjectGrantColumnGrantedOrgRemoved = "granted_org_removed"
)
type projectGrantProjection struct {
@@ -48,10 +51,14 @@ func newProjectGrantProjection(ctx context.Context, config crdb.StatementHandler
crdb.NewColumn(ProjectGrantColumnProjectID, crdb.ColumnTypeText),
crdb.NewColumn(ProjectGrantColumnGrantedOrgID, crdb.ColumnTypeText),
crdb.NewColumn(ProjectGrantColumnRoleKeys, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(ProjectGrantColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(ProjectGrantColumnGrantedOrgRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ProjectGrantColumnInstanceID, ProjectGrantColumnGrantID),
crdb.WithIndex(crdb.NewIndex("pg_ro_idx", []string{ProjectGrantColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("granted_org_idx", []string{ProjectGrantColumnGrantedOrgID})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{ProjectGrantColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("granted_org", []string{ProjectGrantColumnGrantedOrgID})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{ProjectGrantColumnOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("granted_org_removed", []string{ProjectGrantColumnGrantedOrgRemoved})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -93,6 +100,15 @@ func (p *projectGrantProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -235,3 +251,36 @@ func (p *projectGrantProjection) reduceProjectRemoved(event eventstore.Event) (*
},
), nil
}
func (p *projectGrantProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-HDgW3", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewMultiStatement(
e,
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectGrantColumnSequence, e.Sequence()),
handler.NewCol(ProjectGrantColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(ProjectGrantColumnResourceOwner, e.Aggregate().ID),
},
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(ProjectGrantColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectGrantColumnSequence, e.Sequence()),
handler.NewCol(ProjectGrantColumnGrantedOrgRemoved, true),
},
[]handler.Condition{
handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(ProjectGrantColumnGrantedOrgID, e.Aggregate().ID),
},
),
), nil
}
@@ -15,9 +15,11 @@ import (
)
const (
ProjectGrantMemberProjectionTable = "projections.project_grant_members2"
ProjectGrantMemberProjectIDCol = "project_id"
ProjectGrantMemberGrantIDCol = "grant_id"
ProjectGrantMemberProjectionTable = "projections.project_grant_members3"
ProjectGrantMemberProjectIDCol = "project_id"
ProjectGrantMemberGrantIDCol = "grant_id"
ProjectGrantMemberGrantedOrg = "granted_org"
ProjectGrantMemberGrantedOrgRemoved = "granted_org_removed"
)
type projectGrantMemberProjection struct {
@@ -33,9 +35,14 @@ func newProjectGrantMemberProjection(ctx context.Context, config crdb.StatementH
append(memberColumns,
crdb.NewColumn(ProjectGrantMemberProjectIDCol, crdb.ColumnTypeText),
crdb.NewColumn(ProjectGrantMemberGrantIDCol, crdb.ColumnTypeText),
crdb.NewColumn(ProjectGrantMemberGrantedOrg, crdb.ColumnTypeText),
crdb.NewColumn(ProjectGrantMemberGrantedOrgRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
),
crdb.NewPrimaryKey(MemberInstanceID, ProjectGrantMemberProjectIDCol, ProjectGrantMemberGrantIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("proj_grant_memb_user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{MemberOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("user_owner_removed", []string{MemberUserOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("granted_org_removed", []string{ProjectGrantMemberGrantedOrgRemoved})),
),
)
@@ -109,10 +116,22 @@ func (p *projectGrantMemberProjection) reduceAdded(event eventstore.Event) (*han
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-0EBQf", "reduce.wrong.event.type %s", project.GrantMemberAddedType)
}
ctx := setMemberContext(e.Aggregate())
userOwner, err := getResourceOwnerOfUser(ctx, p.Eventstore, e.Aggregate().InstanceID, e.UserID)
if err != nil {
return nil, err
}
grantedOrg, err := getGrantedOrgOfGrantedProject(ctx, p.Eventstore, e.Aggregate().InstanceID, e.Aggregate().ID, e.GrantID)
if err != nil {
return nil, err
}
return reduceMemberAdded(
*member.NewMemberAddedEvent(&e.BaseEvent, e.UserID, e.Roles...),
userOwner,
withMemberCol(ProjectGrantMemberProjectIDCol, e.Aggregate().ID),
withMemberCol(ProjectGrantMemberGrantIDCol, e.GrantID),
withMemberCol(ProjectGrantMemberGrantedOrg, grantedOrg),
withMemberCol(ProjectGrantMemberGrantedOrgRemoved, false),
)
}
@@ -169,15 +188,26 @@ func (p *projectGrantMemberProjection) reduceInstanceRemoved(event eventstore.Ev
}
func (p *projectGrantMemberProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
//TODO: as soon as org deletion is implemented:
// Case: The user has resource owner A and project has resource owner B
// if org B deleted it works
// if org A is deleted, the membership wouldn't be deleted
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Zzp6o", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return reduceMemberRemoved(e, withMemberCond(MemberResourceOwner, e.Aggregate().ID))
return crdb.NewMultiStatement(
e,
multiReduceMemberOwnerRemoved(e),
multiReduceMemberUserOwnerRemoved(e),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(MemberChangeDate, e.CreationDate()),
handler.NewCol(MemberSequence, e.Sequence()),
handler.NewCol(ProjectGrantMemberGrantedOrgRemoved, true),
},
[]handler.Condition{
handler.NewCond(ProjectGrantColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(ProjectGrantMemberGrantedOrg, e.Aggregate().ID),
},
),
), nil
}
func (p *projectGrantMemberProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) {
@@ -1,9 +1,13 @@
package projection
import (
"context"
"testing"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -37,7 +41,25 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
}`),
), project.GrantMemberAddedEventMapper),
},
reduce: (&projectGrantMemberProjection{}).reduceAdded,
reduce: (&projectGrantMemberProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project1", "org2").Aggregate,
"grant", "org3", []string{},
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: project.AggregateType,
sequence: 15,
@@ -45,17 +67,22 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_grant_members2 (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)",
expectedStmt: "INSERT INTO projections.project_grant_members3 (user_id, user_resource_owner, user_owner_removed, roles, creation_date, change_date, sequence, resource_owner, instance_id, owner_removed, project_id, grant_id, granted_org, granted_org_removed) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedArgs: []interface{}{
"user-id",
"org1",
false,
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
"ro-id",
"instance-id",
false,
"agg-id",
"grant-id",
"org3",
false,
},
},
},
@@ -83,7 +110,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grant_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (project_id = $6) AND (grant_id = $7)",
expectedStmt: "UPDATE projections.project_grant_members3 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (project_id = $6) AND (grant_id = $7)",
expectedArgs: []interface{}{
database.StringArray{"role", "changed"},
anyArg{},
@@ -118,7 +145,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3) AND (grant_id = $4)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3) AND (grant_id = $4)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -150,7 +177,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3) AND (grant_id = $4)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3) AND (grant_id = $4)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -179,7 +206,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -190,23 +217,23 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
},
},
{
name: "org OrgRemovedEventType",
name: "project ProjectRemovedEventType",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
repository.EventType(project.ProjectRemovedType),
project.AggregateType,
[]byte(`{}`),
), org.OrgRemovedEventMapper),
), project.ProjectRemovedEventMapper),
},
reduce: (&projectGrantMemberProjection{}).reduceOrgRemoved,
reduce: (&projectGrantMemberProjection{}).reduceProjectRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
aggregateType: project.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -232,7 +259,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -241,33 +268,6 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
},
},
},
{
name: "project ProjectRemovedEventType",
args: args{
event: getEvent(testEvent(
repository.EventType(project.ProjectRemovedType),
project.AggregateType,
[]byte(`{}`),
), project.ProjectRemovedEventMapper),
},
reduce: (&projectGrantMemberProjection{}).reduceProjectRemoved,
want: wantReduce{
aggregateType: project.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "project GrantRemovedEventType",
args: args{
@@ -285,7 +285,7 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grant_members2 WHERE (instance_id = $1) AND (grant_id = $2) AND (project_id = $3)",
expectedStmt: "DELETE FROM projections.project_grant_members3 WHERE (instance_id = $1) AND (grant_id = $2) AND (project_id = $3)",
expectedArgs: []interface{}{
"instance-id",
"grant-id",
@@ -296,6 +296,56 @@ func TestProjectGrantMemberProjection_reduces(t *testing.T) {
},
},
},
{
name: "org OrgRemovedEventType",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
[]byte(`{}`),
), org.OrgRemovedEventMapper),
},
reduce: (&projectGrantMemberProjection{}).reduceOrgRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.project_grant_members3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -10,6 +10,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
@@ -40,7 +41,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grants2 WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.project_grants3 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -67,7 +68,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grants2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.project_grants3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -93,7 +94,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_grants2 WHERE (grant_id = $1) AND (project_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.project_grants3 WHERE (grant_id = $1) AND (project_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"grant-id",
"agg-id",
@@ -121,7 +122,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -152,7 +153,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -183,7 +184,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -214,7 +215,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants2 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, granted_role_keys) = ($1, $2, $3) WHERE (grant_id = $4) AND (project_id = $5) AND (instance_id = $6)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -245,7 +246,7 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_grants2 (grant_id, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence, granted_org_id, granted_role_keys) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.project_grants3 (grant_id, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence, granted_org_id, granted_role_keys) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"grant-id",
"agg-id",
@@ -263,6 +264,46 @@ func TestProjectGrantProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&projectGrantProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.project_grants3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+15 -7
View File
@@ -15,7 +15,7 @@ import (
)
const (
ProjectMemberProjectionTable = "projections.project_members2"
ProjectMemberProjectionTable = "projections.project_members3"
ProjectMemberProjectIDCol = "project_id"
)
@@ -33,7 +33,9 @@ func newProjectMemberProjection(ctx context.Context, config crdb.StatementHandle
crdb.NewColumn(ProjectMemberProjectIDCol, crdb.ColumnTypeText),
),
crdb.NewPrimaryKey(MemberInstanceID, ProjectMemberProjectIDCol, MemberUserIDCol),
crdb.WithIndex(crdb.NewIndex("proj_memb_user_idx", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{MemberUserIDCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{MemberOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("user_owner_removed", []string{MemberUserOwnerRemoved})),
),
)
@@ -103,8 +105,14 @@ func (p *projectMemberProjection) reduceAdded(event eventstore.Event) (*handler.
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-bgx5Q", "reduce.wrong.event.type %s", project.MemberAddedType)
}
ctx := setMemberContext(e.Aggregate())
userOwner, err := getResourceOwnerOfUser(ctx, p.Eventstore, e.Aggregate().InstanceID, e.UserID)
if err != nil {
return nil, err
}
return reduceMemberAdded(
*member.NewMemberAddedEvent(&e.BaseEvent, e.UserID, e.Roles...),
userOwner,
withMemberCol(ProjectMemberProjectIDCol, e.Aggregate().ID),
)
}
@@ -151,15 +159,15 @@ func (p *projectMemberProjection) reduceUserRemoved(event eventstore.Event) (*ha
}
func (p *projectMemberProjection) reduceOrgRemoved(event eventstore.Event) (*handler.Statement, error) {
//TODO: as soon as org deletion is implemented:
// Case: The user has resource owner A and project has resource owner B
// if org B deleted it works
// if org A is deleted, the membership wouldn't be deleted
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-NGUEL", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return reduceMemberRemoved(e, withMemberCond(MemberResourceOwner, e.Aggregate().ID))
return crdb.NewMultiStatement(
e,
multiReduceMemberOwnerRemoved(e),
multiReduceMemberUserOwnerRemoved(e),
), nil
}
func (p *projectMemberProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) {
@@ -1,9 +1,13 @@
package projection
import (
"context"
"testing"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
@@ -36,7 +40,21 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
}`),
), project.MemberAddedEventMapper),
},
reduce: (&projectMemberProjection{}).reduceAdded,
reduce: (&projectMemberProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: project.AggregateType,
sequence: 15,
@@ -44,15 +62,18 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_members2 (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.project_members3 (user_id, user_resource_owner, user_owner_removed, roles, creation_date, change_date, sequence, resource_owner, instance_id, owner_removed, project_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
expectedArgs: []interface{}{
"user-id",
"org1",
false,
database.StringArray{"role"},
anyArg{},
anyArg{},
uint64(15),
"ro-id",
"instance-id",
false,
"agg-id",
},
},
@@ -80,7 +101,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_members2 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (project_id = $6)",
expectedStmt: "UPDATE projections.project_members3 SET (roles, change_date, sequence) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_id = $5) AND (project_id = $6)",
expectedArgs: []interface{}{
database.StringArray{"role", "changed"},
anyArg{},
@@ -113,7 +134,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3)",
expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -143,7 +164,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3)",
expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (user_id = $2) AND (project_id = $3)",
expectedArgs: []interface{}{
"instance-id",
"user-id",
@@ -171,7 +192,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1) AND (user_id = $2)",
expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (user_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -182,23 +203,23 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
},
},
{
name: "org OrgRemovedEventType",
name: "project ProjectRemovedEventType",
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
repository.EventType(project.ProjectRemovedType),
project.AggregateType,
[]byte(`{}`),
), org.OrgRemovedEventMapper),
), project.ProjectRemovedEventMapper),
},
reduce: (&projectMemberProjection{}).reduceOrgRemoved,
reduce: (&projectMemberProjection{}).reduceProjectRemoved,
want: wantReduce{
aggregateType: org.AggregateType,
aggregateType: project.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1) AND (resource_owner = $2)",
expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1) AND (project_id = $2)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -225,7 +246,7 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.project_members3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -235,24 +256,37 @@ func TestProjectMemberProjection_reduces(t *testing.T) {
},
},
{
name: "project ProjectRemovedEventType",
name: "org OrgRemovedEventType",
args: args{
event: getEvent(testEvent(
repository.EventType(project.ProjectRemovedType),
project.AggregateType,
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
[]byte(`{}`),
), project.ProjectRemovedEventMapper),
), org.OrgRemovedEventMapper),
},
reduce: (&projectMemberProjection{}).reduceProjectRemoved,
reduce: (&projectMemberProjection{}).reduceOrgRemoved,
want: wantReduce{
aggregateType: project.AggregateType,
aggregateType: org.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_members2 WHERE (instance_id = $1) AND (project_id = $2)",
expectedStmt: "UPDATE projections.project_members3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.project_members3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (user_resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
+34 -1
View File
@@ -8,11 +8,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
const (
ProjectRoleProjectionTable = "projections.project_roles"
ProjectRoleProjectionTable = "projections.project_roles3"
ProjectRoleColumnProjectID = "project_id"
ProjectRoleColumnKey = "role_key"
@@ -23,6 +24,7 @@ const (
ProjectRoleColumnInstanceID = "instance_id"
ProjectRoleColumnDisplayName = "display_name"
ProjectRoleColumnGroupName = "group_name"
ProjectRoleColumnOwnerRemoved = "owner_removed"
)
type projectRoleProjection struct {
@@ -44,8 +46,10 @@ func newProjectRoleProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(ProjectRoleColumnInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(ProjectRoleColumnDisplayName, crdb.ColumnTypeText),
crdb.NewColumn(ProjectRoleColumnGroupName, crdb.ColumnTypeText),
crdb.NewColumn(ProjectRoleColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(ProjectRoleColumnInstanceID, ProjectRoleColumnProjectID, ProjectRoleColumnKey),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{ProjectRoleColumnOwnerRemoved})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -75,6 +79,15 @@ func (p *projectRoleProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -164,3 +177,23 @@ func (p *projectRoleProjection) reduceProjectRemoved(event eventstore.Event) (*h
},
), nil
}
func (p *projectRoleProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-3XrHY", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(ProjectRoleColumnChangeDate, e.CreationDate()),
handler.NewCol(ProjectRoleColumnSequence, e.Sequence()),
handler.NewCol(ProjectRoleColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(ProjectRoleColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(ProjectRoleColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
+36 -5
View File
@@ -8,6 +8,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
@@ -38,7 +39,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_roles WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.project_roles3 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -65,7 +66,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_roles WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.project_roles3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -91,7 +92,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.project_roles WHERE (role_key = $1) AND (project_id = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.project_roles3 WHERE (role_key = $1) AND (project_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"key",
"agg-id",
@@ -119,7 +120,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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) AND (instance_id = $7)",
expectedStmt: "UPDATE projections.project_roles3 SET (change_date, sequence, display_name, group_name) = ($1, $2, $3, $4) WHERE (role_key = $5) AND (project_id = $6) AND (instance_id = $7)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -168,7 +169,7 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.project_roles (role_key, project_id, creation_date, change_date, resource_owner, instance_id, sequence, display_name, group_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.project_roles3 (role_key, project_id, creation_date, change_date, resource_owner, instance_id, sequence, display_name, group_name) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"key",
"agg-id",
@@ -185,6 +186,36 @@ func TestProjectRoleProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&projectRoleProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.project_roles3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+37 -6
View File
@@ -9,6 +9,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
)
@@ -39,7 +40,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.projects2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.projects3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -66,7 +67,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.projects2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.projects3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -92,7 +93,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.projects3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -122,7 +123,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects2 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.projects3 SET (change_date, sequence, state) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -152,7 +153,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects2 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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.projects3 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) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -203,7 +204,7 @@ func TestProjectProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.projects2 (id, creation_date, change_date, resource_owner, instance_id, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
expectedStmt: "INSERT INTO projections.projects3 (id, creation_date, change_date, resource_owner, instance_id, sequence, name, project_role_assertion, project_role_check, has_project_check, private_labeling_setting, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
@@ -223,6 +224,36 @@ func TestProjectProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&projectProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.projects3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+4 -4
View File
@@ -12,7 +12,7 @@ import (
)
const (
SMSConfigProjectionTable = "projections.sms_configs"
SMSConfigProjectionTable = "projections.sms_configs2"
SMSTwilioTable = SMSConfigProjectionTable + "_" + smsTwilioTableSuffix
SMSColumnID = "id"
@@ -51,7 +51,7 @@ func newSMSConfigProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewColumn(SMSColumnResourceOwner, crdb.ColumnTypeText),
crdb.NewColumn(SMSColumnInstanceID, crdb.ColumnTypeText),
},
crdb.NewPrimaryKey(SMSColumnID, SMSColumnInstanceID),
crdb.NewPrimaryKey(SMSColumnInstanceID, SMSColumnID),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(SMSTwilioConfigColumnSMSID, crdb.ColumnTypeText),
@@ -60,9 +60,9 @@ func newSMSConfigProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewColumn(SMSTwilioConfigColumnSenderNumber, crdb.ColumnTypeText),
crdb.NewColumn(SMSTwilioConfigColumnToken, crdb.ColumnTypeJSONB),
},
crdb.NewPrimaryKey(SMSTwilioConfigColumnSMSID, SMSTwilioColumnInstanceID),
crdb.NewPrimaryKey(SMSTwilioColumnInstanceID, SMSTwilioConfigColumnSMSID),
smsTwilioTableSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_twilio_ref_sms")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
+10 -10
View File
@@ -49,7 +49,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
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)",
expectedStmt: "INSERT INTO projections.sms_configs2 (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",
@@ -62,7 +62,7 @@ func TestSMSProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.sms_configs_twilio (sms_id, instance_id, sid, token, sender_number) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.sms_configs2_twilio (sms_id, instance_id, sid, token, sender_number) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"id",
"instance-id",
@@ -101,7 +101,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.sms_configs_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.sms_configs2_twilio SET (sid, sender_number) = ($1, $2) WHERE (sms_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"sid",
"sender-number",
@@ -110,7 +110,7 @@ func TestSMSProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.sms_configs SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.sms_configs2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -147,7 +147,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.sms_configs_twilio SET token = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.sms_configs2_twilio SET token = $1 WHERE (sms_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
&crypto.CryptoValue{
CryptoType: crypto.TypeEncryption,
@@ -160,7 +160,7 @@ func TestSMSProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.sms_configs SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.sms_configs2 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -191,7 +191,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.sms_configs2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.SMSConfigStateActive,
anyArg{},
@@ -223,7 +223,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.sms_configs SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.sms_configs2 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.SMSConfigStateInactive,
anyArg{},
@@ -255,7 +255,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.sms_configs WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.sms_configs2 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"id",
"instance-id",
@@ -282,7 +282,7 @@ func TestSMSProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.sms_configs WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.sms_configs2 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+44 -10
View File
@@ -10,6 +10,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -18,7 +19,7 @@ type userProjection struct {
}
const (
UserTable = "projections.users5"
UserTable = "projections.users6"
UserHumanTable = UserTable + "_" + UserHumanSuffix
UserMachineTable = UserTable + "_" + UserMachineSuffix
UserNotifyTable = UserTable + "_" + UserNotifySuffix
@@ -32,6 +33,7 @@ const (
UserInstanceIDCol = "instance_id"
UserUsernameCol = "username"
UserTypeCol = "type"
UserOwnerRemovedCol = "owner_removed"
UserHumanSuffix = "humans"
HumanUserIDCol = "user_id"
@@ -87,10 +89,12 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(UserInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(UserUsernameCol, crdb.ColumnTypeText),
crdb.NewColumn(UserTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(UserOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(UserIDCol, UserInstanceIDCol),
crdb.WithIndex(crdb.NewIndex("username_idx5", []string{UserUsernameCol})),
crdb.WithIndex(crdb.NewIndex("user_ro_idx5", []string{UserResourceOwnerCol})),
crdb.NewPrimaryKey(UserInstanceIDCol, UserIDCol),
crdb.WithIndex(crdb.NewIndex("username", []string{UserUsernameCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{UserResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{UserOwnerRemovedCol})),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(HumanUserIDCol, crdb.ColumnTypeText),
@@ -107,9 +111,9 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(HumanPhoneCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(HumanIsPhoneVerifiedCol, crdb.ColumnTypeBool, crdb.Nullable()),
},
crdb.NewPrimaryKey(HumanUserIDCol, HumanUserInstanceIDCol),
crdb.NewPrimaryKey(HumanUserInstanceIDCol, HumanUserIDCol),
UserHumanSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_human_ref_user5")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(MachineUserIDCol, crdb.ColumnTypeText),
@@ -117,9 +121,9 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(MachineNameCol, crdb.ColumnTypeText),
crdb.NewColumn(MachineDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()),
},
crdb.NewPrimaryKey(MachineUserIDCol, MachineUserInstanceIDCol),
crdb.NewPrimaryKey(MachineUserInstanceIDCol, MachineUserIDCol),
UserMachineSuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_machine_ref_user5")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(NotifyUserIDCol, crdb.ColumnTypeText),
@@ -130,9 +134,9 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(NotifyVerifiedPhoneCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(NotifyPasswordSetCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(NotifyUserIDCol, NotifyInstanceIDCol),
crdb.NewPrimaryKey(NotifyInstanceIDCol, NotifyUserIDCol),
UserNotifySuffix,
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys("fk_notify_ref_user5")),
crdb.WithForeignKey(crdb.NewForeignKeyOfPublicKeys()),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -274,6 +278,15 @@ func (p *userProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -965,4 +978,25 @@ func (p *userProjection) reduceMachineChanged(event eventstore.Event) (*handler.
crdb.WithTableSuffix(UserMachineSuffix),
),
), nil
}
func (p *userProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-NCsdV", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(UserChangeDateCol, e.CreationDate()),
handler.NewCol(UserSequenceCol, e.Sequence()),
handler.NewCol(UserOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(UserInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(UserResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
+35 -2
View File
@@ -9,11 +9,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
UserAuthMethodTable = "projections.user_auth_methods3"
UserAuthMethodTable = "projections.user_auth_methods4"
UserAuthMethodUserIDCol = "user_id"
UserAuthMethodTypeCol = "method_type"
@@ -25,6 +26,7 @@ const (
UserAuthMethodInstanceIDCol = "instance_id"
UserAuthMethodStateCol = "state"
UserAuthMethodNameCol = "name"
UserAuthMethodOwnerRemovedCol = "owner_removed"
)
type userAuthMethodProjection struct {
@@ -47,9 +49,11 @@ func newUserAuthMethodProjection(ctx context.Context, config crdb.StatementHandl
crdb.NewColumn(UserAuthMethodResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(UserAuthMethodInstanceIDCol, crdb.ColumnTypeText),
crdb.NewColumn(UserAuthMethodNameCol, crdb.ColumnTypeText),
crdb.NewColumn(UserAuthMethodOwnerRemovedCol, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(UserAuthMethodInstanceIDCol, UserAuthMethodUserIDCol, UserAuthMethodTypeCol, UserAuthMethodTokenIDCol),
crdb.WithIndex(crdb.NewIndex("auth_meth_ro_idx", []string{UserAuthMethodResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{UserAuthMethodResourceOwnerCol})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{UserAuthMethodOwnerRemovedCol})),
),
)
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
@@ -99,6 +103,15 @@ func (p *userAuthMethodProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -219,3 +232,23 @@ func (p *userAuthMethodProjection) reduceRemoveAuthMethod(event eventstore.Event
conditions,
), nil
}
func (p *userAuthMethodProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-FwDZ8", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(UserAuthMethodChangeDateCol, e.CreationDate()),
handler.NewCol(UserAuthMethodSequenceCol, e.Sequence()),
handler.NewCol(UserAuthMethodOwnerRemovedCol, true),
},
[]handler.Condition{
handler.NewCond(UserAuthMethodInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCond(UserAuthMethodResourceOwnerCol, e.Aggregate().ID),
},
), nil
}
@@ -9,6 +9,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -41,7 +42,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_auth_methods3 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedStmt: "INSERT INTO projections.user_auth_methods4 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedArgs: []interface{}{
"token-id",
anyArg{},
@@ -78,7 +79,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_auth_methods3 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedStmt: "INSERT INTO projections.user_auth_methods4 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedArgs: []interface{}{
"token-id",
anyArg{},
@@ -114,7 +115,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_auth_methods3 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedStmt: "INSERT INTO projections.user_auth_methods4 (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) ON CONFLICT (instance_id, user_id, method_type, token_id) DO UPDATE SET (creation_date, change_date, resource_owner, sequence, state, name) = (EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.resource_owner, EXCLUDED.sequence, EXCLUDED.state, EXCLUDED.name)",
expectedArgs: []interface{}{
"",
anyArg{},
@@ -152,7 +153,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_auth_methods3 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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.user_auth_methods4 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) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -189,7 +190,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_auth_methods3 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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.user_auth_methods4 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) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -224,7 +225,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_auth_methods3 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) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.user_auth_methods4 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) AND (instance_id = $9)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -241,6 +242,36 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
},
},
},
{
name: "org reduceOwnerRemoved",
reduce: (&userAuthMethodProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_auth_methods4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -258,7 +289,7 @@ func TestUserAuthMethodProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_auth_methods3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.user_auth_methods4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+193 -14
View File
@@ -3,6 +3,7 @@ package projection
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
@@ -10,25 +11,33 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/repository/usergrant"
)
const (
UserGrantProjectionTable = "projections.user_grants2"
UserGrantProjectionTable = "projections.user_grants3"
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"
UserGrantID = "id"
UserGrantCreationDate = "creation_date"
UserGrantChangeDate = "change_date"
UserGrantSequence = "sequence"
UserGrantState = "state"
UserGrantResourceOwner = "resource_owner"
UserGrantInstanceID = "instance_id"
UserGrantUserID = "user_id"
UserGrantResourceOwnerUser = "resource_owner_user"
UserGrantUserOwnerRemoved = "user_owner_removed"
UserGrantProjectID = "project_id"
UserGrantResourceOwnerProject = "resource_owner_project"
UserGrantProjectOwnerRemoved = "project_owner_removed"
UserGrantGrantID = "grant_id"
UserGrantGrantedOrg = "granted_org"
UserGrantGrantedOrgRemoved = "granted_org_removed"
UserGrantRoles = "roles"
UserGrantOwnerRemoved = "owner_removed"
)
type userGrantProjection struct {
@@ -49,13 +58,24 @@ func newUserGrantProjection(ctx context.Context, config crdb.StatementHandlerCon
crdb.NewColumn(UserGrantResourceOwner, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantUserID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantResourceOwnerUser, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantUserOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(UserGrantProjectID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantResourceOwnerProject, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantProjectOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(UserGrantGrantID, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantGrantedOrg, crdb.ColumnTypeText),
crdb.NewColumn(UserGrantGrantedOrgRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(UserGrantRoles, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(UserGrantOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(UserGrantInstanceID, UserGrantID),
crdb.WithIndex(crdb.NewIndex("user_grant_user_idx", []string{UserGrantUserID})),
crdb.WithIndex(crdb.NewIndex("user_grant_ro_idx", []string{UserGrantResourceOwner})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{UserGrantUserID})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{UserGrantResourceOwner})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{UserGrantOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("user_owner_removed", []string{UserGrantUserOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("project_owner_removed", []string{UserGrantProjectOwnerRemoved})),
crdb.WithIndex(crdb.NewIndex("granted_org_removed", []string{UserGrantGrantedOrgRemoved})),
),
)
@@ -132,6 +152,15 @@ func (p *userGrantProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -149,6 +178,27 @@ func (p *userGrantProjection) reduceAdded(event eventstore.Event) (*handler.Stat
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-MQHVB", "reduce.wrong.event.type %s", usergrant.UserGrantAddedType)
}
ctx := setUserGrantContext(e.Aggregate())
userOwner, err := getResourceOwnerOfUser(ctx, p.Eventstore, e.Aggregate().InstanceID, e.UserID)
if err != nil {
return nil, err
}
projectOwner := ""
grantOwner := ""
if e.ProjectGrantID != "" {
grantOwner, err = getGrantedOrgOfGrantedProject(ctx, p.Eventstore, e.Aggregate().InstanceID, e.ProjectID, e.ProjectGrantID)
if err != nil {
return nil, err
}
} else {
projectOwner, err = getResourceOwnerOfProject(ctx, p.Eventstore, e.Aggregate().InstanceID, e.ProjectID)
if err != nil {
return nil, err
}
}
return crdb.NewCreateStatement(
e,
[]handler.Column{
@@ -159,8 +209,11 @@ func (p *userGrantProjection) reduceAdded(event eventstore.Event) (*handler.Stat
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
handler.NewCol(UserGrantUserID, e.UserID),
handler.NewCol(UserGrantResourceOwnerUser, userOwner),
handler.NewCol(UserGrantProjectID, e.ProjectID),
handler.NewCol(UserGrantResourceOwnerProject, projectOwner),
handler.NewCol(UserGrantGrantID, e.ProjectGrantID),
handler.NewCol(UserGrantGrantedOrg, grantOwner),
handler.NewCol(UserGrantRoles, database.StringArray(e.RoleKeys)),
handler.NewCol(UserGrantState, domain.UserGrantStateActive),
},
@@ -334,3 +387,129 @@ func (p *userGrantProjection) reduceProjectGrantChanged(event eventstore.Event)
},
), nil
}
func (p *userGrantProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-jpIvp", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewMultiStatement(
e,
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
handler.NewCol(UserGrantOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID),
handler.NewCond(UserGrantResourceOwner, e.Aggregate().ID),
},
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
handler.NewCol(UserGrantUserOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID),
handler.NewCond(UserGrantResourceOwnerUser, e.Aggregate().ID),
},
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
handler.NewCol(UserGrantProjectOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID),
handler.NewCond(UserGrantResourceOwnerProject, e.Aggregate().ID),
},
),
crdb.AddUpdateStatement(
[]handler.Column{
handler.NewCol(UserGrantChangeDate, e.CreationDate()),
handler.NewCol(UserGrantSequence, e.Sequence()),
handler.NewCol(UserGrantGrantedOrgRemoved, true),
},
[]handler.Condition{
handler.NewCond(UserGrantInstanceID, e.Aggregate().InstanceID),
handler.NewCond(UserGrantGrantedOrg, e.Aggregate().ID),
},
),
), nil
}
func getResourceOwnerOfUser(ctx context.Context, es *eventstore.Eventstore, instanceID, aggID string) (string, error) {
events, err := es.Filter(
ctx,
eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
InstanceID(instanceID).
AddQuery().
AggregateTypes(user.AggregateType).
AggregateIDs(aggID).
EventTypes(user.HumanRegisteredType, user.HumanAddedType, user.MachineAddedEventType).
Builder(),
)
if err != nil {
return "", err
}
if len(events) != 1 {
return "", errors.ThrowNotFound(nil, "PROJ-0I92sp", "Errors.User.NotFound")
}
return events[0].Aggregate().ResourceOwner, nil
}
func getResourceOwnerOfProject(ctx context.Context, es *eventstore.Eventstore, instanceID, aggID string) (string, error) {
events, err := es.Filter(
ctx,
eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
InstanceID(instanceID).
AddQuery().
AggregateTypes(project.AggregateType).
AggregateIDs(aggID).
EventTypes(project.ProjectAddedType).
Builder(),
)
if err != nil {
return "", err
}
if len(events) != 1 {
return "", errors.ThrowNotFound(nil, "PROJ-0I91sp", "Errors.Project.NotFound")
}
return events[0].Aggregate().ResourceOwner, nil
}
func getGrantedOrgOfGrantedProject(ctx context.Context, es *eventstore.Eventstore, instanceID, projectID, grantID string) (string, error) {
events, err := es.Filter(
ctx,
eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
InstanceID(instanceID).
AddQuery().
AggregateTypes(project.AggregateType).
AggregateIDs(projectID).
EventTypes(project.GrantAddedType).
EventData(map[string]interface{}{
"grantId": grantID,
}).
Builder(),
)
if err != nil {
return "", err
}
if len(events) != 1 {
return "", errors.ThrowNotFound(nil, "PROJ-MoaSpw", "Errors.Grant.NotFound")
}
grantAddedEvent, ok := events[0].(*project.GrantAddedEvent)
if !ok {
return "", errors.ThrowNotFound(nil, "PROJ-P0s2o0", "Errors.Grant.NotFound")
}
return grantAddedEvent.GrantedOrgID, nil
}
func setUserGrantContext(event eventstore.Aggregate) context.Context {
return authz.WithInstanceID(context.Background(), event.InstanceID)
}
+194 -14
View File
@@ -1,15 +1,20 @@
package projection
import (
"context"
"testing"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/repository/usergrant"
@@ -38,7 +43,29 @@ func TestUserGrantProjection_reduces(t *testing.T) {
}`),
), usergrant.UserGrantAddedEventMapper),
},
reduce: (&userGrantProjection{}).reduceAdded,
reduce: (&userGrantProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
project.NewProjectAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"project",
false,
false,
false,
domain.PrivateLabelingSettingUnspecified,
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: usergrant.AggregateType,
sequence: 15,
@@ -46,7 +73,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_grants2 (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)",
expectedStmt: "INSERT INTO projections.user_grants3 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedArgs: []interface{}{
"agg-id",
"ro-id",
@@ -55,8 +82,75 @@ func TestUserGrantProjection_reduces(t *testing.T) {
anyArg{},
uint64(15),
"user-id",
"org1",
"project-id",
"org2",
"",
"",
database.StringArray{"role"},
domain.UserGrantStateActive,
},
},
},
},
},
},
{
name: "reduceAdded with projectgrant",
args: args{
event: getEvent(testEvent(
repository.EventType(usergrant.UserGrantAddedType),
usergrant.AggregateType,
[]byte(`{
"userId": "user-id",
"projectId": "project-id",
"grantId": "grant-id",
"roleKeys": ["role"]
}`),
), usergrant.UserGrantAddedEventMapper),
},
reduce: (&userGrantProjection{
StatementHandler: getStatementHandlerWithFilters(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user-id", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
project.NewGrantAddedEvent(context.Background(),
&project.NewAggregate("project-id", "org2").Aggregate,
"grant-id",
"org3",
[]string{},
),
)(t)}).reduceAdded,
want: wantReduce{
aggregateType: usergrant.AggregateType,
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_grants3 (id, resource_owner, instance_id, creation_date, change_date, sequence, user_id, resource_owner_user, project_id, resource_owner_project, grant_id, granted_org, roles, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
expectedArgs: []interface{}{
"agg-id",
"ro-id",
"instance-id",
anyArg{},
anyArg{},
uint64(15),
"user-id",
"org1",
"project-id",
"",
"grant-id",
"org3",
database.StringArray{"role"},
domain.UserGrantStateActive,
},
@@ -84,7 +178,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
database.StringArray{"role"},
@@ -116,7 +210,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, roles, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
database.StringArray{"role"},
@@ -146,7 +240,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -173,7 +267,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -199,7 +293,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -226,7 +320,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserGrantStateInactive,
@@ -256,7 +350,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserGrantStateActive,
@@ -286,7 +380,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -313,7 +407,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
anyArg{},
"instance-id",
@@ -340,7 +434,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_grants2 WHERE (grant_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_grants3 WHERE (grant_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"grantID",
"instance-id",
@@ -367,7 +461,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET roles = array_remove(roles, $1) WHERE (project_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.user_grants3 SET roles = array_remove(roles, $1) WHERE (project_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"key",
"agg-id",
@@ -395,7 +489,7 @@ func TestUserGrantProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants2 SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::TEXT[]))) WHERE (grant_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.user_grants3 SET (roles) = (SELECT ARRAY( SELECT UNNEST(roles) INTERSECT SELECT UNNEST ($1::TEXT[]))) WHERE (grant_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
database.StringArray{"key"},
"grantID",
@@ -406,6 +500,66 @@ func TestUserGrantProjection_reduces(t *testing.T) {
},
},
},
{
name: "org.reduceOwnerRemoved",
reduce: (&userGrantProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, user_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner_user = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, project_owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner_project = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
{
expectedStmt: "UPDATE projections.user_grants3 SET (change_date, sequence, granted_org_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (granted_org = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -421,3 +575,29 @@ func TestUserGrantProjection_reduces(t *testing.T) {
})
}
}
func getStatementHandlerWithFilters(events ...eventstore.Command) func(t *testing.T) crdb.StatementHandler {
filters := make([]expect, 0)
for _, event := range events {
filters = append(filters,
expectFilter(
eventFromEventPusher(
event,
),
),
)
}
return func(t *testing.T) crdb.StatementHandler {
return crdb.StatementHandler{
ProjectionHandler: &handler.ProjectionHandler{
Handler: handler.Handler{
Eventstore: eventstoreExpect(
t,
filters...,
),
},
},
}
}
}
+35 -2
View File
@@ -8,11 +8,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
UserMetadataProjectionTable = "projections.user_metadata3"
UserMetadataProjectionTable = "projections.user_metadata4"
UserMetadataColumnUserID = "user_id"
UserMetadataColumnCreationDate = "creation_date"
@@ -22,6 +23,7 @@ const (
UserMetadataColumnInstanceID = "instance_id"
UserMetadataColumnKey = "key"
UserMetadataColumnValue = "value"
UserMetadataColumnOwnerRemoved = "owner_removed"
)
type userMetadataProjection struct {
@@ -42,9 +44,11 @@ func newUserMetadataProjection(ctx context.Context, config crdb.StatementHandler
crdb.NewColumn(UserMetadataColumnInstanceID, crdb.ColumnTypeText),
crdb.NewColumn(UserMetadataColumnKey, crdb.ColumnTypeText),
crdb.NewColumn(UserMetadataColumnValue, crdb.ColumnTypeBytes, crdb.Nullable()),
crdb.NewColumn(UserMetadataColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(UserMetadataColumnInstanceID, UserMetadataColumnUserID, UserMetadataColumnKey),
crdb.WithIndex(crdb.NewIndex("usr_md_ro_idx", []string{UserGrantResourceOwner})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{UserGrantResourceOwner})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{UserMetadataColumnOwnerRemoved})),
),
)
@@ -75,6 +79,15 @@ func (p *userMetadataProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -143,3 +156,23 @@ func (p *userMetadataProjection) reduceMetadataRemovedAll(event eventstore.Event
},
), nil
}
func (p *userMetadataProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-oqwul", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(UserMetadataColumnChangeDate, e.CreationDate()),
handler.NewCol(UserMetadataColumnSequence, e.Sequence()),
handler.NewCol(UserMetadataColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(UserMetadataColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(UserMetadataColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
@@ -8,6 +8,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -41,7 +42,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.user_metadata3 (instance_id, user_id, key, resource_owner, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (instance_id, user_id, key) DO UPDATE SET (resource_owner, creation_date, change_date, sequence, value) = (EXCLUDED.resource_owner, EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedStmt: "INSERT INTO projections.user_metadata4 (instance_id, user_id, key, resource_owner, creation_date, change_date, sequence, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (instance_id, user_id, key) DO UPDATE SET (resource_owner, creation_date, change_date, sequence, value) = (EXCLUDED.resource_owner, EXCLUDED.creation_date, EXCLUDED.change_date, EXCLUDED.sequence, EXCLUDED.value)",
expectedArgs: []interface{}{
"instance-id",
"agg-id",
@@ -76,7 +77,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_metadata3 WHERE (user_id = $1) AND (key = $2) AND (instance_id = $3)",
expectedStmt: "DELETE FROM projections.user_metadata4 WHERE (user_id = $1) AND (key = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"agg-id",
"key",
@@ -104,7 +105,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_metadata3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_metadata4 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -131,7 +132,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_metadata3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.user_metadata4 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -141,6 +142,36 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
},
},
},
{
name: "org reduceOwnerRemoved",
reduce: (&userMetadataProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.user_metadata4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -158,7 +189,7 @@ func TestUserMetadataProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.user_metadata3 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.user_metadata4 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -9,11 +9,12 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
PersonalAccessTokenProjectionTable = "projections.personal_access_tokens2"
PersonalAccessTokenProjectionTable = "projections.personal_access_tokens3"
PersonalAccessTokenColumnID = "id"
PersonalAccessTokenColumnCreationDate = "creation_date"
@@ -24,6 +25,7 @@ const (
PersonalAccessTokenColumnUserID = "user_id"
PersonalAccessTokenColumnExpiration = "expiration"
PersonalAccessTokenColumnScopes = "scopes"
PersonalAccessTokenColumnOwnerRemoved = "owner_removed"
)
type personalAccessTokenProjection struct {
@@ -45,10 +47,12 @@ func newPersonalAccessTokenProjection(ctx context.Context, config crdb.Statement
crdb.NewColumn(PersonalAccessTokenColumnUserID, crdb.ColumnTypeText),
crdb.NewColumn(PersonalAccessTokenColumnExpiration, crdb.ColumnTypeTimestamp),
crdb.NewColumn(PersonalAccessTokenColumnScopes, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(PersonalAccessTokenColumnOwnerRemoved, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(PersonalAccessTokenColumnInstanceID, PersonalAccessTokenColumnID),
crdb.WithIndex(crdb.NewIndex("pat_user_idx", []string{PersonalAccessTokenColumnUserID})),
crdb.WithIndex(crdb.NewIndex("pat_ro_idx", []string{PersonalAccessTokenColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("user_id", []string{PersonalAccessTokenColumnUserID})),
crdb.WithIndex(crdb.NewIndex("resource_owner", []string{PersonalAccessTokenColumnResourceOwner})),
crdb.WithIndex(crdb.NewIndex("owner_removed", []string{PersonalAccessTokenColumnOwnerRemoved})),
),
)
@@ -75,6 +79,15 @@ func (p *personalAccessTokenProjection) reducers() []handler.AggregateReducer {
},
},
},
{
Aggregate: org.AggregateType,
EventRedusers: []handler.EventReducer{
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOwnerRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventRedusers: []handler.EventReducer{
@@ -135,3 +148,23 @@ func (p *personalAccessTokenProjection) reduceUserRemoved(event eventstore.Event
},
), nil
}
func (p *personalAccessTokenProjection) reduceOwnerRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "PROJE-zQVhl", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
}
return crdb.NewUpdateStatement(
e,
[]handler.Column{
handler.NewCol(PersonalAccessTokenColumnChangeDate, e.CreationDate()),
handler.NewCol(PersonalAccessTokenColumnSequence, e.Sequence()),
handler.NewCol(PersonalAccessTokenColumnOwnerRemoved, true),
},
[]handler.Condition{
handler.NewCond(PersonalAccessTokenColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCond(PersonalAccessTokenColumnResourceOwner, e.Aggregate().ID),
},
), nil
}
@@ -10,6 +10,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -40,7 +41,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.personal_access_tokens2 (id, creation_date, change_date, resource_owner, instance_id, sequence, user_id, expiration, scopes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.personal_access_tokens3 (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{},
@@ -74,7 +75,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.personal_access_tokens2 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.personal_access_tokens3 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"tokenID",
"instance-id",
@@ -101,7 +102,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.personal_access_tokens2 WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.personal_access_tokens3 WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -111,6 +112,36 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
},
},
},
{
name: "org reduceOwnerRemoved",
reduce: (&personalAccessTokenProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.personal_access_tokens3 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -128,7 +159,7 @@ func TestPersonalAccessTokenProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.personal_access_tokens2 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.personal_access_tokens3 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
+109 -78
View File
@@ -10,6 +10,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/handler"
"github.com/zitadel/zitadel/internal/eventstore/repository"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/repository/user"
)
@@ -50,7 +51,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -64,7 +65,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -79,7 +80,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -119,7 +120,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -133,7 +134,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -148,7 +149,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -183,7 +184,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -197,7 +198,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -212,7 +213,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -252,7 +253,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -266,7 +267,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -281,7 +282,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -321,7 +322,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -335,7 +336,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -350,7 +351,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -385,7 +386,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -399,7 +400,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedStmt: "INSERT INTO projections.users6_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -414,7 +415,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.users6_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -444,7 +445,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
domain.UserStateInitial,
"agg-id",
@@ -472,7 +473,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
domain.UserStateInitial,
"agg-id",
@@ -500,7 +501,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
domain.UserStateActive,
"agg-id",
@@ -528,7 +529,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
domain.UserStateActive,
"agg-id",
@@ -556,7 +557,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserStateLocked,
@@ -586,7 +587,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserStateActive,
@@ -616,7 +617,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserStateInactive,
@@ -646,7 +647,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
domain.UserStateActive,
@@ -676,7 +677,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.users5 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.users6 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -705,7 +706,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
"username",
@@ -737,7 +738,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.users6 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
"[email protected]",
@@ -774,7 +775,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -783,7 +784,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedStmt: "UPDATE projections.users6_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{
"first-name",
"last-name",
@@ -823,7 +824,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -832,7 +833,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedStmt: "UPDATE projections.users6_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{
"first-name",
"last-name",
@@ -867,7 +868,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -876,7 +877,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"+41 00 000 00 00",
false,
@@ -885,7 +886,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
"agg-id",
@@ -915,7 +916,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -924,7 +925,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"+41 00 000 00 00",
false,
@@ -933,7 +934,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
&sql.NullString{String: "+41 00 000 00 00", Valid: true},
"agg-id",
@@ -961,7 +962,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -970,7 +971,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
nil,
nil,
@@ -979,7 +980,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
nil,
nil,
@@ -1008,7 +1009,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1017,7 +1018,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
nil,
nil,
@@ -1026,7 +1027,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
nil,
nil,
@@ -1055,7 +1056,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1064,7 +1065,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
true,
"agg-id",
@@ -1072,7 +1073,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.users6_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1099,7 +1100,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1108,7 +1109,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
true,
"agg-id",
@@ -1116,7 +1117,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.users6_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1145,7 +1146,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1154,7 +1155,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"[email protected]",
false,
@@ -1163,7 +1164,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
&sql.NullString{String: "[email protected]", Valid: true},
"agg-id",
@@ -1193,7 +1194,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1202,7 +1203,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"[email protected]",
false,
@@ -1211,7 +1212,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
&sql.NullString{String: "[email protected]", Valid: true},
"agg-id",
@@ -1239,7 +1240,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1248,7 +1249,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
true,
"agg-id",
@@ -1256,7 +1257,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.users6_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1283,7 +1284,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1292,7 +1293,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
true,
"agg-id",
@@ -1300,7 +1301,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedStmt: "UPDATE projections.users6_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1329,7 +1330,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1338,7 +1339,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"users/agg-id/avatar",
"agg-id",
@@ -1366,7 +1367,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1375,7 +1376,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
nil,
"agg-id",
@@ -1406,7 +1407,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -1420,7 +1421,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.users6_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1453,7 +1454,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.users5 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.users6 (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{},
@@ -1467,7 +1468,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "INSERT INTO projections.users5_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
expectedStmt: "INSERT INTO projections.users6_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -1499,7 +1500,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1508,7 +1509,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
"machine-name",
"description",
@@ -1539,7 +1540,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1548,7 +1549,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_machines SET name = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_machines SET name = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"machine-name",
"agg-id",
@@ -1578,7 +1579,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -1587,7 +1588,7 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.users5_machines SET description = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.users6_machines SET description = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
"description",
"agg-id",
@@ -1617,6 +1618,36 @@ func TestUserProjection_reduces(t *testing.T) {
},
},
},
{
name: "org reduceOwnerRemoved",
reduce: (&userProjection{}).reduceOwnerRemoved,
args: args{
event: getEvent(testEvent(
repository.EventType(org.OrgRemovedEventType),
org.AggregateType,
nil,
), org.OrgRemovedEventMapper),
},
want: wantReduce{
aggregateType: eventstore.AggregateType("org"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.users6 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"instance-id",
"agg-id",
},
},
},
},
},
},
{
name: "instance reduceInstanceRemoved",
args: args{
@@ -1634,7 +1665,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.users5 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.users6 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},