mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-15 02:15:14 +00:00
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:
co-authored by
Stefan Benz
Livio Spring
Fabi
Stefan Benz
parent
21a4e73bb6
commit
f3e6f3b23b
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 != ""},
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 +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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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...,
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user