diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index 029925fa1a..b9d92f9637 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -15,7 +15,7 @@ SystemDefaults: IncludeLowerLetters: true IncludeUpperLetters: true IncludeDigits: true - IncludeSymbols: true + IncludeSymbols: false InitializeUserCode: Length: 6 Expiry: '72h' diff --git a/internal/api/oidc/auth_request.go b/internal/api/oidc/auth_request.go index 69dd528654..ea471a4b1e 100644 --- a/internal/api/oidc/auth_request.go +++ b/internal/api/oidc/auth_request.go @@ -89,7 +89,7 @@ func (o *OPStorage) CreateToken(ctx context.Context, req op.TokenRequest) (_ str userAgentID = authReq.AgentID applicationID = authReq.ApplicationID } - resp, err := o.command.CreateUserToken(ctx, authReq.UserOrgID, userAgentID, applicationID, req.GetSubject(), req.GetAudience(), req.GetScopes(), o.defaultAccessTokenLifetime) //PLANNED: lifetime from client + resp, err := o.command.AddUserToken(ctx, authReq.UserOrgID, userAgentID, applicationID, req.GetSubject(), req.GetAudience(), req.GetScopes(), o.defaultAccessTokenLifetime) //PLANNED: lifetime from client if err != nil { return "", time.Time{}, err } diff --git a/internal/eventstore/v2/aggregate.go b/internal/eventstore/v2/aggregate.go index 5abbc7fab9..d3e84f2229 100644 --- a/internal/eventstore/v2/aggregate.go +++ b/internal/eventstore/v2/aggregate.go @@ -1,86 +1,66 @@ package eventstore -type Aggregater interface { - //ID returns the aggreagte id - ID() string - //KeyType returns the aggregate type - Type() AggregateType - //Events returns the events which will be pushed - Events() []EventPusher - //ResourceOwner returns the organisation id which manages this aggregate - // resource owner is only on the inital push needed - // afterwards the resource owner of the previous event is taken - ResourceOwner() string - //Version represents the semantic version of the aggregate - Version() Version -} +import ( + "context" + "github.com/caos/zitadel/internal/api/authz" +) + +type aggregateOpt func(*Aggregate) + +//NewAggregate is the default constructor of an aggregate +// opts overwrite values calculated by given parameters func NewAggregate( + ctx context.Context, id string, typ AggregateType, - resourceOwner string, version Version, + opts ...aggregateOpt, ) *Aggregate { - return &Aggregate{ - id: id, - typ: typ, - resourceOwner: resourceOwner, - version: version, - events: []EventPusher{}, + a := &Aggregate{ + ID: id, + Typ: typ, + ResourceOwner: authz.GetCtxData(ctx).OrgID, + Version: version, + } + + for _, opt := range opts { + opt(a) + } + + return a +} + +//WithResourceOwner overwrites the resource owner of the aggregate +// by default the resource owner is set by the context +func WithResourceOwner(resourceOwner string) aggregateOpt { + return func(aggregate *Aggregate) { + aggregate.ResourceOwner = resourceOwner } } +//AggregateFromWriteModel maps the given WriteModel to an Aggregate func AggregateFromWriteModel( wm *WriteModel, typ AggregateType, version Version, ) *Aggregate { return &Aggregate{ - id: wm.AggregateID, - typ: typ, - resourceOwner: wm.ResourceOwner, - version: version, - events: []EventPusher{}, + ID: wm.AggregateID, + Typ: typ, + ResourceOwner: wm.ResourceOwner, + Version: version, } } //Aggregate is the basic implementation of Aggregater type Aggregate struct { - id string `json:"-"` - typ AggregateType `json:"-"` - events []EventPusher `json:"-"` - resourceOwner string `json:"-"` - version Version `json:"-"` -} - -//PushEvents adds all the events to the aggregate. -// The added events will be pushed to eventstore -func (a *Aggregate) PushEvents(events ...EventPusher) *Aggregate { - a.events = append(a.events, events...) - return a -} - -//ID implements Aggregater -func (a *Aggregate) ID() string { - return a.id -} - -//KeyType implements Aggregater -func (a *Aggregate) Type() AggregateType { - return a.typ -} - -//Events implements Aggregater -func (a *Aggregate) Events() []EventPusher { - return a.events -} - -//ResourceOwner implements Aggregater -func (a *Aggregate) ResourceOwner() string { - return a.resourceOwner -} - -//Version implements Aggregater -func (a *Aggregate) Version() Version { - return a.version + //ID is the unique identitfier of this aggregate + ID string `json:"-"` + //Typ is the name of the aggregate. + Typ AggregateType `json:"-"` + //ResourceOwner is the org this aggregates belongs to + ResourceOwner string `json:"-"` + //Version is the semver this aggregate represents + Version Version `json:"-"` } diff --git a/internal/eventstore/v2/event.go b/internal/eventstore/v2/event.go index 08a4e64aec..775a3cc97c 100644 --- a/internal/eventstore/v2/event.go +++ b/internal/eventstore/v2/event.go @@ -5,6 +5,8 @@ import ( ) type EventPusher interface { + //Aggregate is the metadata of an aggregate + Aggregate() Aggregate // EditorService is the service who wants to push the event EditorService() string //EditorUser is the user who wants to push the event @@ -30,10 +32,8 @@ type EventReader interface { //KeyType is the type of the event Type() EventType - AggregateID() string - AggregateType() AggregateType - ResourceOwner() string - AggregateVersion() Version + Aggregate() Aggregate + Sequence() uint64 CreationDate() time.Time } diff --git a/internal/eventstore/v2/event_base.go b/internal/eventstore/v2/event_base.go index 4dc3b2b077..9f9980e68a 100644 --- a/internal/eventstore/v2/event_base.go +++ b/internal/eventstore/v2/event_base.go @@ -9,15 +9,14 @@ import ( "github.com/caos/zitadel/internal/eventstore/v2/repository" ) +//BaseEvent represents the minimum metadata of an event type BaseEvent struct { - aggregateID string `json:"-"` - aggregateType AggregateType `json:"-"` - EventType EventType `json:"-"` + EventType EventType - resourceOwner string `json:"-"` - aggregateVersion Version `json:"-"` - sequence uint64 `json:"-"` - creationDate time.Time `json:"-"` + aggregate Aggregate + + sequence uint64 + creationDate time.Time //User is the user who created the event User string `json:"-"` @@ -35,59 +34,51 @@ func (e *BaseEvent) EditorUser() string { return e.User } -//KeyType implements EventPusher +//Type implements EventPusher func (e *BaseEvent) Type() EventType { return e.EventType } -func (e *BaseEvent) AggregateID() string { - return e.aggregateID -} -func (e *BaseEvent) AggregateType() AggregateType { - return e.aggregateType -} -func (e *BaseEvent) ResourceOwner() string { - return e.resourceOwner -} -func (e *BaseEvent) AggregateVersion() Version { - return e.aggregateVersion -} +//Sequence is an upcounting unique number of the event func (e *BaseEvent) Sequence() uint64 { return e.sequence } + +//CreationDate is the the time, the event is inserted into the eventstore func (e *BaseEvent) CreationDate() time.Time { return e.creationDate } +//Aggregate represents the metadata of the event's aggregate +func (e *BaseEvent) Aggregate() Aggregate { + return e.aggregate +} + +//BaseEventFromRepo maps a stored event to a BaseEvent func BaseEventFromRepo(event *repository.Event) *BaseEvent { return &BaseEvent{ - aggregateID: event.AggregateID, - aggregateType: AggregateType(event.AggregateType), - aggregateVersion: Version(event.Version), - EventType: EventType(event.Type), - creationDate: event.CreationDate, - sequence: event.Sequence, - resourceOwner: event.ResourceOwner, - Service: event.EditorService, - User: event.EditorUser, + aggregate: Aggregate{ + ID: event.AggregateID, + Typ: AggregateType(event.AggregateType), + ResourceOwner: event.ResourceOwner, + Version: Version(event.Version), + }, + EventType: EventType(event.Type), + creationDate: event.CreationDate, + sequence: event.Sequence, + Service: event.EditorService, + User: event.EditorUser, } } -func NewBaseEventForPush(ctx context.Context, typ EventType) *BaseEvent { - svcName := service.FromContext(ctx) +//NewBaseEventForPush is the constructor for event's which will be pushed into the eventstore +// the resource owner of the aggregate is only used if it's the first event of this aggregateroot +// afterwards the resource owner of the first previous events is taken +func NewBaseEventForPush(ctx context.Context, aggregate *Aggregate, typ EventType) *BaseEvent { return &BaseEvent{ + aggregate: *aggregate, User: authz.GetCtxData(ctx).UserID, - Service: svcName, + Service: service.FromContext(ctx), EventType: typ, } } - -func NewBaseEventForPushWithResourceOwner(ctx context.Context, typ EventType, resourceOwner string) *BaseEvent { - svcName := service.FromContext(ctx) - return &BaseEvent{ - User: authz.GetCtxData(ctx).UserID, - Service: svcName, - EventType: typ, - resourceOwner: resourceOwner, - } -} diff --git a/internal/eventstore/v2/eventstore.go b/internal/eventstore/v2/eventstore.go index 052d738d42..501a7077cc 100644 --- a/internal/eventstore/v2/eventstore.go +++ b/internal/eventstore/v2/eventstore.go @@ -36,67 +36,56 @@ func (es *Eventstore) Health(ctx context.Context) error { return es.repo.Health(ctx) } -//PushAggregate pushes the aggregate and reduces the new events on the aggregate -func (es *Eventstore) PushAggregate(ctx context.Context, writeModel queryReducer, aggregate Aggregater) error { - events, err := es.PushAggregates(ctx, aggregate) - if err != nil { - return err - } - - writeModel.AppendEvents(events...) - return writeModel.Reduce() -} - -//PushAggregates maps the events of all aggregates to an eventstore event -// based on the pushMapper -func (es *Eventstore) PushAggregates(ctx context.Context, aggregates ...Aggregater) ([]EventReader, error) { - events, uniqueConstraints, err := es.aggregatesToEvents(aggregates) +//PushEvents pushes the events in a single transaction +// an event needs at least an aggregate +func (es *Eventstore) PushEvents(ctx context.Context, pushEvents ...EventPusher) ([]EventReader, error) { + events, constraints, err := eventsToRepository(pushEvents) if err != nil { return nil, err } - - err = es.repo.Push(ctx, events, uniqueConstraints...) + err = es.repo.Push(ctx, events, constraints...) if err != nil { return nil, err } - return es.mapEvents(events) } -func (es *Eventstore) aggregatesToEvents(aggregates []Aggregater) ([]*repository.Event, []*repository.UniqueConstraint, error) { - events := make([]*repository.Event, 0, len(aggregates)) - uniqueConstraints := make([]*repository.UniqueConstraint, 0) - for _, aggregate := range aggregates { - for _, event := range aggregate.Events() { - data, err := eventData(event) - if err != nil { - return nil, nil, err - } - events = append(events, &repository.Event{ - AggregateID: aggregate.ID(), - AggregateType: repository.AggregateType(aggregate.Type()), - ResourceOwner: aggregate.ResourceOwner(), - EditorService: event.EditorService(), - EditorUser: event.EditorUser(), - Type: repository.EventType(event.Type()), - Version: repository.Version(aggregate.Version()), - Data: data, - }) - if event.UniqueConstraints() != nil { - for _, constraint := range event.UniqueConstraints() { - uniqueConstraints = append(uniqueConstraints, - &repository.UniqueConstraint{ - UniqueType: constraint.UniqueType, - UniqueField: constraint.UniqueField, - Action: uniqueConstraintActionToRepository(constraint.Action), - ErrorMessage: constraint.ErrorMessage, - }, - ) - } - } +func eventsToRepository(pushEvents []EventPusher) (events []*repository.Event, constraints []*repository.UniqueConstraint, err error) { + events = make([]*repository.Event, len(pushEvents)) + for i, event := range pushEvents { + data, err := eventData(event) + if err != nil { + return nil, nil, err + } + events[i] = &repository.Event{ + AggregateID: event.Aggregate().ID, + AggregateType: repository.AggregateType(event.Aggregate().Typ), + ResourceOwner: event.Aggregate().ResourceOwner, + EditorService: event.EditorService(), + EditorUser: event.EditorUser(), + Type: repository.EventType(event.Type()), + Version: repository.Version(event.Aggregate().Version), + Data: data, + } + if len(event.UniqueConstraints()) > 0 { + constraints = append(constraints, uniqueConstraintsToRepository(event.UniqueConstraints())...) } } - return events, uniqueConstraints, nil + + return events, constraints, nil +} + +func uniqueConstraintsToRepository(constraints []*EventUniqueConstraint) (uniqueConstraints []*repository.UniqueConstraint) { + uniqueConstraints = make([]*repository.UniqueConstraint, len(constraints)) + for i, constraint := range constraints { + uniqueConstraints[i] = &repository.UniqueConstraint{ + UniqueType: constraint.UniqueType, + UniqueField: constraint.UniqueField, + Action: uniqueConstraintActionToRepository(constraint.Action), + ErrorMessage: constraint.ErrorMessage, + } + } + return uniqueConstraints } //FilterEvents filters the stored events based on the searchQuery diff --git a/internal/eventstore/v2/eventstore_test.go b/internal/eventstore/v2/eventstore_test.go index 9a6c2fd271..c0d7aca8eb 100644 --- a/internal/eventstore/v2/eventstore_test.go +++ b/internal/eventstore/v2/eventstore_test.go @@ -31,7 +31,7 @@ func (a *testAggregate) Events() []EventPusher { } func (a *testAggregate) ResourceOwner() string { - return "ro" + return "caos" } func (a *testAggregate) Version() Version { @@ -47,13 +47,14 @@ type testEvent struct { data func() interface{} } -func newTestEvent(description string, data func() interface{}, checkPrevious bool) *testEvent { +func newTestEvent(id, description string, data func() interface{}, checkPrevious bool) *testEvent { return &testEvent{ description: description, data: data, shouldCheckPrevious: checkPrevious, BaseEvent: *NewBaseEventForPush( service.WithService(authz.NewMockContext("resourceOwner", "editorUser"), "editorService"), + NewAggregate(authz.NewMockContext("caos", "adlerhurst"), id, "test.aggregate", "v1"), "test.event", ), } @@ -69,7 +70,7 @@ func (e *testEvent) UniqueConstraints() []*EventUniqueConstraint { func testFilterMapper(event *repository.Event) (EventReader, error) { if event == nil { - return newTestEvent("hodor", nil, false), nil + return newTestEvent("testID", "hodor", nil, false), nil } return &testEvent{description: "hodor", BaseEvent: *BaseEventFromRepo(event)}, nil } @@ -129,7 +130,7 @@ func Test_eventstore_RegisterFilterEventMapper(t *testing.T) { mapper: testFilterMapper, }, res: res{ - event: newTestEvent("hodor", nil, false), + event: newTestEvent("testID", "hodor", nil, false), mapperCount: 1, }, }, @@ -145,7 +146,7 @@ func Test_eventstore_RegisterFilterEventMapper(t *testing.T) { mapper: testFilterMapper, }, res: res{ - event: newTestEvent("hodor", nil, false), + event: newTestEvent("testID", "hodor", nil, false), mapperCount: 2, }, }, @@ -165,7 +166,7 @@ func Test_eventstore_RegisterFilterEventMapper(t *testing.T) { mapper: testFilterMapper, }, res: res{ - event: newTestEvent("hodor", nil, false), + event: newTestEvent("testID", "hodor", nil, false), mapperCount: 2, }, }, @@ -215,6 +216,7 @@ func Test_eventData(t *testing.T) { name: "data as json bytes", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return []byte(`{"piff":"paff"}`) @@ -230,6 +232,7 @@ func Test_eventData(t *testing.T) { name: "data as invalid json bytes", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return []byte(`{"piffpaff"}`) @@ -245,6 +248,7 @@ func Test_eventData(t *testing.T) { name: "data as struct", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return struct { @@ -262,6 +266,7 @@ func Test_eventData(t *testing.T) { name: "data as ptr to struct", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return &struct { @@ -279,6 +284,7 @@ func Test_eventData(t *testing.T) { name: "no data", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return nil @@ -294,6 +300,7 @@ func Test_eventData(t *testing.T) { name: "invalid because primitive", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return "" @@ -309,6 +316,7 @@ func Test_eventData(t *testing.T) { name: "invalid because pointer to primitive", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { var s string @@ -325,6 +333,7 @@ func Test_eventData(t *testing.T) { name: "invalid because invalid struct for json", args: args{ event: newTestEvent( + "id", "hodor", func() interface{} { return struct { @@ -355,7 +364,8 @@ func Test_eventData(t *testing.T) { func TestEventstore_aggregatesToEvents(t *testing.T) { type args struct { - aggregates []Aggregater + aggregates []Aggregate + events []EventPusher } type res struct { wantErr bool @@ -369,18 +379,14 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "one aggregate one event", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), }, }, res: res{ @@ -392,7 +398,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -402,24 +408,21 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "one aggregate multiple events", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), + newTestEvent( + "1", + "", + func() interface{} { + return nil + }, + false), }, }, res: res{ @@ -431,7 +434,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -441,7 +444,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -451,18 +454,14 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "invalid data", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return `{"data":""` - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return `{"data":""` }, - }, + false), }, }, res: res{ @@ -472,35 +471,28 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { { name: "multiple aggregates", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, - &testAggregate{ - id: "2", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - true), + false), + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), + newTestEvent( + "2", + "", + func() interface{} { + return nil + }, + true), }, }, res: res{ @@ -513,7 +505,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -523,7 +515,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -535,7 +527,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -546,8 +538,7 @@ func TestEventstore_aggregatesToEvents(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - es := &Eventstore{} - events, _, err := es.aggregatesToEvents(tt.args.aggregates) + events, _, err := eventsToRepository(tt.args.events) if (err != nil) != tt.res.wantErr { t.Errorf("Eventstore.aggregatesToEvents() error = %v, wantErr %v", err, tt.res.wantErr) return @@ -613,7 +604,7 @@ func (repo *testRepo) LatestSequence(ctx context.Context, queryFactory *reposito func TestEventstore_Push(t *testing.T) { type args struct { - aggregates []Aggregater + events []EventPusher } type fields struct { repo *testRepo @@ -631,18 +622,14 @@ func TestEventstore_Push(t *testing.T) { { name: "one aggregate one event", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), }, }, fields: fields{ @@ -655,7 +642,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -671,24 +658,21 @@ func TestEventstore_Push(t *testing.T) { { name: "one aggregate multiple events", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), + newTestEvent( + "1", + "", + func() interface{} { + return nil + }, + false), }, }, fields: fields{ @@ -701,7 +685,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -711,7 +695,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -730,35 +714,28 @@ func TestEventstore_Push(t *testing.T) { { name: "multiple aggregates", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, - &testAggregate{ - id: "2", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - true), + false), + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), + newTestEvent( + "2", + "", + func() interface{} { + return nil + }, + true), }, }, fields: fields{ @@ -772,7 +749,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -782,7 +759,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -794,7 +771,7 @@ func TestEventstore_Push(t *testing.T) { Data: []byte(nil), EditorService: "editorService", EditorUser: "editorUser", - ResourceOwner: "ro", + ResourceOwner: "caos", Type: "test.event", Version: "v1", }, @@ -814,18 +791,14 @@ func TestEventstore_Push(t *testing.T) { { name: "push fails", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return nil - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return nil }, - }, + false), }, }, fields: fields{ @@ -841,18 +814,14 @@ func TestEventstore_Push(t *testing.T) { { name: "aggreagtes to events mapping fails", args: args{ - aggregates: []Aggregater{ - &testAggregate{ - id: "1", - events: []EventPusher{ - newTestEvent( - "", - func() interface{} { - return `{"data":""` - }, - false), + events: []EventPusher{ + newTestEvent( + "1", + "", + func() interface{} { + return `{"data":""` }, - }, + false), }, }, fields: fields{ @@ -881,7 +850,7 @@ func TestEventstore_Push(t *testing.T) { t.FailNow() } - _, err := es.PushAggregates(context.Background(), tt.args.aggregates...) + _, err := es.PushEvents(context.Background(), tt.args.events...) if (err != nil) != tt.res.wantErr { t.Errorf("Eventstore.aggregatesToEvents() error = %v, wantErr %v", err, tt.res.wantErr) } @@ -1313,13 +1282,13 @@ func compareEvents(t *testing.T, want, got *repository.Event) { t.Helper() if want.AggregateID != got.AggregateID { - t.Errorf("wrong aggregateID got %q want %q", want.AggregateID, got.AggregateID) + t.Errorf("wrong aggregateID got %q want %q", got.AggregateID, want.AggregateID) } if want.AggregateType != got.AggregateType { - t.Errorf("wrong aggregateType got %q want %q", want.AggregateType, got.AggregateType) + t.Errorf("wrong aggregateType got %q want %q", got.AggregateType, want.AggregateType) } if !reflect.DeepEqual(want.Data, got.Data) { - t.Errorf("wrong data got %s want %s", string(want.Data), string(got.Data)) + t.Errorf("wrong data got %s want %s", string(got.Data), string(want.Data)) } if want.EditorService != got.EditorService { t.Errorf("wrong editor service got %q want %q", got.EditorService, want.EditorService) diff --git a/internal/eventstore/v2/example_test.go b/internal/eventstore/v2/example_test.go index 767ee9ac94..a89c297b00 100644 --- a/internal/eventstore/v2/example_test.go +++ b/internal/eventstore/v2/example_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/eventstore/v2/repository/sql" @@ -15,34 +16,13 @@ import ( // ------------------------------------------------------------ // User aggregate start // ------------------------------------------------------------ - -type UserAggregate struct { - eventstore.Aggregate - - FirstName string -} - -func NewUserAggregate(id string) *UserAggregate { - return &UserAggregate{ - Aggregate: *eventstore.NewAggregate( - id, - "test.user", - "caos", - "v1", - ), - } -} - -func (rm *UserAggregate) Reduce() error { - for _, event := range rm.Aggregate.Events() { - switch e := event.(type) { - case *UserAddedEvent: - rm.FirstName = e.FirstName - case *UserFirstNameChangedEvent: - rm.FirstName = e.FirstName - } - } - return nil +func NewUserAggregate(id string) *eventstore.Aggregate { + return eventstore.NewAggregate( + authz.NewMockContext("caos", "adlerhurst"), + id, + "test.user", + "v1", + ) } // ------------------------------------------------------------ @@ -55,14 +35,13 @@ type UserAddedEvent struct { FirstName string `json:"firstName"` } -func NewUserAddedEvent(firstName string) *UserAddedEvent { +func NewUserAddedEvent(id string, firstName string) *UserAddedEvent { return &UserAddedEvent{ FirstName: firstName, - BaseEvent: eventstore.BaseEvent{ - Service: "test.suite", - User: "adlerhurst", - EventType: "user.added", - }, + BaseEvent: *eventstore.NewBaseEventForPush( + context.Background(), + NewUserAggregate(id), + "user.added"), } } @@ -97,14 +76,13 @@ type UserFirstNameChangedEvent struct { FirstName string `json:"firstName"` } -func NewUserFirstNameChangedEvent(firstName string) *UserFirstNameChangedEvent { +func NewUserFirstNameChangedEvent(id, firstName string) *UserFirstNameChangedEvent { return &UserFirstNameChangedEvent{ FirstName: firstName, - BaseEvent: eventstore.BaseEvent{ - Service: "test.suite", - User: "adlerhurst", - EventType: "user.firstName.changed", - }, + BaseEvent: *eventstore.NewBaseEventForPush( + context.Background(), + NewUserAggregate(id), + "user.firstname.changed"), } } @@ -137,13 +115,12 @@ type UserPasswordCheckedEvent struct { eventstore.BaseEvent `json:"-"` } -func NewUserPasswordCheckedEvent() *UserPasswordCheckedEvent { +func NewUserPasswordCheckedEvent(id string) *UserPasswordCheckedEvent { return &UserPasswordCheckedEvent{ - BaseEvent: eventstore.BaseEvent{ - Service: "test.suite", - User: "adlerhurst", - EventType: "user.password.checked", - }, + BaseEvent: *eventstore.NewBaseEventForPush( + context.Background(), + NewUserAggregate(id), + "user.password.checked"), } } @@ -171,13 +148,12 @@ type UserDeletedEvent struct { eventstore.BaseEvent `json:"-"` } -func NewUserDeletedEvent() *UserDeletedEvent { +func NewUserDeletedEvent(id string) *UserDeletedEvent { return &UserDeletedEvent{ - BaseEvent: eventstore.BaseEvent{ - Service: "test.suite", - User: "adlerhurst", - EventType: "user.deleted", - }, + BaseEvent: *eventstore.NewBaseEventForPush( + context.Background(), + NewUserAggregate(id), + "user.deleted"), } } @@ -213,18 +189,18 @@ func (rm *UsersReadModel) AppendEvents(events ...eventstore.EventReader) { switch e := event.(type) { case *UserAddedEvent: //insert - user := NewUserReadModel(e.AggregateID()) + user := NewUserReadModel(e.Aggregate().ID) rm.Users = append(rm.Users, user) user.AppendEvents(e) case *UserFirstNameChangedEvent, *UserPasswordCheckedEvent: //update - _, user := rm.userByID(e.AggregateID()) + _, user := rm.userByID(e.Aggregate().ID) if user == nil { return } user.AppendEvents(e) case *UserDeletedEvent: - idx, _ := rm.userByID(e.AggregateID()) + idx, _ := rm.userByID(e.Aggregate().ID) if idx < 0 { return } @@ -302,11 +278,14 @@ func TestUserReadModel(t *testing.T) { RegisterFilterEventMapper(UserPasswordCheckedMapper()). RegisterFilterEventMapper(UserDeletedMapper()) - events, err := es.PushAggregates(context.Background(), - NewUserAggregate("1").PushEvents(NewUserAddedEvent("hodor")), - NewUserAggregate("2").PushEvents(NewUserAddedEvent("hodor"), NewUserPasswordCheckedEvent(), NewUserPasswordCheckedEvent(), NewUserFirstNameChangedEvent("ueli")), - NewUserAggregate("2").PushEvents(NewUserDeletedEvent()), - ) + events, err := es.PushEvents(context.Background(), + NewUserAddedEvent("1", "hodor"), + NewUserAddedEvent("2", "hodor"), + NewUserPasswordCheckedEvent("2"), + NewUserPasswordCheckedEvent("2"), + NewUserFirstNameChangedEvent("2", "ueli"), + NewUserDeletedEvent("2")) + if err != nil { t.Errorf("unexpected error on push aggregates: %v", err) } diff --git a/internal/eventstore/v2/read_model.go b/internal/eventstore/v2/read_model.go index 976ab34170..041ae90be9 100644 --- a/internal/eventstore/v2/read_model.go +++ b/internal/eventstore/v2/read_model.go @@ -2,7 +2,7 @@ package eventstore import "time" -//MemberReadModel is the minimum representation of a View model. +//ReadModel is the minimum representation of a View model. // It implements a basic reducer // it might be saved in a database or in memory type ReadModel struct { @@ -29,10 +29,10 @@ func (rm *ReadModel) Reduce() error { } if rm.AggregateID == "" { - rm.AggregateID = rm.Events[0].AggregateID() + rm.AggregateID = rm.Events[0].Aggregate().ID } if rm.ResourceOwner == "" { - rm.ResourceOwner = rm.Events[0].ResourceOwner() + rm.ResourceOwner = rm.Events[0].Aggregate().ResourceOwner } if rm.CreationDate.IsZero() { diff --git a/internal/eventstore/v2/search_query.go b/internal/eventstore/v2/search_query.go index 0ff1166cbb..9acf0e3092 100644 --- a/internal/eventstore/v2/search_query.go +++ b/internal/eventstore/v2/search_query.go @@ -93,7 +93,7 @@ func (factory *SearchQueryBuilder) build() (*repository.SearchQuery, error) { if factory == nil || len(factory.aggregateTypes) < 1 || factory.columns.Validate() != nil { - return nil, errors.ThrowPreconditionFailed(nil, "MODEL-tGAD3", "factory invalid") + return nil, errors.ThrowPreconditionFailed(nil, "MODEL-4m9gs", "factory invalid") } filters := []*repository.Filter{ factory.aggregateTypeFilter(), diff --git a/internal/eventstore/v2/search_query_test.go b/internal/eventstore/v2/search_query_test.go index 8a2acbc805..9b5b90e252 100644 --- a/internal/eventstore/v2/search_query_test.go +++ b/internal/eventstore/v2/search_query_test.go @@ -488,7 +488,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) { } if !reflect.DeepEqual(query, tt.res.query) { - t.Errorf("NewSearchQueryFactory() = %+v, want %+v", factory, tt.res) + t.Errorf("NewSearchQueryFactory() = %+v, want %+v", factory, tt.res.query) } }) } diff --git a/internal/eventstore/v2/write_model.go b/internal/eventstore/v2/write_model.go index 420a8aff89..ad41d35478 100644 --- a/internal/eventstore/v2/write_model.go +++ b/internal/eventstore/v2/write_model.go @@ -15,9 +15,8 @@ type WriteModel struct { //AppendEvents adds all the events to the read model. // The function doesn't compute the new state of the read model -func (rm *WriteModel) AppendEvents(events ...EventReader) *WriteModel { +func (rm *WriteModel) AppendEvents(events ...EventReader) { rm.Events = append(rm.Events, events...) - return rm } //Reduce is the basic implementaion of reducer @@ -28,10 +27,10 @@ func (wm *WriteModel) Reduce() error { } if wm.AggregateID == "" { - wm.AggregateID = wm.Events[0].AggregateID() + wm.AggregateID = wm.Events[0].Aggregate().ID } if wm.ResourceOwner == "" { - wm.ResourceOwner = wm.Events[0].ResourceOwner() + wm.ResourceOwner = wm.Events[0].Aggregate().ResourceOwner } wm.ProcessedSequence = wm.Events[len(wm.Events)-1].Sequence() diff --git a/internal/v2/command/command.go b/internal/v2/command/command.go index e896c5e6d4..23ba46305c 100644 --- a/internal/v2/command/command.go +++ b/internal/v2/command/command.go @@ -131,3 +131,11 @@ func (r *CommandSide) getIAMWriteModel(ctx context.Context) (_ *IAMWriteModel, e return writeModel, nil } + +func AppendAndReduce(object interface { + AppendEvents(...eventstore.EventReader) + Reduce() error +}, events ...eventstore.EventReader) error { + object.AppendEvents(events...) + return object.Reduce() +} diff --git a/internal/v2/command/iam.go b/internal/v2/command/iam.go index 9bb3b921cc..723907e9cd 100644 --- a/internal/v2/command/iam.go +++ b/internal/v2/command/iam.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/v2/domain" @@ -18,26 +19,24 @@ func (r *CommandSide) GetIAM(ctx context.Context) (*domain.IAM, error) { return writeModelToIAM(iamWriteModel), nil } -func (r *CommandSide) setGlobalOrg(ctx context.Context, iamAgg *iam.Aggregate, iamWriteModel *IAMWriteModel, orgID string) error { +func (r *CommandSide) setGlobalOrg(ctx context.Context, iamAgg *eventstore.Aggregate, iamWriteModel *IAMWriteModel, orgID string) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel) if err != nil { - return err + return nil, err } if iamWriteModel.GlobalOrgID != "" { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-HGG24", "Errors.IAM.GlobalOrgAlreadySet") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-HGG24", "Errors.IAM.GlobalOrgAlreadySet") } - iamAgg.PushEvents(iam.NewGlobalOrgSetEventEvent(ctx, orgID)) - return nil + return iam.NewGlobalOrgSetEventEvent(ctx, iamAgg, orgID), nil } -func (r *CommandSide) setIAMProject(ctx context.Context, iamAgg *iam.Aggregate, iamWriteModel *IAMWriteModel, projectID string) error { +func (r *CommandSide) setIAMProject(ctx context.Context, iamAgg *eventstore.Aggregate, iamWriteModel *IAMWriteModel, projectID string) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel) if err != nil { - return err + return nil, err } if iamWriteModel.ProjectID != "" { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-EGbw2", "Errors.IAM.IAMProjectAlreadySet") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-EGbw2", "Errors.IAM.IAMProjectAlreadySet") } - iamAgg.PushEvents(iam.NewIAMProjectSetEvent(ctx, projectID)) - return nil + return iam.NewIAMProjectSetEvent(ctx, iamAgg, projectID), nil } diff --git a/internal/v2/command/iam_idp_config.go b/internal/v2/command/iam_idp_config.go index d172d0e8c6..4b37044ff0 100644 --- a/internal/v2/command/iam_idp_config.go +++ b/internal/v2/command/iam_idp_config.go @@ -2,9 +2,8 @@ package command import ( "context" - "github.com/caos/zitadel/internal/eventstore/v2" - caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" @@ -30,18 +29,19 @@ func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *domain.ID } iamAgg := IAMAggregateFromWriteModel(&addedConfig.WriteModel) - iamAgg.PushEvents( + events := []eventstore.EventPusher{ iam_repo.NewIDPConfigAddedEvent( ctx, + iamAgg, idpConfigID, config.Name, config.Type, config.StylingType, ), - ) - iamAgg.PushEvents( iam_repo.NewIDPOIDCConfigAddedEvent( - ctx, config.OIDCConfig.ClientID, + ctx, + iamAgg, + config.OIDCConfig.ClientID, idpConfigID, config.OIDCConfig.Issuer, clientSecret, @@ -49,8 +49,13 @@ func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *domain.ID config.OIDCConfig.UsernameMapping, config.OIDCConfig.Scopes..., ), - ) - err = r.eventstore.PushAggregate(ctx, addedConfig, iamAgg) + } + + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedConfig, pushedEvents...) if err != nil { return nil, err } @@ -66,14 +71,16 @@ func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotExisting") } - changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, existingIDP.ResourceOwner, config.IDPConfigID, config.Name, config.StylingType) + iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) + changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, iamAgg, config.IDPConfigID, config.Name, config.StylingType) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingIDP, pushedEvents...) if err != nil { return nil, err } @@ -89,9 +96,8 @@ func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, idpID stri return caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive") } iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) - iamAgg.PushEvents(iam_repo.NewIDPConfigDeactivatedEvent(ctx, idpID)) - - return r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + _, err = r.eventstore.PushEvents(ctx, iam_repo.NewIDPConfigDeactivatedEvent(ctx, iamAgg, idpID)) + return err } func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) error { @@ -103,9 +109,8 @@ func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID stri return caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mo0d", "Errors.IAM.IDPConfig.NotInactive") } iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) - iamAgg.PushEvents(iam_repo.NewIDPConfigReactivatedEvent(ctx, idpID)) - - return r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + _, err = r.eventstore.PushEvents(ctx, iam_repo.NewIDPConfigReactivatedEvent(ctx, iamAgg, idpID)) + return err } func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idpProviders []*domain.IDPProvider, externalIDPs ...*domain.ExternalIDP) error { @@ -117,22 +122,22 @@ func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, idpID string, return caos_errs.ThrowNotFound(nil, "IAM-4M0xy", "Errors.IAM.IDPConfig.NotExisting") } - aggregates := make([]eventstore.Aggregater, 0) iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) - iamAgg.PushEvents(iam_repo.NewIDPConfigRemovedEvent(ctx, existingIDP.ResourceOwner, idpID, existingIDP.Name)) - - userAggregates := make([]eventstore.Aggregater, 0) - for _, idpProvider := range idpProviders { - if idpProvider.AggregateID == domain.IAMID { - userAggregates = r.removeIDPProviderFromDefaultLoginPolicy(ctx, iamAgg, idpProvider, true, externalIDPs...) - } - orgAgg := OrgAggregateFromWriteModel(&NewOrgIdentityProviderWriteModel(idpProvider.AggregateID, idpID).WriteModel) - r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpID, true) + events := []eventstore.EventPusher{ + iam_repo.NewIDPConfigRemovedEvent(ctx, iamAgg, idpID, existingIDP.Name), } - aggregates = append(aggregates, iamAgg) - aggregates = append(aggregates, userAggregates...) - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + for _, idpProvider := range idpProviders { + if idpProvider.AggregateID == domain.IAMID { + userEvents := r.removeIDPProviderFromDefaultLoginPolicy(ctx, iamAgg, idpProvider, true, externalIDPs...) + events = append(events, userEvents...) + } + orgAgg := OrgAggregateFromWriteModel(&NewOrgIdentityProviderWriteModel(idpProvider.AggregateID, idpID).WriteModel) + orgEvents := r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpID, true) + events = append(events, orgEvents...) + } + + _, err = r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/iam_idp_config_model.go b/internal/v2/command/iam_idp_config_model.go index c1f3c19ba7..02c00f1dae 100644 --- a/internal/v2/command/iam_idp_config_model.go +++ b/internal/v2/command/iam_idp_config_model.go @@ -28,7 +28,16 @@ func NewIAMIDPConfigWriteModel(configID string) *IAMIDPConfigWriteModel { func (wm *IAMIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.IDPConfigAddedEventType, + iam.IDPConfigChangedEventType, + iam.IDPConfigDeactivatedEventType, + iam.IDPConfigReactivatedEventType, + iam.IDPConfigRemovedEventType, + iam.IDPOIDCConfigAddedEventType, + iam.IDPOIDCConfigChangedEventType, + ) } func (wm *IAMIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { @@ -84,7 +93,7 @@ func (wm *IAMIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventRead func (wm *IAMIDPConfigWriteModel) NewChangedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, name string, stylingType domain.IDPConfigStylingType, @@ -102,7 +111,7 @@ func (wm *IAMIDPConfigWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changeEvent, err := iam.NewIDPConfigChangedEvent(ctx, resourceOwner, configID, oldName, changes) + changeEvent, err := iam.NewIDPConfigChangedEvent(ctx, aggregate, configID, oldName, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_idp_oidc_config.go b/internal/v2/command/iam_idp_oidc_config.go index 364d0bed37..ea86da402e 100644 --- a/internal/v2/command/iam_idp_oidc_config.go +++ b/internal/v2/command/iam_idp_oidc_config.go @@ -17,8 +17,10 @@ func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *do return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-67J9d", "Errors.IAM.IDPConfig.AlreadyExists") } + iamAgg := IAMAggregateFromWriteModel(&existingConfig.WriteModel) changedEvent, hasChanged, err := existingConfig.NewChangedEvent( ctx, + iamAgg, config.IDPConfigID, config.ClientID, config.Issuer, @@ -34,13 +36,13 @@ func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *do return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingConfig.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingConfig, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingConfig, pushedEvents...) if err != nil { return nil, err } - return writeModelToIDPOIDCConfig(&existingConfig.OIDCConfigWriteModel), nil } diff --git a/internal/v2/command/iam_idp_oidc_config_model.go b/internal/v2/command/iam_idp_oidc_config_model.go index dddd19328d..77ade5d377 100644 --- a/internal/v2/command/iam_idp_oidc_config_model.go +++ b/internal/v2/command/iam_idp_oidc_config_model.go @@ -71,11 +71,18 @@ func (wm *IAMIDPOIDCConfigWriteModel) Reduce() error { func (wm *IAMIDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.IDPOIDCConfigAddedEventType, + iam.IDPOIDCConfigChangedEventType, + iam.IDPConfigReactivatedEventType, + iam.IDPConfigDeactivatedEventType, + iam.IDPConfigRemovedEventType) } func (wm *IAMIDPOIDCConfigWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID, clientID, issuer, @@ -114,7 +121,7 @@ func (wm *IAMIDPOIDCConfigWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false, nil } - changeEvent, err := iam.NewIDPOIDCConfigChangedEvent(ctx, idpConfigID, changes) + changeEvent, err := iam.NewIDPOIDCConfigChangedEvent(ctx, aggregate, idpConfigID, changes) if err != nil { return nil, false, err } diff --git a/internal/v2/command/iam_member.go b/internal/v2/command/iam_member.go index fd3f330700..968301d2cb 100644 --- a/internal/v2/command/iam_member.go +++ b/internal/v2/command/iam_member.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "reflect" "github.com/caos/zitadel/internal/errors" @@ -14,37 +15,38 @@ import ( func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) { addedMember := NewIAMMemberWriteModel(member.UserID) iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel) - err := r.addIAMMember(ctx, iamAgg, addedMember, member) + event, err := r.addIAMMember(ctx, iamAgg, addedMember, member) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedMember, pushedEvents...) if err != nil { return nil, err } - return memberWriteModelToMember(&addedMember.MemberWriteModel), nil } -func (r *CommandSide) addIAMMember(ctx context.Context, iamAgg *iam_repo.Aggregate, addedMember *IAMMemberWriteModel, member *domain.Member) error { +func (r *CommandSide) addIAMMember(ctx context.Context, iamAgg *eventstore.Aggregate, addedMember *IAMMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) { //TODO: check if roles valid if !member.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-GR34U", "Errors.IAM.MemberInvalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-GR34U", "Errors.IAM.MemberInvalid") } err := r.eventstore.FilterToQueryReducer(ctx, addedMember) if err != nil { - return err + return nil, err } if addedMember.State == domain.MemberStateActive { - return errors.ThrowAlreadyExists(nil, "IAM-sdgQ4", "Errors.IAM.Member.AlreadyExists") + return nil, errors.ThrowAlreadyExists(nil, "IAM-sdgQ4", "Errors.IAM.Member.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, iamAgg.ID(), member.UserID, member.Roles...)) - - return nil + return iam_repo.NewMemberAddedEvent(ctx, iamAgg, member.UserID, member.Roles...), nil } //ChangeIAMMember updates an existing member @@ -64,15 +66,12 @@ func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.Member return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.Member.RolesNotChanged") } iamAgg := IAMAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewMemberChangedEvent(ctx, member.UserID, member.Roles...)) - - events, err := r.eventstore.PushAggregates(ctx, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, iam_repo.NewMemberChangedEvent(ctx, iamAgg, member.UserID, member.Roles...)) if err != nil { return nil, err } - - existingMember.AppendEvents(events...) - if err = existingMember.Reduce(); err != nil { + err = AppendAndReduce(existingMember, pushedEvents...) + if err != nil { return nil, err } @@ -89,9 +88,8 @@ func (r *CommandSide) RemoveIAMMember(ctx context.Context, userID string) error } iamAgg := IAMAggregateFromWriteModel(&m.MemberWriteModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, iamAgg.ID(), userID)) - - return r.eventstore.PushAggregate(ctx, m, iamAgg) + _, err = r.eventstore.PushEvents(ctx, iam_repo.NewMemberRemovedEvent(ctx, iamAgg, userID)) + return err } func (r *CommandSide) iamMemberWriteModelByID(ctx context.Context, userID string) (member *IAMMemberWriteModel, err error) { diff --git a/internal/v2/command/iam_member_model.go b/internal/v2/command/iam_member_model.go index 4b6998300f..ffc7918efd 100644 --- a/internal/v2/command/iam_member_model.go +++ b/internal/v2/command/iam_member_model.go @@ -50,5 +50,10 @@ func (wm *IAMMemberWriteModel) Reduce() error { func (wm *IAMMemberWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). - AggregateIDs(wm.MemberWriteModel.AggregateID).ResourceOwner(wm.ResourceOwner) + AggregateIDs(wm.MemberWriteModel.AggregateID). + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.MemberAddedEventType, + iam.MemberChangedEventType, + iam.MemberRemovedEventType) } diff --git a/internal/v2/command/iam_model.go b/internal/v2/command/iam_model.go index 8993581220..8450a98e8e 100644 --- a/internal/v2/command/iam_model.go +++ b/internal/v2/command/iam_model.go @@ -25,10 +25,6 @@ func NewIAMWriteModel() *IAMWriteModel { } } -func (wm *IAMWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *IAMWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -50,11 +46,14 @@ func (wm *IAMWriteModel) Reduce() error { func (wm *IAMWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.ProjectSetEventType, + iam.GlobalOrgSetEventType, + iam.SetupStartedEventType, + iam.SetupDoneEventType) } -func IAMAggregateFromWriteModel(wm *eventstore.WriteModel) *iam.Aggregate { - return &iam.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, iam.AggregateType, iam.AggregateVersion), - } +func IAMAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, iam.AggregateType, iam.AggregateVersion) } diff --git a/internal/v2/command/iam_policy_label.go b/internal/v2/command/iam_policy_label.go index 141528ccdd..03f8390961 100644 --- a/internal/v2/command/iam_policy_label.go +++ b/internal/v2/command/iam_policy_label.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,31 +12,33 @@ import ( func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { addedPolicy := NewIAMLabelPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel) - err := r.addDefaultLabelPolicy(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultLabelPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLabelPolicy(&addedPolicy.LabelPolicyWriteModel), nil } -func (r *CommandSide) addDefaultLabelPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMLabelPolicyWriteModel, policy *domain.LabelPolicy) error { +func (r *CommandSide) addDefaultLabelPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMLabelPolicyWriteModel, policy *domain.LabelPolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)) + return iam_repo.NewLabelPolicyAddedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor), nil - return nil } func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { @@ -47,20 +50,20 @@ func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *doma if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { return nil, caos_errs.ThrowNotFound(nil, "IAM-0K9dq", "Errors.IAM.LabelPolicy.NotFound") } - - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.PrimaryColor, policy.SecondaryColor) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLabelPolicy(&existingPolicy.LabelPolicyWriteModel), nil } diff --git a/internal/v2/command/iam_policy_label_model.go b/internal/v2/command/iam_policy_label_model.go index 61325c3f01..1aa3e9b9e3 100644 --- a/internal/v2/command/iam_policy_label_model.go +++ b/internal/v2/command/iam_policy_label_model.go @@ -42,11 +42,15 @@ func (wm *IAMLabelPolicyWriteModel) Reduce() error { func (wm *IAMLabelPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.LabelPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.LabelPolicyAddedEventType, + iam.LabelPolicyChangedEventType) } func (wm *IAMLabelPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, primaryColor, secondaryColor string, ) (*iam.LabelPolicyChangedEvent, bool) { @@ -60,7 +64,7 @@ func (wm *IAMLabelPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewLabelPolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewLabelPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_login.go b/internal/v2/command/iam_policy_login.go index a43b6d93c0..6c66fa28a3 100644 --- a/internal/v2/command/iam_policy_login.go +++ b/internal/v2/command/iam_policy_login.go @@ -25,11 +25,11 @@ func (r *CommandSide) getDefaultLoginPolicy(ctx context.Context) (*domain.LoginP func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { addedPolicy := NewIAMLoginPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) - err := r.addDefaultLoginPolicy(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultLoginPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + _, err = r.eventstore.PushEvents(ctx, event) if err != nil { return nil, err } @@ -37,50 +37,49 @@ func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *domain. return writeModelToLoginPolicy(&addedPolicy.LoginPolicyWriteModel), nil } -func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) error { +func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType)) - - return nil + return iam_repo.NewLoginPolicyAddedEvent(ctx, iamAgg, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType), nil } func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { existingPolicy := NewIAMLoginPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) - err := r.changeDefaultLoginPolicy(ctx, iamAgg, existingPolicy, policy) + event, err := r.changeDefaultLoginPolicy(ctx, iamAgg, existingPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLoginPolicy(&existingPolicy.LoginPolicyWriteModel), nil } -func (r *CommandSide) changeDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, existingPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) error { +func (r *CommandSide) changeDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, existingPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) (eventstore.EventPusher, error) { err := r.defaultLoginPolicyWriteModelByID(ctx, existingPolicy) if err != nil { - return err + return nil, err } if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { - return caos_errs.ThrowNotFound(nil, "IAM-M0sif", "Errors.IAM.LoginPolicy.NotFound") + return nil, caos_errs.ThrowNotFound(nil, "IAM-M0sif", "Errors.IAM.LoginPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType) if !hasChanged { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged") } - iamAgg.PushEvents(changedEvent) - - return nil + return changedEvent, nil } func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) { @@ -94,12 +93,14 @@ func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, id } iamAgg := IAMAggregateFromWriteModel(&idpModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewIdentityProviderAddedEvent(ctx, idpProvider.IDPConfigID, domain.IdentityProviderType(idpProvider.Type))) - - if err = r.eventstore.PushAggregate(ctx, idpModel, iamAgg); err != nil { + pushedEvents, err := r.eventstore.PushEvents(ctx, iam_repo.NewIdentityProviderAddedEvent(ctx, iamAgg, idpProvider.IDPConfigID, idpProvider.Type)) + if err != nil { + return nil, err + } + err = AppendAndReduce(idpModel, pushedEvents...) + if err != nil { return nil, err } - return writeModelToIDPProvider(&idpModel.IdentityProviderWriteModel), nil } @@ -113,64 +114,61 @@ func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Contex return caos_errs.ThrowNotFound(nil, "IAM-39fjs", "Errors.IAM.LoginPolicy.IDP.NotExisting") } - aggregates := make([]eventstore.Aggregater, 0) iamAgg := IAMAggregateFromWriteModel(&idpModel.IdentityProviderWriteModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewIdentityProviderRemovedEvent(ctx, idpProvider.IDPConfigID)) + events := []eventstore.EventPusher{ + iam_repo.NewIdentityProviderRemovedEvent(ctx, iamAgg, idpProvider.IDPConfigID), + } - userAggregates := r.removeIDPProviderFromDefaultLoginPolicy(ctx, iamAgg, idpProvider, false, cascadeExternalIDPs...) - aggregates = append(aggregates, iamAgg) - aggregates = append(aggregates, userAggregates...) - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + userEvents := r.removeIDPProviderFromDefaultLoginPolicy(ctx, iamAgg, idpProvider, false, cascadeExternalIDPs...) + events = append(events, userEvents...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } -func (r *CommandSide) removeIDPProviderFromDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, idpProvider *domain.IDPProvider, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.Aggregater { +func (r *CommandSide) removeIDPProviderFromDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, idpProvider *domain.IDPProvider, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.EventPusher { + var events []eventstore.EventPusher if cascade { - iamAgg.PushEvents(iam_repo.NewIdentityProviderCascadeRemovedEvent(ctx, idpProvider.IDPConfigID)) - return nil + events = append(events, iam_repo.NewIdentityProviderCascadeRemovedEvent(ctx, iamAgg, idpProvider.IDPConfigID)) + } else { + events = append(events, iam_repo.NewIdentityProviderRemovedEvent(ctx, iamAgg, idpProvider.IDPConfigID)) } - iamAgg.PushEvents(iam_repo.NewIdentityProviderRemovedEvent(ctx, idpProvider.IDPConfigID)) - userAggregates := make([]eventstore.Aggregater, 0) for _, idp := range cascadeExternalIDPs { - userAgg, _, err := r.removeHumanExternalIDP(ctx, idp, true) + userEvent, err := r.removeHumanExternalIDP(ctx, idp, true) if err != nil { logging.LogWithFields("COMMAND-4nfsf", "userid", idp.AggregateID, "idp-id", idp.IDPConfigID).WithError(err).Warn("could not cascade remove externalidp in remove provider from policy") continue } - userAggregates = append(userAggregates, userAgg) + events = append(events, userEvent) } - return userAggregates + return events } func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, secondFactor domain.SecondFactorType) (domain.SecondFactorType, error) { secondFactorModel := NewIAMSecondFactorWriteModel() iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) - err := r.addSecondFactorToDefaultLoginPolicy(ctx, nil, secondFactorModel, secondFactor) + event, err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, secondFactor) if err != nil { return domain.SecondFactorTypeUnspecified, err } - if err = r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg); err != nil { + if _, err = r.eventstore.PushEvents(ctx, event); err != nil { return domain.SecondFactorTypeUnspecified, err } return secondFactorModel.MFAType, nil } -func (r *CommandSide) addSecondFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, secondFactorModel *IAMSecondFactorWriteModel, secondFactor domain.SecondFactorType) error { +func (r *CommandSide) addSecondFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, secondFactorModel *IAMSecondFactorWriteModel, secondFactor domain.SecondFactorType) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) if err != nil { - return err + return nil, err } if secondFactorModel.State == domain.FactorStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") } - - iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorAddedEvent(ctx, domain.SecondFactorType(secondFactor))) - - return nil + return iam_repo.NewLoginPolicySecondFactorAddedEvent(ctx, iamAgg, secondFactor), nil } func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, secondFactor domain.SecondFactorType) error { @@ -183,38 +181,35 @@ func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Conte return caos_errs.ThrowNotFound(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.NotExisting") } iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorRemovedEvent(ctx, domain.SecondFactorType(secondFactor))) - - return r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg) + _, err = r.eventstore.PushEvents(ctx, iam_repo.NewLoginPolicySecondFactorRemovedEvent(ctx, iamAgg, secondFactor)) + return err } func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, multiFactor domain.MultiFactorType) (domain.MultiFactorType, error) { multiFactorModel := NewIAMMultiFactorWriteModel() iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) - err := r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, multiFactor) + event, err := r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, multiFactor) if err != nil { return domain.MultiFactorTypeUnspecified, err } - if err = r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg); err != nil { + if _, err = r.eventstore.PushEvents(ctx, event); err != nil { return domain.MultiFactorTypeUnspecified, err } - return domain.MultiFactorType(multiFactorModel.MultiFactoryWriteModel.MFAType), nil + return multiFactorModel.MultiFactoryWriteModel.MFAType, nil } -func (r *CommandSide) addMultiFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, multiFactorModel *IAMMultiFactorWriteModel, multiFactor domain.MultiFactorType) error { +func (r *CommandSide) addMultiFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, multiFactorModel *IAMMultiFactorWriteModel, multiFactor domain.MultiFactorType) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) if err != nil { - return err + return nil, err } if multiFactorModel.State == domain.FactorStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorAddedEvent(ctx, domain.MultiFactorType(multiFactor))) - - return nil + return iam_repo.NewLoginPolicyMultiFactorAddedEvent(ctx, iamAgg, multiFactor), nil } func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, multiFactor domain.MultiFactorType) error { @@ -227,9 +222,8 @@ func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Contex return caos_errs.ThrowNotFound(nil, "IAM-3M9df", "Errors.IAM.LoginPolicy.MFA.NotExisting") } iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) - iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorRemovedEvent(ctx, domain.MultiFactorType(multiFactor))) - - return r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg) + _, err = r.eventstore.PushEvents(ctx, iam_repo.NewLoginPolicyMultiFactorRemovedEvent(ctx, iamAgg, multiFactor)) + return err } func (r *CommandSide) defaultLoginPolicyWriteModelByID(ctx context.Context, writeModel *IAMLoginPolicyWriteModel) (err error) { diff --git a/internal/v2/command/iam_policy_login_factors_model.go b/internal/v2/command/iam_policy_login_factors_model.go index e7d264645b..7bf9104633 100644 --- a/internal/v2/command/iam_policy_login_factors_model.go +++ b/internal/v2/command/iam_policy_login_factors_model.go @@ -39,7 +39,10 @@ func (wm *IAMSecondFactorWriteModel) Reduce() error { func (wm *IAMSecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.WriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.LoginPolicySecondFactorAddedEventType, + iam.LoginPolicySecondFactorRemovedEventType) } type IAMMultiFactorWriteModel struct { @@ -75,5 +78,8 @@ func (wm *IAMMultiFactorWriteModel) Reduce() error { func (wm *IAMMultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.WriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.LoginPolicyMultiFactorAddedEventType, + iam.LoginPolicyMultiFactorRemovedEventType) } diff --git a/internal/v2/command/iam_policy_login_model.go b/internal/v2/command/iam_policy_login_model.go index 31227ee69c..ef2b21b93a 100644 --- a/internal/v2/command/iam_policy_login_model.go +++ b/internal/v2/command/iam_policy_login_model.go @@ -46,11 +46,15 @@ func (wm *IAMLoginPolicyWriteModel) Reduce() error { func (wm *IAMLoginPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.LoginPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.LoginPolicyAddedEventType, + iam.LoginPolicyChangedEventType) } func (wm *IAMLoginPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, allowUsernamePassword, allowRegister, allowExternalIDP, @@ -77,7 +81,7 @@ func (wm *IAMLoginPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewLoginPolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewLoginPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_mail_template.go b/internal/v2/command/iam_policy_mail_template.go index f08ddefa81..48c2b341ae 100644 --- a/internal/v2/command/iam_policy_mail_template.go +++ b/internal/v2/command/iam_policy_mail_template.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,34 +12,35 @@ import ( func (r *CommandSide) AddDefaultMailTemplate(ctx context.Context, policy *domain.MailTemplate) (*domain.MailTemplate, error) { addedPolicy := NewIAMMailTemplateWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.MailTemplateWriteModel.WriteModel) - err := r.addDefaultMailTemplate(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultMailTemplate(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTemplatePolicy(&addedPolicy.MailTemplateWriteModel), nil } -func (r *CommandSide) addDefaultMailTemplate(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMMailTemplateWriteModel, policy *domain.MailTemplate) error { +func (r *CommandSide) addDefaultMailTemplate(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMMailTemplateWriteModel, policy *domain.MailTemplate) (eventstore.EventPusher, error) { if !policy.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-fm9sd", "Errors.IAM.MailTemplate.Invalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-fm9sd", "Errors.IAM.MailTemplate.Invalid") } err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-5n8fs", "Errors.IAM.MailTemplate.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-5n8fs", "Errors.IAM.MailTemplate.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewMailTemplateAddedEvent(ctx, policy.Template)) - - return nil + return iam_repo.NewMailTemplateAddedEvent(ctx, iamAgg, policy.Template), nil } func (r *CommandSide) ChangeDefaultMailTemplate(ctx context.Context, policy *domain.MailTemplate) (*domain.MailTemplate, error) { @@ -54,19 +56,20 @@ func (r *CommandSide) ChangeDefaultMailTemplate(ctx context.Context, policy *dom return nil, caos_errs.ThrowNotFound(nil, "IAM-2N8fs", "Errors.IAM.MailTemplate.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.Template) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.Template) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-3nfsG", "Errors.IAM.MailTemplate.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTemplatePolicy(&existingPolicy.MailTemplateWriteModel), nil } diff --git a/internal/v2/command/iam_policy_mail_template_model.go b/internal/v2/command/iam_policy_mail_template_model.go index 07d8f4ad0f..2970b1170c 100644 --- a/internal/v2/command/iam_policy_mail_template_model.go +++ b/internal/v2/command/iam_policy_mail_template_model.go @@ -43,11 +43,15 @@ func (wm *IAMMailTemplateWriteModel) Reduce() error { func (wm *IAMMailTemplateWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.MailTemplateWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.MailTemplateAddedEventType, + iam.MailTemplateChangedEventType) } func (wm *IAMMailTemplateWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, template []byte, ) (*iam.MailTemplateChangedEvent, bool) { changes := make([]policy.MailTemplateChanges, 0) @@ -57,7 +61,7 @@ func (wm *IAMMailTemplateWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewMailTemplateChangedEvent(ctx, changes) + changedEvent, err := iam.NewMailTemplateChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_mail_text.go b/internal/v2/command/iam_policy_mail_text.go index 25ec6b67b1..dbf8dd75d4 100644 --- a/internal/v2/command/iam_policy_mail_text.go +++ b/internal/v2/command/iam_policy_mail_text.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,45 +12,45 @@ import ( func (r *CommandSide) AddDefaultMailText(ctx context.Context, policy *domain.MailText) (*domain.MailText, error) { addedPolicy := NewIAMMailTextWriteModel(policy.MailTextType, policy.Language) iamAgg := IAMAggregateFromWriteModel(&addedPolicy.MailTextWriteModel.WriteModel) - err := r.addDefaultMailText(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultMailText(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTextPolicy(&addedPolicy.MailTextWriteModel), nil } -func (r *CommandSide) addDefaultMailText(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMMailTextWriteModel, mailText *domain.MailText) error { +func (r *CommandSide) addDefaultMailText(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMMailTextWriteModel, mailText *domain.MailText) (eventstore.EventPusher, error) { if !mailText.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "IAM-3n8fs", "Errors.IAM.MailText.Invalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-3n8fs", "Errors.IAM.MailText.Invalid") } err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-9o0pM", "Errors.IAM.MailText.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-9o0pM", "Errors.IAM.MailText.AlreadyExists") } - iamAgg.PushEvents( - iam_repo.NewMailTextAddedEvent( - ctx, - mailText.MailTextType, - mailText.Language, - mailText.Title, - mailText.PreHeader, - mailText.Subject, - mailText.Greeting, - mailText.Text, - mailText.ButtonText), - ) - - return nil + return iam_repo.NewMailTextAddedEvent( + ctx, + iamAgg, + mailText.MailTextType, + mailText.Language, + mailText.Title, + mailText.PreHeader, + mailText.Subject, + mailText.Greeting, + mailText.Text, + mailText.ButtonText), nil } func (r *CommandSide) ChangeDefaultMailText(ctx context.Context, mailText *domain.MailText) (*domain.MailText, error) { @@ -65,8 +66,10 @@ func (r *CommandSide) ChangeDefaultMailText(ctx context.Context, mailText *domai return nil, caos_errs.ThrowNotFound(nil, "IAM-2N8fs", "Errors.IAM.MailText.NotFound") } + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) changedEvent, hasChanged := existingPolicy.NewChangedEvent( ctx, + iamAgg, mailText.MailTextType, mailText.Language, mailText.Title, @@ -79,14 +82,14 @@ func (r *CommandSide) ChangeDefaultMailText(ctx context.Context, mailText *domai return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-m9L0s", "Errors.IAM.MailText.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTextPolicy(&existingPolicy.MailTextWriteModel), nil } diff --git a/internal/v2/command/iam_policy_mail_text_model.go b/internal/v2/command/iam_policy_mail_text_model.go index a87d89f5f9..0c1b8f598b 100644 --- a/internal/v2/command/iam_policy_mail_text_model.go +++ b/internal/v2/command/iam_policy_mail_text_model.go @@ -43,11 +43,15 @@ func (wm *IAMMailTextWriteModel) Reduce() error { func (wm *IAMMailTextWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.MailTextWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.MailTextAddedEventType, + iam.MailTextChangedEventType) } func (wm *IAMMailTextWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mailTextType, language, title, @@ -79,7 +83,7 @@ func (wm *IAMMailTextWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewMailTextChangedEvent(ctx, mailTextType, language, changes) + changedEvent, err := iam.NewMailTextChangedEvent(ctx, aggregate, mailTextType, language, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_org_iam.go b/internal/v2/command/iam_policy_org_iam.go index 8037d45e1e..b197b51253 100644 --- a/internal/v2/command/iam_policy_org_iam.go +++ b/internal/v2/command/iam_policy_org_iam.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,30 +12,31 @@ import ( func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { addedPolicy := NewIAMOrgIAMPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) - err := r.addDefaultOrgIAMPolicy(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToOrgIAMPolicy(addedPolicy), nil } -func (r *CommandSide) addDefaultOrgIAMPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) error { +func (r *CommandSide) addDefaultOrgIAMPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) - - return nil + return iam_repo.NewOrgIAMPolicyAddedEvent(ctx, iamAgg, policy.UserLoginMustBeDomain), nil } func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { @@ -46,19 +48,20 @@ func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *dom return nil, caos_errs.ThrowNotFound(nil, "IAM-0Pl0d", "Errors.IAM.OrgIAMPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.UserLoginMustBeDomain) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToOrgIAMPolicy(existingPolicy), nil } diff --git a/internal/v2/command/iam_policy_org_iam_model.go b/internal/v2/command/iam_policy_org_iam_model.go index 304ce12bc6..84e9f13642 100644 --- a/internal/v2/command/iam_policy_org_iam_model.go +++ b/internal/v2/command/iam_policy_org_iam_model.go @@ -42,10 +42,16 @@ func (wm *IAMOrgIAMPolicyWriteModel) Reduce() error { func (wm *IAMOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.OrgIAMPolicyAddedEventType, + iam.OrgIAMPolicyChangedEventType) } -func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*iam.OrgIAMPolicyChangedEvent, bool) { +func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userLoginMustBeDomain bool) (*iam.OrgIAMPolicyChangedEvent, bool) { changes := make([]policy.OrgIAMPolicyChanges, 0) if wm.UserLoginMustBeDomain != userLoginMustBeDomain { changes = append(changes, policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain)) @@ -53,7 +59,7 @@ func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLo if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewOrgIAMPolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewOrgIAMPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_password_age.go b/internal/v2/command/iam_policy_password_age.go index d1d0851179..6d8f84e0eb 100644 --- a/internal/v2/command/iam_policy_password_age.go +++ b/internal/v2/command/iam_policy_password_age.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,31 +12,33 @@ import ( func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { addedPolicy := NewIAMPasswordAgePolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) - err := r.addDefaultPasswordAgePolicy(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordAgePolicy(&addedPolicy.PasswordAgePolicyWriteModel), nil } -func (r *CommandSide) addDefaultPasswordAgePolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordAgePolicyWriteModel, policy *domain.PasswordAgePolicy) error { +func (r *CommandSide) addDefaultPasswordAgePolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMPasswordAgePolicyWriteModel, policy *domain.PasswordAgePolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordAgePolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordAgePolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)) + return iam_repo.NewPasswordAgePolicyAddedEvent(ctx, iamAgg, policy.ExpireWarnDays, policy.MaxAgeDays), nil - return nil } func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { @@ -47,15 +50,17 @@ func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.ExpireWarnDays, policy.MaxAgeDays) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } diff --git a/internal/v2/command/iam_policy_password_age_model.go b/internal/v2/command/iam_policy_password_age_model.go index 704e341e3e..588f328c58 100644 --- a/internal/v2/command/iam_policy_password_age_model.go +++ b/internal/v2/command/iam_policy_password_age_model.go @@ -42,10 +42,17 @@ func (wm *IAMPasswordAgePolicyWriteModel) Reduce() error { func (wm *IAMPasswordAgePolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.PasswordAgePolicyAddedEventType, + iam.PasswordAgePolicyChangedEventType) } -func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) (*iam.PasswordAgePolicyChangedEvent, bool) { +func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + expireWarnDays, + maxAgeDays uint64) (*iam.PasswordAgePolicyChangedEvent, bool) { changes := make([]policy.PasswordAgePolicyChanges, 0) if wm.ExpireWarnDays != expireWarnDays { changes = append(changes, policy.ChangeExpireWarnDays(expireWarnDays)) @@ -56,7 +63,7 @@ func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, e if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewPasswordAgePolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewPasswordAgePolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_password_complexity.go b/internal/v2/command/iam_policy_password_complexity.go index 27d60ace6d..c191d70877 100644 --- a/internal/v2/command/iam_policy_password_complexity.go +++ b/internal/v2/command/iam_policy_password_complexity.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -22,35 +23,36 @@ func (r *CommandSide) getDefaultPasswordComplexityPolicy(ctx context.Context) (* func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { addedPolicy := NewIAMPasswordComplexityPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) - err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, addedPolicy, policy) + events, err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordComplexityPolicy(&addedPolicy.PasswordComplexityPolicyWriteModel), nil } -func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *domain.PasswordComplexityPolicy) error { +func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *domain.PasswordComplexityPolicy) (eventstore.EventPusher, error) { if err := policy.IsValid(); err != nil { - return err + return nil, err } err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)) - - return nil + return iam_repo.NewPasswordComplexityPolicyAddedEvent(ctx, iamAgg, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol), nil } func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { @@ -66,18 +68,19 @@ func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordComplexityPolicy(&existingPolicy.PasswordComplexityPolicyWriteModel), nil } diff --git a/internal/v2/command/iam_policy_password_complexity_model.go b/internal/v2/command/iam_policy_password_complexity_model.go index 6aada2caef..0dc0fbca36 100644 --- a/internal/v2/command/iam_policy_password_complexity_model.go +++ b/internal/v2/command/iam_policy_password_complexity_model.go @@ -42,11 +42,15 @@ func (wm *IAMPasswordComplexityPolicyWriteModel) Reduce() error { func (wm *IAMPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.PasswordComplexityPolicyAddedEventType, + iam.PasswordComplexityPolicyChangedEventType) } func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, minLength uint64, hasLowercase, hasUppercase, @@ -73,7 +77,7 @@ func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewPasswordComplexityPolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewPasswordComplexityPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/iam_policy_password_lockout.go b/internal/v2/command/iam_policy_password_lockout.go index 635b753d10..0f9e5d3dfd 100644 --- a/internal/v2/command/iam_policy_password_lockout.go +++ b/internal/v2/command/iam_policy_password_lockout.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" @@ -11,12 +12,15 @@ import ( func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { addedPolicy := NewIAMPasswordLockoutPolicyWriteModel() iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) - err := r.addDefaultPasswordLockoutPolicy(ctx, nil, addedPolicy, policy) + event, err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } @@ -24,18 +28,16 @@ func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, polic return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil } -func (r *CommandSide) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordLockoutPolicyWriteModel, policy *domain.PasswordLockoutPolicy) error { +func (r *CommandSide) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, addedPolicy *IAMPasswordLockoutPolicyWriteModel, policy *domain.PasswordLockoutPolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") } - iamAgg.PushEvents(iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)) - - return nil + return iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures), nil } func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { @@ -47,19 +49,20 @@ func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, po return nil, caos_errs.ThrowNotFound(nil, "IAM-0oPew", "Errors.IAM.PasswordLockoutPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, iamAgg, policy.MaxAttempts, policy.ShowLockOutFailures) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.PasswordLockoutPolicy.NotChanged") } - iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel) - iamAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil } diff --git a/internal/v2/command/iam_policy_password_lockout_model.go b/internal/v2/command/iam_policy_password_lockout_model.go index 21aa48f6ec..9775a2bfb5 100644 --- a/internal/v2/command/iam_policy_password_lockout_model.go +++ b/internal/v2/command/iam_policy_password_lockout_model.go @@ -42,10 +42,17 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error { func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + iam.PasswordLockoutPolicyAddedEventType, + iam.PasswordLockoutPolicyChangedEventType) } -func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) { +func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + maxAttempts uint64, + showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) { changes := make([]policy.PasswordLockoutPolicyChanges, 0) if wm.MaxAttempts != maxAttempts { changes = append(changes, policy.ChangeMaxAttempts(maxAttempts)) @@ -56,7 +63,7 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Contex if len(changes) == 0 { return nil, false } - changedEvent, err := iam.NewPasswordLockoutPolicyChangedEvent(ctx, changes) + changedEvent, err := iam.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/idp_config_model.go b/internal/v2/command/idp_config_model.go index 80a862e5e8..24834c57b5 100644 --- a/internal/v2/command/idp_config_model.go +++ b/internal/v2/command/idp_config_model.go @@ -15,6 +15,7 @@ type IDPConfigWriteModel struct { Name string StylingType domain.IDPConfigStylingType + //TODO: sub writemodels not used anymore? OIDCConfig *OIDCConfigWriteModel } diff --git a/internal/v2/command/key_pair.go b/internal/v2/command/key_pair.go index 8cbd49b249..4b43b708ad 100644 --- a/internal/v2/command/key_pair.go +++ b/internal/v2/command/key_pair.go @@ -29,15 +29,14 @@ func (r *CommandSide) GenerateSigningKeyPair(ctx context.Context, algorithm stri keyPairWriteModel := NewKeyPairWriteModel(keyID, domain.IAMID) keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel) - keyAgg.PushEvents( - keypair.NewAddedEvent( - ctx, - domain.KeyUsageSigning, - algorithm, - privateCrypto, publicCrypto, - privateKeyExp, publicKeyExp), - ) - return r.eventstore.PushAggregate(ctx, keyPairWriteModel, keyAgg) + _, err = r.eventstore.PushEvents(ctx, keypair.NewAddedEvent( + ctx, + keyAgg, + domain.KeyUsageSigning, + algorithm, + privateCrypto, publicCrypto, + privateKeyExp, publicKeyExp)) + return err } func setOIDCCtx(ctx context.Context) context.Context { diff --git a/internal/v2/command/key_pair_model.go b/internal/v2/command/key_pair_model.go index 3fe72786b5..126f25a084 100644 --- a/internal/v2/command/key_pair_model.go +++ b/internal/v2/command/key_pair_model.go @@ -51,11 +51,11 @@ func (wm *KeyPairWriteModel) Reduce() error { func (wm *KeyPairWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(keypair.AddedEventType) } -func KeyPairAggregateFromWriteModel(wm *eventstore.WriteModel) *keypair.Aggregate { - return &keypair.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, keypair.AggregateType, keypair.AggregateVersion), - } +func KeyPairAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, keypair.AggregateType, keypair.AggregateVersion) + } diff --git a/internal/v2/command/org.go b/internal/v2/command/org.go index 71bfb57e4a..bac6ac8b84 100644 --- a/internal/v2/command/org.go +++ b/internal/v2/command/org.go @@ -7,7 +7,6 @@ import ( caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/org" - "github.com/caos/zitadel/internal/v2/repository/user" ) func (r *CommandSide) getOrg(ctx context.Context, orgID string) (*domain.Org, error) { @@ -33,19 +32,16 @@ func (r *CommandSide) checkOrgExists(ctx context.Context, orgID string) error { } func (r *CommandSide) SetUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) error { - orgAgg, userAgg, orgMemberAgg, claimedUsers, err := r.setUpOrg(ctx, organisation, admin) + _, _, _, events, err := r.setUpOrg(ctx, organisation, admin) if err != nil { return err } - aggregates := make([]eventstore.Aggregater, 0) - aggregates = append(aggregates, orgAgg, userAgg, orgMemberAgg) - aggregates = append(aggregates, claimedUsers...) - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } func (r *CommandSide) AddOrg(ctx context.Context, name, userID, resourceOwner string) (*domain.Org, error) { - orgAgg, addedOrg, claimedUsers, err := r.addOrg(ctx, &domain.Org{Name: name}) + orgAgg, addedOrg, events, err := r.addOrg(ctx, &domain.Org{Name: name}) if err != nil { return nil, err } @@ -54,20 +50,17 @@ func (r *CommandSide) AddOrg(ctx context.Context, name, userID, resourceOwner st if err != nil { return nil, err } - addedMember := NewOrgMemberWriteModel(orgAgg.ID(), userID) - err = r.addOrgMember(ctx, orgAgg, addedMember, domain.NewMember(orgAgg.ID(), userID, domain.RoleOrgOwner)) + addedMember := NewOrgMemberWriteModel(addedOrg.AggregateID, userID) + orgMemberEvent, err := r.addOrgMember(ctx, orgAgg, addedMember, domain.NewMember(orgAgg.ID, userID, domain.RoleOrgOwner)) if err != nil { return nil, err } - aggregates := make([]eventstore.Aggregater, 0) - aggregates = append(aggregates, orgAgg) - aggregates = append(aggregates, claimedUsers...) - resEvents, err := r.eventstore.PushAggregates(ctx, aggregates...) + events = append(events, orgMemberEvent) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) if err != nil { return nil, err } - addedOrg.AppendEvents(resEvents...) - err = addedOrg.Reduce() + err = AppendAndReduce(addedOrg, pushedEvents...) if err != nil { return nil, err } @@ -86,9 +79,8 @@ func (r *CommandSide) DeactivateOrg(ctx context.Context, orgID string) error { return caos_errs.ThrowInvalidArgument(nil, "EVENT-Dbs2g", "Errors.Org.AlreadyDeactivated") } orgAgg := OrgAggregateFromWriteModel(&orgWriteModel.WriteModel) - orgAgg.PushEvents(org.NewOrgDeactivatedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, orgWriteModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewOrgDeactivatedEvent(ctx, orgAgg)) + return err } func (r *CommandSide) ReactivateOrg(ctx context.Context, orgID string) error { @@ -103,32 +95,33 @@ func (r *CommandSide) ReactivateOrg(ctx context.Context, orgID string) error { return caos_errs.ThrowInvalidArgument(nil, "EVENT-bfnrh", "Errors.Org.AlreadyActive") } orgAgg := OrgAggregateFromWriteModel(&orgWriteModel.WriteModel) - orgAgg.PushEvents(org.NewOrgReactivatedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, orgWriteModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewOrgReactivatedEvent(ctx, orgAgg)) + return err } -func (r *CommandSide) setUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) (*org.Aggregate, *user.Aggregate, *org.Aggregate, []eventstore.Aggregater, error) { - orgAgg, _, claimedUserAggregates, err := r.addOrg(ctx, organisation) +func (r *CommandSide) setUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) (orgAgg *eventstore.Aggregate, human *HumanWriteModel, orgMember *OrgMemberWriteModel, events []eventstore.EventPusher, err error) { + orgAgg, _, addOrgEvents, err := r.addOrg(ctx, organisation) if err != nil { return nil, nil, nil, nil, err } - userAgg, _, err := r.addHuman(ctx, orgAgg.ID(), admin) + userEvents, human, err := r.addHuman(ctx, orgAgg.ID, admin) if err != nil { return nil, nil, nil, nil, err } + addOrgEvents = append(addOrgEvents, userEvents...) - addedMember := NewOrgMemberWriteModel(orgAgg.ID(), userAgg.ID()) + addedMember := NewOrgMemberWriteModel(orgAgg.ID, human.AggregateID) orgMemberAgg := OrgAggregateFromWriteModel(&addedMember.WriteModel) - err = r.addOrgMember(ctx, orgMemberAgg, addedMember, domain.NewMember(orgMemberAgg.ID(), userAgg.ID(), domain.RoleOrgOwner)) + orgMemberEvent, err := r.addOrgMember(ctx, orgMemberAgg, addedMember, domain.NewMember(orgMemberAgg.ID, human.AggregateID, domain.RoleOrgOwner)) if err != nil { return nil, nil, nil, nil, err } - return orgAgg, userAgg, orgMemberAgg, claimedUserAggregates, nil + addOrgEvents = append(addOrgEvents, orgMemberEvent) + return orgAgg, human, addedMember, addOrgEvents, nil } -func (r *CommandSide) addOrg(ctx context.Context, organisation *domain.Org, claimedUserIDs ...string) (_ *org.Aggregate, _ *OrgWriteModel, _ []eventstore.Aggregater, err error) { +func (r *CommandSide) addOrg(ctx context.Context, organisation *domain.Org, claimedUserIDs ...string) (_ *eventstore.Aggregate, _ *OrgWriteModel, _ []eventstore.EventPusher, err error) { if organisation == nil || !organisation.IsValid() { return nil, nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMM-deLSk", "Errors.Org.Invalid") } @@ -141,17 +134,18 @@ func (r *CommandSide) addOrg(ctx context.Context, organisation *domain.Org, clai addedOrg := NewOrgWriteModel(organisation.AggregateID) orgAgg := OrgAggregateFromWriteModel(&addedOrg.WriteModel) - orgAgg.PushEvents(org.NewOrgAddedEvent(ctx, organisation.Name)) - claimedUserAggregates := make([]eventstore.Aggregater, 0) + events := []eventstore.EventPusher{ + org.NewOrgAddedEvent(ctx, orgAgg, organisation.Name), + } for _, orgDomain := range organisation.Domains { - aggregates, err := r.addOrgDomain(ctx, orgAgg, NewOrgDomainWriteModel(orgAgg.ID(), orgDomain.Domain), orgDomain, claimedUserIDs...) + orgDomainEvents, err := r.addOrgDomain(ctx, orgAgg, NewOrgDomainWriteModel(orgAgg.ID, orgDomain.Domain), orgDomain, claimedUserIDs...) if err != nil { return nil, nil, nil, err } else { - claimedUserAggregates = append(claimedUserAggregates, aggregates...) + events = append(events, orgDomainEvents...) } } - return orgAgg, addedOrg, claimedUserAggregates, nil + return orgAgg, addedOrg, events, nil } func (r *CommandSide) getOrgWriteModelByID(ctx context.Context, orgID string) (*OrgWriteModel, error) { diff --git a/internal/v2/command/org_domain.go b/internal/v2/command/org_domain.go index 370e51d923..0c1103d75e 100644 --- a/internal/v2/command/org_domain.go +++ b/internal/v2/command/org_domain.go @@ -16,27 +16,18 @@ import ( func (r *CommandSide) AddOrgDomain(ctx context.Context, orgDomain *domain.OrgDomain) (*domain.OrgDomain, error) { domainWriteModel := NewOrgDomainWriteModel(orgDomain.AggregateID, orgDomain.Domain) orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel) - userAggregates, err := r.addOrgDomain(ctx, orgAgg, domainWriteModel, orgDomain) + events, err := r.addOrgDomain(ctx, orgAgg, domainWriteModel, orgDomain) if err != nil { return nil, err } - if len(userAggregates) == 0 { - err = r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg) - if err != nil { - return nil, err - } - return orgDomainWriteModelToOrgDomain(domainWriteModel), nil - } - - aggregates := make([]eventstore.Aggregater, 0) - aggregates = append(aggregates, orgAgg) - aggregates = append(aggregates, userAggregates...) - resultEvents, err := r.eventstore.PushAggregates(ctx, aggregates...) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(domainWriteModel, pushedEvents...) if err != nil { return nil, err } - domainWriteModel.AppendEvents(resultEvents...) - domainWriteModel.Reduce() return orgDomainWriteModelToOrgDomain(domainWriteModel), nil } @@ -68,9 +59,10 @@ func (r *CommandSide) GenerateOrgDomainValidation(ctx context.Context, orgDomain } orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel) - orgAgg.PushEvents(org.NewDomainVerificationAddedEvent(ctx, orgDomain.Domain, orgDomain.ValidationType, orgDomain.ValidationCode)) - err = r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg) + _, err = r.eventstore.PushEvents( + ctx, + org.NewDomainVerificationAddedEvent(ctx, orgAgg, orgDomain.Domain, orgDomain.ValidationType, orgDomain.ValidationCode)) if err != nil { return "", "", err } @@ -102,25 +94,24 @@ func (r *CommandSide) ValidateOrgDomain(ctx context.Context, orgDomain *domain.O checkType, _ := domainWriteModel.ValidationType.CheckType() err = r.domainVerificationValidator(domainWriteModel.Domain, validationCode, validationCode, checkType) orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel) + var events []eventstore.EventPusher if err == nil { - aggregates := make([]eventstore.Aggregater, 0) - orgAgg.PushEvents(org.NewDomainVerifiedEvent(ctx, orgDomain.Domain)) - aggregates = append(aggregates, orgAgg) + events = append(events, org.NewDomainVerifiedEvent(ctx, orgAgg, orgDomain.Domain)) for _, userID := range claimedUserIDs { - userAgg, _, err := r.userDomainClaimed(ctx, userID) + userEvents, _, err := r.userDomainClaimed(ctx, userID) if err != nil { logging.LogWithFields("COMMAND-5m8fs", "userid", userID).WithError(err).Warn("could not claim user") continue } - aggregates = append(aggregates, userAgg) + events = append(events, userEvents...) } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } - orgAgg.PushEvents(org.NewDomainVerificationFailedEvent(ctx, orgDomain.Domain)) - err = r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg) - logging.LogWithFields("ORG-dhTE", "orgID", orgAgg.ID(), "domain", orgDomain.Domain).OnError(err).Error("NewDomainVerificationFailedEvent push failed") + events = append(events, org.NewDomainVerificationFailedEvent(ctx, orgAgg, orgDomain.Domain)) + _, err = r.eventstore.PushEvents(ctx, events...) + logging.LogWithFields("ORG-dhTE", "orgID", orgAgg.ID, "domain", orgDomain.Domain).OnError(err).Error("NewDomainVerificationFailedEvent push failed") return caos_errs.ThrowInvalidArgument(err, "ORG-GH3s", "Errors.Org.DomainVerificationFailed") } @@ -139,8 +130,8 @@ func (r *CommandSide) SetPrimaryOrgDomain(ctx context.Context, orgDomain *domain return caos_errs.ThrowPreconditionFailed(nil, "ORG-Ggd32", "Errors.Org.DomainNotVerified") } orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel) - orgAgg.PushEvents(org.NewDomainPrimarySetEvent(ctx, orgDomain.Domain)) - return r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewDomainPrimarySetEvent(ctx, orgAgg, orgDomain.Domain)) + return err } func (r *CommandSide) RemoveOrgDomain(ctx context.Context, orgDomain *domain.OrgDomain) error { @@ -158,11 +149,11 @@ func (r *CommandSide) RemoveOrgDomain(ctx context.Context, orgDomain *domain.Org return caos_errs.ThrowPreconditionFailed(nil, "ORG-Sjdi3", "Errors.Org.PrimaryDomainNotDeletable") } orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel) - orgAgg.PushEvents(org.NewDomainRemovedEvent(ctx, orgDomain.Domain)) - return r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewDomainRemovedEvent(ctx, orgAgg, orgDomain.Domain)) + return err } -func (r *CommandSide) addOrgDomain(ctx context.Context, orgAgg *org.Aggregate, addedDomain *OrgDomainWriteModel, orgDomain *domain.OrgDomain, claimedUserIDs ...string) ([]eventstore.Aggregater, error) { +func (r *CommandSide) addOrgDomain(ctx context.Context, orgAgg *eventstore.Aggregate, addedDomain *OrgDomainWriteModel, orgDomain *domain.OrgDomain, claimedUserIDs ...string) ([]eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedDomain) if err != nil { return nil, err @@ -171,24 +162,25 @@ func (r *CommandSide) addOrgDomain(ctx context.Context, orgAgg *org.Aggregate, a return nil, caos_errs.ThrowAlreadyExists(nil, "COMMA-Bd2jj", "Errors.Org.Domain.AlreadyExists") } - orgAgg.PushEvents(org.NewDomainAddedEvent(ctx, orgDomain.Domain)) + events := []eventstore.EventPusher{ + org.NewDomainAddedEvent(ctx, orgAgg, orgDomain.Domain), + } - userAggregates := make([]eventstore.Aggregater, 0) if orgDomain.Verified { - orgAgg.PushEvents(org.NewDomainVerifiedEvent(ctx, orgDomain.Domain)) + events = append(events, org.NewDomainVerifiedEvent(ctx, orgAgg, orgDomain.Domain)) for _, userID := range claimedUserIDs { - userAgg, _, err := r.userDomainClaimed(ctx, userID) + userEvents, _, err := r.userDomainClaimed(ctx, userID) if err != nil { logging.LogWithFields("COMMAND-nn8Jf", "userid", userID).WithError(err).Warn("could not claim user") continue } - userAggregates = append(userAggregates, userAgg) + events = append(events, userEvents...) } } if orgDomain.Primary { - orgAgg.PushEvents(org.NewDomainPrimarySetEvent(ctx, orgDomain.Domain)) + events = append(events, org.NewDomainPrimarySetEvent(ctx, orgAgg, orgDomain.Domain)) } - return userAggregates, nil + return events, nil } func (r *CommandSide) getOrgDomainWriteModel(ctx context.Context, orgID, domain string) (*OrgDomainWriteModel, error) { diff --git a/internal/v2/command/org_domain_model.go b/internal/v2/command/org_domain_model.go index d35c45f7d7..1e4da098bc 100644 --- a/internal/v2/command/org_domain_model.go +++ b/internal/v2/command/org_domain_model.go @@ -88,5 +88,12 @@ func (wm *OrgDomainWriteModel) Reduce() error { func (wm *OrgDomainWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.OrgDomainAddedEventType, + org.OrgDomainVerifiedEventType, + org.OrgDomainVerificationAddedEventType, + org.OrgDomainVerifiedEventType, + org.OrgDomainPrimarySetEventType, + org.OrgDomainRemovedEventType) } diff --git a/internal/v2/command/org_idp_config.go b/internal/v2/command/org_idp_config.go index c38d9a43af..ade4a336dd 100644 --- a/internal/v2/command/org_idp_config.go +++ b/internal/v2/command/org_idp_config.go @@ -30,28 +30,31 @@ func (r *CommandSide) AddIDPConfig(ctx context.Context, config *domain.IDPConfig } orgAgg := OrgAggregateFromWriteModel(&addedConfig.WriteModel) - orgAgg.PushEvents( + events := []eventstore.EventPusher{ org_repo.NewIDPConfigAddedEvent( ctx, - orgAgg.ResourceOwner(), + orgAgg, idpConfigID, config.Name, config.Type, config.StylingType, ), - ) - orgAgg.PushEvents( org_repo.NewIDPOIDCConfigAddedEvent( - ctx, config.OIDCConfig.ClientID, + ctx, + orgAgg, + config.OIDCConfig.ClientID, idpConfigID, config.OIDCConfig.Issuer, clientSecret, config.OIDCConfig.IDPDisplayNameMapping, config.OIDCConfig.UsernameMapping, - config.OIDCConfig.Scopes..., - ), - ) - err = r.eventstore.PushAggregate(ctx, addedConfig, orgAgg) + config.OIDCConfig.Scopes...), + } + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedConfig, pushedEvents...) if err != nil { return nil, err } @@ -67,9 +70,10 @@ func (r *CommandSide) ChangeIDPConfig(ctx context.Context, config *domain.IDPCon return nil, caos_errs.ThrowNotFound(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotExisting") } + orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel) changedEvent, hasChanged := existingIDP.NewChangedEvent( ctx, - existingIDP.ResourceOwner, + orgAgg, config.IDPConfigID, config.Name, config.StylingType) @@ -77,10 +81,11 @@ func (r *CommandSide) ChangeIDPConfig(ctx context.Context, config *domain.IDPCon if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingIDP, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingIDP, pushedEvents...) if err != nil { return nil, err } @@ -96,9 +101,8 @@ func (r *CommandSide) DeactivateIDPConfig(ctx context.Context, idpID, orgID stri return caos_errs.ThrowPreconditionFailed(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotActive") } orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel) - orgAgg.PushEvents(org_repo.NewIDPConfigDeactivatedEvent(ctx, idpID)) - - return r.eventstore.PushAggregate(ctx, existingIDP, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org_repo.NewIDPConfigDeactivatedEvent(ctx, orgAgg, idpID)) + return err } func (r *CommandSide) ReactivateIDPConfig(ctx context.Context, idpID, orgID string) error { @@ -110,9 +114,8 @@ func (r *CommandSide) ReactivateIDPConfig(ctx context.Context, idpID, orgID stri return caos_errs.ThrowPreconditionFailed(nil, "Org-5Mo0d", "Errors.Org.IDPConfig.NotInactive") } orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel) - orgAgg.PushEvents(org_repo.NewIDPConfigReactivatedEvent(ctx, idpID)) - - return r.eventstore.PushAggregate(ctx, existingIDP, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org_repo.NewIDPConfigReactivatedEvent(ctx, orgAgg, idpID)) + return err } func (r *CommandSide) RemoveIDPConfig(ctx context.Context, idpID, orgID string, cascadeRemoveProvider bool, cascadeExternalIDPs ...*domain.ExternalIDP) error { @@ -128,18 +131,16 @@ func (r *CommandSide) RemoveIDPConfig(ctx context.Context, idpID, orgID string, return caos_errs.ThrowPreconditionFailed(nil, "Org-5Mo0d", "Errors.Org.IDPConfig.NotInactive") } - aggregates := make([]eventstore.Aggregater, 0) orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel) - orgAgg.PushEvents(org_repo.NewIDPConfigRemovedEvent(ctx, existingIDP.ResourceOwner, idpID, existingIDP.Name)) - - userAggregates := make([]eventstore.Aggregater, 0) - if cascadeRemoveProvider { - userAggregates = r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpID, true, cascadeExternalIDPs...) + events := []eventstore.EventPusher{ + org_repo.NewIDPConfigRemovedEvent(ctx, orgAgg, idpID, existingIDP.Name), } - aggregates = append(aggregates, orgAgg) - aggregates = append(aggregates, userAggregates...) - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + if cascadeRemoveProvider { + removeIDPEvents := r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpID, true, cascadeExternalIDPs...) + events = append(events, removeIDPEvents...) + } + _, err = r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/org_idp_config_model.go b/internal/v2/command/org_idp_config_model.go index 6004d4850c..c1b062f1bb 100644 --- a/internal/v2/command/org_idp_config_model.go +++ b/internal/v2/command/org_idp_config_model.go @@ -28,7 +28,15 @@ func NewOrgIDPConfigWriteModel(configID, orgID string) *OrgIDPConfigWriteModel { func (wm *OrgIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.IDPConfigAddedEventType, + org.IDPConfigChangedEventType, + org.IDPConfigDeactivatedEventType, + org.IDPConfigReactivatedEventType, + org.IDPConfigRemovedEventType, + org.IDPOIDCConfigAddedEventType, + org.IDPOIDCConfigChangedEventType) } func (wm *OrgIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { @@ -84,7 +92,7 @@ func (wm *OrgIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventRead func (wm *OrgIDPConfigWriteModel) NewChangedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, name string, stylingType domain.IDPConfigStylingType, @@ -102,7 +110,7 @@ func (wm *OrgIDPConfigWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changeEvent, err := org.NewIDPConfigChangedEvent(ctx, resourceOwner, configID, oldName, changes) + changeEvent, err := org.NewIDPConfigChangedEvent(ctx, aggregate, configID, oldName, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_idp_oidc_config.go b/internal/v2/command/org_idp_oidc_config.go index 851fb5e5fc..ade56a3425 100644 --- a/internal/v2/command/org_idp_oidc_config.go +++ b/internal/v2/command/org_idp_oidc_config.go @@ -17,8 +17,10 @@ func (r *CommandSide) ChangeIDPOIDCConfig(ctx context.Context, config *domain.OI return nil, caos_errs.ThrowAlreadyExists(nil, "Org-67J9d", "Errors.Org.IDPConfig.AlreadyExists") } + orgAgg := OrgAggregateFromWriteModel(&existingConfig.WriteModel) changedEvent, hasChanged, err := existingConfig.NewChangedEvent( ctx, + orgAgg, config.IDPConfigID, config.ClientID, config.Issuer, @@ -34,10 +36,11 @@ func (r *CommandSide) ChangeIDPOIDCConfig(ctx context.Context, config *domain.OI return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingConfig.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingConfig, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingConfig, pushedEvents...) if err != nil { return nil, err } diff --git a/internal/v2/command/org_idp_oidc_config_model.go b/internal/v2/command/org_idp_oidc_config_model.go index e2cbc455b9..dbbc817b73 100644 --- a/internal/v2/command/org_idp_oidc_config_model.go +++ b/internal/v2/command/org_idp_oidc_config_model.go @@ -71,11 +71,18 @@ func (wm *IDPOIDCConfigWriteModel) Reduce() error { func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.IDPOIDCConfigAddedEventType, + org.IDPOIDCConfigChangedEventType, + org.IDPConfigReactivatedEventType, + org.IDPConfigDeactivatedEventType, + org.IDPConfigRemovedEventType) } func (wm *IDPOIDCConfigWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID, clientID, issuer, @@ -114,7 +121,7 @@ func (wm *IDPOIDCConfigWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false, nil } - changeEvent, err := org.NewIDPOIDCConfigChangedEvent(ctx, idpConfigID, changes) + changeEvent, err := org.NewIDPOIDCConfigChangedEvent(ctx, aggregate, idpConfigID, changes) if err != nil { return nil, false, err } diff --git a/internal/v2/command/org_member.go b/internal/v2/command/org_member.go index f7e2ea49ca..c84a3dd7e9 100644 --- a/internal/v2/command/org_member.go +++ b/internal/v2/command/org_member.go @@ -6,6 +6,7 @@ import ( "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/org" @@ -14,37 +15,38 @@ import ( func (r *CommandSide) AddOrgMember(ctx context.Context, member *domain.Member) (*domain.Member, error) { addedMember := NewOrgMemberWriteModel(member.AggregateID, member.UserID) orgAgg := OrgAggregateFromWriteModel(&addedMember.WriteModel) - err := r.addOrgMember(ctx, orgAgg, addedMember, member) + event, err := r.addOrgMember(ctx, orgAgg, addedMember, member) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedMember, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedMember, pushedEvents...) if err != nil { return nil, err } - return memberWriteModelToMember(&addedMember.MemberWriteModel), nil } -func (r *CommandSide) addOrgMember(ctx context.Context, orgAgg *org.Aggregate, addedMember *OrgMemberWriteModel, member *domain.Member) error { +func (r *CommandSide) addOrgMember(ctx context.Context, orgAgg *eventstore.Aggregate, addedMember *OrgMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) { //TODO: check if roles valid if !member.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "Org-W8m4l", "Errors.Org.MemberInvalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-W8m4l", "Errors.Org.MemberInvalid") } err := r.eventstore.FilterToQueryReducer(ctx, addedMember) if err != nil { - return err + return nil, err } if addedMember.State == domain.MemberStateActive { - return errors.ThrowAlreadyExists(nil, "Org-PtXi1", "Errors.Org.Member.AlreadyExists") + return nil, errors.ThrowAlreadyExists(nil, "Org-PtXi1", "Errors.Org.Member.AlreadyExists") } - orgAgg.PushEvents(org.NewMemberAddedEvent(ctx, orgAgg.ID(), member.UserID, member.Roles...)) - - return nil + return org.NewMemberAddedEvent(ctx, orgAgg, member.UserID, member.Roles...), nil } //ChangeOrgMember updates an existing member @@ -64,18 +66,12 @@ func (r *CommandSide) ChangeOrgMember(ctx context.Context, member *domain.Member return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-LiaZi", "Errors.Org.Member.RolesNotChanged") } orgAgg := OrgAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) - orgAgg.PushEvents(org.NewMemberChangedEvent(ctx, member.UserID, member.Roles...)) - - events, err := r.eventstore.PushAggregates(ctx, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewMemberChangedEvent(ctx, orgAgg, member.UserID, member.Roles...)) + err = AppendAndReduce(existingMember, pushedEvents...) if err != nil { return nil, err } - existingMember.AppendEvents(events...) - if err = existingMember.Reduce(); err != nil { - return nil, err - } - return memberWriteModelToMember(&existingMember.MemberWriteModel), nil } @@ -89,9 +85,8 @@ func (r *CommandSide) RemoveOrgMember(ctx context.Context, orgID, userID string) } orgAgg := OrgAggregateFromWriteModel(&m.MemberWriteModel.WriteModel) - orgAgg.PushEvents(org.NewMemberRemovedEvent(ctx, orgAgg.ID(), userID)) - - return r.eventstore.PushAggregate(ctx, m, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewMemberRemovedEvent(ctx, orgAgg, userID)) + return err } func (r *CommandSide) orgMemberWriteModelByID(ctx context.Context, orgID, userID string) (member *OrgMemberWriteModel, err error) { diff --git a/internal/v2/command/org_member_model.go b/internal/v2/command/org_member_model.go index fd9075597f..a9c43e774d 100644 --- a/internal/v2/command/org_member_model.go +++ b/internal/v2/command/org_member_model.go @@ -50,5 +50,9 @@ func (wm *OrgMemberWriteModel) Reduce() error { func (wm *OrgMemberWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.MemberWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.MemberAddedEventType, + org.MemberChangedEventType, + org.MemberRemovedEventType) } diff --git a/internal/v2/command/org_model.go b/internal/v2/command/org_model.go index 9ba1f3c0a4..b55e8e88cd 100644 --- a/internal/v2/command/org_model.go +++ b/internal/v2/command/org_model.go @@ -3,7 +3,6 @@ package command import ( "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" - "github.com/caos/zitadel/internal/v2/repository/iam" "github.com/caos/zitadel/internal/v2/repository/org" ) @@ -24,19 +23,6 @@ func NewOrgWriteModel(orgID string) *OrgWriteModel { } } -func (wm *OrgWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) - for _, event := range events { - switch e := event.(type) { - case *org.OrgAddedEvent, - *iam.LabelPolicyChangedEvent: - wm.WriteModel.AppendEvents(e) - case *org.DomainPrimarySetEvent: - wm.WriteModel.AppendEvents(e) - } - } -} - func (wm *OrgWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -55,11 +41,13 @@ func (wm *OrgWriteModel) Reduce() error { func (wm *OrgWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.OrgAddedEventType, + org.OrgChangedEventType, + org.OrgDomainPrimarySetEventType) } -func OrgAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate { - return &org.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, org.AggregateType, org.AggregateVersion), - } +func OrgAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, org.AggregateType, org.AggregateVersion) } diff --git a/internal/v2/command/org_policy_label.go b/internal/v2/command/org_policy_label.go index 1c7628c0be..c0303f7a51 100644 --- a/internal/v2/command/org_policy_label.go +++ b/internal/v2/command/org_policy_label.go @@ -19,13 +19,14 @@ func (r *CommandSide) AddLabelPolicy(ctx context.Context, resourceOwner string, } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel) - orgAgg.PushEvents(org.NewLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewLabelPolicyAddedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLabelPolicy(&addedPolicy.LabelPolicyWriteModel), nil } @@ -39,19 +40,20 @@ func (r *CommandSide) ChangeLabelPolicy(ctx context.Context, resourceOwner strin return nil, caos_errs.ThrowNotFound(nil, "Org-0K9dq", "Errors.Org.LabelPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.PrimaryColor, policy.SecondaryColor) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLabelPolicy(&existingPolicy.LabelPolicyWriteModel), nil } @@ -65,7 +67,6 @@ func (r *CommandSide) RemoveLabelPolicy(ctx context.Context, orgID string) error return caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LabelPolicy.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewLabelPolicyRemovedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewLabelPolicyRemovedEvent(ctx, orgAgg)) + return err } diff --git a/internal/v2/command/org_policy_label_model.go b/internal/v2/command/org_policy_label_model.go index 3a62865216..a5d51df520 100644 --- a/internal/v2/command/org_policy_label_model.go +++ b/internal/v2/command/org_policy_label_model.go @@ -41,11 +41,15 @@ func (wm *OrgLabelPolicyWriteModel) Reduce() error { func (wm *OrgLabelPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.LabelPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.LabelPolicyAddedEventType, + org.LabelPolicyChangedEventType) } func (wm *OrgLabelPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, primaryColor, secondaryColor string, ) (*org.LabelPolicyChangedEvent, bool) { @@ -59,7 +63,7 @@ func (wm *OrgLabelPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewLabelPolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewLabelPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_login.go b/internal/v2/command/org_policy_login.go index 9393ab8cf3..31674b628b 100644 --- a/internal/v2/command/org_policy_login.go +++ b/internal/v2/command/org_policy_login.go @@ -3,9 +3,8 @@ package command import ( "context" "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore/v2" - caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/org" ) @@ -21,13 +20,23 @@ func (r *CommandSide) AddLoginPolicy(ctx context.Context, resourceOwner string, } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents( + ctx, + org.NewLoginPolicyAddedEvent( + ctx, + orgAgg, + policy.AllowUsernamePassword, + policy.AllowRegister, + policy.AllowExternalIDP, + policy.ForceMFA, + policy.PasswordlessType)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLoginPolicy(&addedPolicy.LoginPolicyWriteModel), nil } @@ -40,19 +49,20 @@ func (r *CommandSide) ChangeLoginPolicy(ctx context.Context, resourceOwner strin if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved { return nil, caos_errs.ThrowNotFound(nil, "Org-M0sif", "Errors.Org.LoginPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIDP, policy.ForceMFA, policy.PasswordlessType) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-5M9vdd", "Errors.Org.LoginPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToLoginPolicy(&existingPolicy.LoginPolicyWriteModel), nil } @@ -66,9 +76,8 @@ func (r *CommandSide) RemoveLoginPolicy(ctx context.Context, orgID string) error return caos_errs.ThrowNotFound(nil, "Org-GHB37", "Errors.Org.LoginPolicy.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicyRemovedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewLoginPolicyRemovedEvent(ctx, orgAgg)) + return err } func (r *CommandSide) AddIDPProviderToLoginPolicy(ctx context.Context, resourceOwner string, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) { @@ -82,12 +91,14 @@ func (r *CommandSide) AddIDPProviderToLoginPolicy(ctx context.Context, resourceO } orgAgg := OrgAggregateFromWriteModel(&idpModel.WriteModel) - orgAgg.PushEvents(org.NewIdentityProviderAddedEvent(ctx, idpProvider.IDPConfigID, idpProvider.Type)) - - if err = r.eventstore.PushAggregate(ctx, idpModel, orgAgg); err != nil { + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewIdentityProviderAddedEvent(ctx, orgAgg, idpProvider.IDPConfigID, idpProvider.Type)) + if err != nil { + return nil, err + } + err = AppendAndReduce(idpModel, pushedEvents...) + if err != nil { return nil, err } - return writeModelToIDPProvider(&idpModel.IdentityProviderWriteModel), nil } @@ -101,35 +112,30 @@ func (r *CommandSide) RemoveIDPProviderFromLoginPolicy(ctx context.Context, reso return caos_errs.ThrowNotFound(nil, "Org-39fjs", "Errors.Org.LoginPolicy.IDP.NotExisting") } - aggregates := make([]eventstore.Aggregater, 0) orgAgg := OrgAggregateFromWriteModel(&idpModel.IdentityProviderWriteModel.WriteModel) - userAggregates := r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpProvider.IDPConfigID, false, cascadeExternalIDPs...) + events := r.removeIDPProviderFromLoginPolicy(ctx, orgAgg, idpProvider.IDPConfigID, false, cascadeExternalIDPs...) - aggregates = append(aggregates, orgAgg) - aggregates = append(aggregates, userAggregates...) - - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } -func (r *CommandSide) removeIDPProviderFromLoginPolicy(ctx context.Context, orgAgg *org.Aggregate, idpConfigID string, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.Aggregater { +func (r *CommandSide) removeIDPProviderFromLoginPolicy(ctx context.Context, orgAgg *eventstore.Aggregate, idpConfigID string, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.EventPusher { + var events []eventstore.EventPusher if cascade { - orgAgg.PushEvents(org.NewIdentityProviderCascadeRemovedEvent(ctx, idpConfigID)) - + events = append(events, org.NewIdentityProviderCascadeRemovedEvent(ctx, orgAgg, idpConfigID)) } else { - orgAgg.PushEvents(org.NewIdentityProviderRemovedEvent(ctx, idpConfigID)) + events = append(events, org.NewIdentityProviderRemovedEvent(ctx, orgAgg, idpConfigID)) } - userAggregates := make([]eventstore.Aggregater, 0) for _, idp := range cascadeExternalIDPs { - userAgg, _, err := r.removeHumanExternalIDP(ctx, idp, true) + event, err := r.removeHumanExternalIDP(ctx, idp, true) if err != nil { logging.LogWithFields("COMMAND-n8RRf", "userid", idp.AggregateID, "idpconfigid", idp.IDPConfigID).WithError(err).Warn("could not cascade remove external idp") continue } - userAggregates = append(userAggregates, userAgg) + events = append(events, event) } - return userAggregates + return events } func (r *CommandSide) AddSecondFactorToLoginPolicy(ctx context.Context, secondFactor domain.SecondFactorType, orgID string) (domain.SecondFactorType, error) { @@ -144,9 +150,8 @@ func (r *CommandSide) AddSecondFactorToLoginPolicy(ctx context.Context, secondFa } orgAgg := OrgAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicySecondFactorAddedEvent(ctx, secondFactor)) - if err = r.eventstore.PushAggregate(ctx, secondFactorModel, orgAgg); err != nil { + if _, err = r.eventstore.PushEvents(ctx, org.NewLoginPolicySecondFactorAddedEvent(ctx, orgAgg, secondFactor)); err != nil { return domain.SecondFactorTypeUnspecified, err } @@ -163,9 +168,9 @@ func (r *CommandSide) RemoveSecondFactorFromLoginPolicy(ctx context.Context, sec return caos_errs.ThrowNotFound(nil, "Org-3M9od", "Errors.Org.LoginPolicy.MFA.NotExisting") } orgAgg := OrgAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicySecondFactorRemovedEvent(ctx, domain.SecondFactorType(secondFactor))) - return r.eventstore.PushAggregate(ctx, secondFactorModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewLoginPolicySecondFactorRemovedEvent(ctx, orgAgg, secondFactor)) + return err } func (r *CommandSide) AddMultiFactorToLoginPolicy(ctx context.Context, multiFactor domain.MultiFactorType, orgID string) (domain.MultiFactorType, error) { @@ -179,9 +184,8 @@ func (r *CommandSide) AddMultiFactorToLoginPolicy(ctx context.Context, multiFact } orgAgg := OrgAggregateFromWriteModel(&multiFactorModel.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicyMultiFactorAddedEvent(ctx, multiFactor)) - if err = r.eventstore.PushAggregate(ctx, multiFactorModel, orgAgg); err != nil { + if _, err = r.eventstore.PushEvents(ctx, org.NewLoginPolicyMultiFactorAddedEvent(ctx, orgAgg, multiFactor)); err != nil { return domain.MultiFactorTypeUnspecified, err } @@ -198,7 +202,7 @@ func (r *CommandSide) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mult return caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LoginPolicy.MFA.NotExisting") } orgAgg := OrgAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) - orgAgg.PushEvents(org.NewLoginPolicyMultiFactorRemovedEvent(ctx, domain.MultiFactorType(multiFactor))) - return r.eventstore.PushAggregate(ctx, multiFactorModel, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewLoginPolicyMultiFactorRemovedEvent(ctx, orgAgg, multiFactor)) + return err } diff --git a/internal/v2/command/org_policy_login_factors_model.go b/internal/v2/command/org_policy_login_factors_model.go index 5cbc7d42be..fc8a060e0a 100644 --- a/internal/v2/command/org_policy_login_factors_model.go +++ b/internal/v2/command/org_policy_login_factors_model.go @@ -2,7 +2,7 @@ package command import ( "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/org" ) type OrgSecondFactorWriteModel struct { @@ -23,8 +23,10 @@ func NewOrgSecondFactorWriteModel(orgID string) *OrgSecondFactorWriteModel { func (wm *OrgSecondFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { for _, event := range events { switch e := event.(type) { - case *iam.LoginPolicySecondFactorAddedEvent: + case *org.LoginPolicySecondFactorAddedEvent: wm.WriteModel.AppendEvents(&e.SecondFactorAddedEvent) + case *org.LoginPolicySecondFactorRemovedEvent: + wm.WriteModel.AppendEvents(&e.SecondFactorRemovedEvent) } } } @@ -34,9 +36,12 @@ func (wm *OrgSecondFactorWriteModel) Reduce() error { } func (wm *OrgSecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.WriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.LoginPolicySecondFactorAddedEventType, + org.LoginPolicySecondFactorRemovedEventType) } type OrgMultiFactorWriteModel struct { @@ -57,8 +62,10 @@ func NewOrgMultiFactorWriteModel(orgID string) *OrgMultiFactorWriteModel { func (wm *OrgMultiFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { for _, event := range events { switch e := event.(type) { - case *iam.LoginPolicyMultiFactorAddedEvent: + case *org.LoginPolicyMultiFactorAddedEvent: wm.WriteModel.AppendEvents(&e.MultiFactorAddedEvent) + case *org.LoginPolicyMultiFactorRemovedEvent: + wm.WriteModel.AppendEvents(&e.MultiFactorRemovedEvent) } } } @@ -68,7 +75,10 @@ func (wm *OrgMultiFactorWriteModel) Reduce() error { } func (wm *OrgMultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.WriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.LoginPolicyMultiFactorAddedEventType, + org.LoginPolicyMultiFactorRemovedEventType) } diff --git a/internal/v2/command/org_policy_login_model.go b/internal/v2/command/org_policy_login_model.go index 3bab9fba47..4314bdf9b4 100644 --- a/internal/v2/command/org_policy_login_model.go +++ b/internal/v2/command/org_policy_login_model.go @@ -48,11 +48,16 @@ func (wm *OrgLoginPolicyWriteModel) Reduce() error { func (wm *OrgLoginPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.LoginPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.LoginPolicyAddedEventType, + org.LoginPolicyChangedEventType, + org.LoginPolicyRemovedEventType) } func (wm *OrgLoginPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, allowUsernamePassword, allowRegister, allowExternalIDP, @@ -79,7 +84,7 @@ func (wm *OrgLoginPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewLoginPolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewLoginPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_mail_template.go b/internal/v2/command/org_policy_mail_template.go index 558c7513d6..c7c47463cc 100644 --- a/internal/v2/command/org_policy_mail_template.go +++ b/internal/v2/command/org_policy_mail_template.go @@ -22,13 +22,14 @@ func (r *CommandSide) AddMailTemplate(ctx context.Context, resourceOwner string, } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.MailTemplateWriteModel.WriteModel) - orgAgg.PushEvents(org.NewMailTemplateAddedEvent(ctx, policy.Template)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewMailTemplateAddedEvent(ctx, orgAgg, policy.Template)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTemplate(&addedPolicy.MailTemplateWriteModel), nil } @@ -45,19 +46,20 @@ func (r *CommandSide) ChangeMailTemplate(ctx context.Context, resourceOwner stri return nil, caos_errs.ThrowNotFound(nil, "Org-5m9ie", "Errors.Org.MailTemplate.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.Template) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.Template) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.MailTemplate.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTemplateWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToMailTemplate(&existingPolicy.MailTemplateWriteModel), nil } @@ -71,7 +73,7 @@ func (r *CommandSide) RemoveMailTemplate(ctx context.Context, orgID string) erro return caos_errs.ThrowNotFound(nil, "Org-3b8Jf", "Errors.Org.MailTemplate.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewMailTemplateRemovedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewMailTemplateRemovedEvent(ctx, orgAgg)) + return err } diff --git a/internal/v2/command/org_policy_mail_template_model.go b/internal/v2/command/org_policy_mail_template_model.go index 1ac78bedf5..5b64e7e35e 100644 --- a/internal/v2/command/org_policy_mail_template_model.go +++ b/internal/v2/command/org_policy_mail_template_model.go @@ -31,6 +31,8 @@ func (wm *OrgMailTemplateWriteModel) AppendEvents(events ...eventstore.EventRead wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateAddedEvent) case *org.MailTemplateChangedEvent: wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateChangedEvent) + case *org.MailTemplateRemovedEvent: + wm.MailTemplateWriteModel.AppendEvents(&e.MailTemplateRemovedEvent) } } } @@ -41,7 +43,12 @@ func (wm *OrgMailTemplateWriteModel) Reduce() error { func (wm *OrgMailTemplateWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). - AggregateIDs(wm.MailTemplateWriteModel.AggregateID) + AggregateIDs(wm.MailTemplateWriteModel.AggregateID). + EventTypes( + org.MailTemplateAddedEventType, + org.MailTemplateChangedEventType, + org.MailTemplateRemovedEventType) + if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } @@ -50,6 +57,7 @@ func (wm *OrgMailTemplateWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *OrgMailTemplateWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, template []byte, ) (*org.MailTemplateChangedEvent, bool) { changes := make([]policy.MailTemplateChanges, 0) @@ -59,7 +67,7 @@ func (wm *OrgMailTemplateWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewMailTemplateChangedEvent(ctx, changes) + changedEvent, err := org.NewMailTemplateChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_mail_text.go b/internal/v2/command/org_policy_mail_text.go index ae4e7db6db..962cadd260 100644 --- a/internal/v2/command/org_policy_mail_text.go +++ b/internal/v2/command/org_policy_mail_text.go @@ -22,10 +22,11 @@ func (r *CommandSide) AddMailText(ctx context.Context, resourceOwner string, mai } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.MailTextWriteModel.WriteModel) - orgAgg.PushEvents( + pushedEvents, err := r.eventstore.PushEvents( + ctx, org.NewMailTextAddedEvent( ctx, - resourceOwner, + orgAgg, mailText.MailTextType, mailText.Language, mailText.Title, @@ -34,8 +35,10 @@ func (r *CommandSide) AddMailText(ctx context.Context, resourceOwner string, mai mailText.Greeting, mailText.Text, mailText.ButtonText)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } @@ -56,8 +59,10 @@ func (r *CommandSide) ChangeMailText(ctx context.Context, resourceOwner string, return nil, caos_errs.ThrowNotFound(nil, "Org-3n8fM", "Errors.Org.MailText.NotFound") } + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) changedEvent, hasChanged := existingPolicy.NewChangedEvent( ctx, + orgAgg, mailText.MailTextType, mailText.Language, mailText.Title, @@ -70,10 +75,11 @@ func (r *CommandSide) ChangeMailText(ctx context.Context, resourceOwner string, return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-2n9fs", "Errors.Org.MailText.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.MailTextWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } @@ -91,7 +97,6 @@ func (r *CommandSide) RemoveMailText(ctx context.Context, resourceOwner, mailTex return caos_errs.ThrowNotFound(nil, "Org-3b8Jf", "Errors.Org.MailText.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewMailTextRemovedEvent(ctx, mailTextType, language, resourceOwner)) - - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewMailTextRemovedEvent(ctx, orgAgg, mailTextType, language)) + return err } diff --git a/internal/v2/command/org_policy_mail_text_model.go b/internal/v2/command/org_policy_mail_text_model.go index e493e5cf5b..723fa9643a 100644 --- a/internal/v2/command/org_policy_mail_text_model.go +++ b/internal/v2/command/org_policy_mail_text_model.go @@ -31,6 +31,8 @@ func (wm *OrgMailTextWriteModel) AppendEvents(events ...eventstore.EventReader) wm.MailTextWriteModel.AppendEvents(&e.MailTextAddedEvent) case *org.MailTextChangedEvent: wm.MailTextWriteModel.AppendEvents(&e.MailTextChangedEvent) + case *org.MailTextRemovedEvent: + wm.MailTextWriteModel.AppendEvents(&e.MailTextRemovedEvent) } } } @@ -41,7 +43,10 @@ func (wm *OrgMailTextWriteModel) Reduce() error { func (wm *OrgMailTextWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). - AggregateIDs(wm.MailTextWriteModel.AggregateID) + AggregateIDs(wm.MailTextWriteModel.AggregateID). + EventTypes(org.MailTextAddedEventType, + org.MailTextChangedEventType, + org.MailTextRemovedEventType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } @@ -50,6 +55,7 @@ func (wm *OrgMailTextWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *OrgMailTextWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mailTextType, language, title, @@ -81,7 +87,7 @@ func (wm *OrgMailTextWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewMailTextChangedEvent(ctx, mailTextType, language, changes) + changedEvent, err := org.NewMailTextChangedEvent(ctx, aggregate, mailTextType, language, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_org_iam.go b/internal/v2/command/org_policy_org_iam.go index ff50710b06..9a35250f1f 100644 --- a/internal/v2/command/org_policy_org_iam.go +++ b/internal/v2/command/org_policy_org_iam.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/org" @@ -11,33 +12,30 @@ import ( func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, resourceOwner string, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { addedPolicy := NewORGOrgIAMPolicyWriteModel(resourceOwner) orgAgg := OrgAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel) - err := r.addOrgIAMPolicy(ctx, orgAgg, addedPolicy, policy) + event, err := r.addOrgIAMPolicy(ctx, orgAgg, addedPolicy, policy) if err != nil { return nil, err } - if addedPolicy.State == domain.PolicyStateActive { - return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-5M0ds", "Errors.Org.OrgIAMPolicy.AlreadyExists") - } - orgAgg.PushEvents(org.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return orgWriteModelToOrgIAMPolicy(addedPolicy), nil } -func (r *CommandSide) addOrgIAMPolicy(ctx context.Context, orgAgg *org.Aggregate, addedPolicy *ORGOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) error { +func (r *CommandSide) addOrgIAMPolicy(ctx context.Context, orgAgg *eventstore.Aggregate, addedPolicy *ORGOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) (eventstore.EventPusher, error) { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return err + return nil, err } if addedPolicy.State == domain.PolicyStateActive { - return caos_errs.ThrowAlreadyExists(nil, "ORG-1M8ds", "Errors.Org.OrgIAMPolicy.AlreadyExists") + return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-1M8ds", "Errors.Org.OrgIAMPolicy.AlreadyExists") } - orgAgg.PushEvents(org.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) - return nil + return org.NewOrgIAMPolicyAddedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain), nil } func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, resourceOwner string, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { @@ -49,19 +47,20 @@ func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, resourceOwner stri return nil, caos_errs.ThrowNotFound(nil, "ORG-2N9sd", "Errors.Org.OrgIAMPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-3M9ds", "Errors.Org.LabelPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return orgWriteModelToOrgIAMPolicy(existingPolicy), nil } @@ -75,9 +74,8 @@ func (r *CommandSide) RemoveOrgIAMPolicy(ctx context.Context, orgID string) erro } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) - orgAgg.PushEvents(org.NewOrgIAMPolicyRemovedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewOrgIAMPolicyRemovedEvent(ctx, orgAgg)) + return err } func (r *CommandSide) getOrgIAMPolicy(ctx context.Context, orgID string) (*domain.OrgIAMPolicy, error) { diff --git a/internal/v2/command/org_policy_org_iam_model.go b/internal/v2/command/org_policy_org_iam_model.go index 41b3cffb38..8cd18f3f1f 100644 --- a/internal/v2/command/org_policy_org_iam_model.go +++ b/internal/v2/command/org_policy_org_iam_model.go @@ -30,6 +30,8 @@ func (wm *ORGOrgIAMPolicyWriteModel) AppendEvents(events ...eventstore.EventRead wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) case *org.OrgIAMPolicyChangedEvent: wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyChangedEvent) + case *org.OrgIAMPolicyRemovedEvent: + wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyRemovedEvent) } } } @@ -41,10 +43,16 @@ func (wm *ORGOrgIAMPolicyWriteModel) Reduce() error { func (wm *ORGOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(org.OrgIAMPolicyAddedEventType, + org.OrgIAMPolicyChangedEventType, + org.OrgIAMPolicyRemovedEventType) } -func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*org.OrgIAMPolicyChangedEvent, bool) { +func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userLoginMustBeDomain bool) (*org.OrgIAMPolicyChangedEvent, bool) { changes := make([]policy.OrgIAMPolicyChanges, 0) if wm.UserLoginMustBeDomain != userLoginMustBeDomain { changes = append(changes, policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain)) @@ -52,7 +60,7 @@ func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLo if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewOrgIAMPolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewOrgIAMPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_password_age.go b/internal/v2/command/org_policy_password_age.go index b6c6f5dfdf..60f034f033 100644 --- a/internal/v2/command/org_policy_password_age.go +++ b/internal/v2/command/org_policy_password_age.go @@ -19,13 +19,14 @@ func (r *CommandSide) AddPasswordAgePolicy(ctx context.Context, resourceOwner st } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewPasswordAgePolicyAddedEvent(ctx, orgAgg, policy.ExpireWarnDays, policy.MaxAgeDays)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordAgePolicy(&addedPolicy.PasswordAgePolicyWriteModel), nil } @@ -39,19 +40,20 @@ func (r *CommandSide) ChangePasswordAgePolicy(ctx context.Context, resourceOwner return nil, caos_errs.ThrowNotFound(nil, "ORG-0oPew", "Errors.Org.PasswordAgePolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.ExpireWarnDays, policy.MaxAgeDays) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-dsgjR", "Errors.ORg.LabelPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordAgePolicy(&existingPolicy.PasswordAgePolicyWriteModel), nil } @@ -65,6 +67,6 @@ func (r *CommandSide) RemovePasswordAgePolicy(ctx context.Context, orgID string) return caos_errs.ThrowNotFound(nil, "ORG-Dgs1g", "Errors.Org.PasswordAgePolicy.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordAgePolicyRemovedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewPasswordAgePolicyRemovedEvent(ctx, orgAgg)) + return err } diff --git a/internal/v2/command/org_policy_password_age_model.go b/internal/v2/command/org_policy_password_age_model.go index 5e5df99ece..08c6745cc5 100644 --- a/internal/v2/command/org_policy_password_age_model.go +++ b/internal/v2/command/org_policy_password_age_model.go @@ -43,10 +43,18 @@ func (wm *OrgPasswordAgePolicyWriteModel) Reduce() error { func (wm *OrgPasswordAgePolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes( + org.PasswordAgePolicyAddedEventType, + org.PasswordAgePolicyChangedEventType, + org.PasswordAgePolicyRemovedEventType) } -func (wm *OrgPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) (*org.PasswordAgePolicyChangedEvent, bool) { +func (wm *OrgPasswordAgePolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + expireWarnDays, + maxAgeDays uint64) (*org.PasswordAgePolicyChangedEvent, bool) { changes := make([]policy.PasswordAgePolicyChanges, 0) if wm.ExpireWarnDays != expireWarnDays { changes = append(changes, policy.ChangeExpireWarnDays(expireWarnDays)) @@ -57,7 +65,7 @@ func (wm *OrgPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, e if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewPasswordAgePolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewPasswordAgePolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_password_complexity.go b/internal/v2/command/org_policy_password_complexity.go index 52e11c90fd..452b12205e 100644 --- a/internal/v2/command/org_policy_password_complexity.go +++ b/internal/v2/command/org_policy_password_complexity.go @@ -34,13 +34,23 @@ func (r *CommandSide) AddPasswordComplexityPolicy(ctx context.Context, resourceO } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents( + ctx, + org.NewPasswordComplexityPolicyAddedEvent( + ctx, + orgAgg, + policy.MinLength, + policy.HasLowercase, + policy.HasUppercase, + policy.HasNumber, + policy.HasSymbol)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordComplexityPolicy(&addedPolicy.PasswordComplexityPolicyWriteModel), nil } @@ -58,18 +68,20 @@ func (r *CommandSide) ChangePasswordComplexityPolicy(ctx context.Context, resour return nil, caos_errs.ThrowNotFound(nil, "ORG-Dgs3g", "Errors.Org.PasswordComplexityPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-DAs21", "Errors.Org.PasswordComplexityPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordComplexityPolicy(&existingPolicy.PasswordComplexityPolicyWriteModel), nil } @@ -83,6 +95,6 @@ func (r *CommandSide) RemovePasswordComplexityPolicy(ctx context.Context, orgID return caos_errs.ThrowNotFound(nil, "ORG-ADgs2", "Errors.Org.PasswordComplexityPolicy.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordComplexityPolicyRemovedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + _, err = r.eventstore.PushEvents(ctx, org.NewPasswordComplexityPolicyRemovedEvent(ctx, orgAgg)) + return err } diff --git a/internal/v2/command/org_policy_password_complexity_model.go b/internal/v2/command/org_policy_password_complexity_model.go index ba0aae8cea..8739d9857a 100644 --- a/internal/v2/command/org_policy_password_complexity_model.go +++ b/internal/v2/command/org_policy_password_complexity_model.go @@ -43,11 +43,15 @@ func (wm *OrgPasswordComplexityPolicyWriteModel) Reduce() error { func (wm *OrgPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(org.PasswordComplexityPolicyAddedEventType, + org.PasswordComplexityPolicyChangedEventType, + org.PasswordComplexityPolicyRemovedEventType) } func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, minLength uint64, hasLowercase, hasUppercase, @@ -74,7 +78,7 @@ func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewPasswordComplexityPolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewPasswordComplexityPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/org_policy_password_lockout.go b/internal/v2/command/org_policy_password_lockout.go index c07635e35f..7ececefa51 100644 --- a/internal/v2/command/org_policy_password_lockout.go +++ b/internal/v2/command/org_policy_password_lockout.go @@ -2,7 +2,6 @@ package command import ( "context" - caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/org" @@ -19,13 +18,14 @@ func (r *CommandSide) AddPasswordLockoutPolicy(ctx context.Context, resourceOwne } orgAgg := OrgAggregateFromWriteModel(&addedPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyAddedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordLockoutPolicy(&addedPolicy.PasswordLockoutPolicyWriteModel), nil } @@ -39,19 +39,20 @@ func (r *CommandSide) ChangePasswordLockoutPolicy(ctx context.Context, resourceO return nil, caos_errs.ThrowNotFound(nil, "ORG-ADfs1", "Errors.Org.PasswordLockoutPolicy.NotFound") } - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures) + orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.MaxAttempts, policy.ShowLockOutFailures) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-4M9vs", "Errors.Org.PasswordLockoutPolicy.NotChanged") } - orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel) - orgAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPolicy, pushedEvents...) if err != nil { return nil, err } - return writeModelToPasswordLockoutPolicy(&existingPolicy.PasswordLockoutPolicyWriteModel), nil } @@ -65,6 +66,7 @@ func (r *CommandSide) RemovePasswordLockoutPolicy(ctx context.Context, orgID str return caos_errs.ThrowNotFound(nil, "ORG-D4zuz", "Errors.Org.PasswordLockoutPolicy.NotFound") } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.WriteModel) - orgAgg.PushEvents(org.NewPasswordLockoutPolicyRemovedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + + _, err = r.eventstore.PushEvents(ctx, org.NewPasswordLockoutPolicyRemovedEvent(ctx, orgAgg)) + return err } diff --git a/internal/v2/command/org_policy_password_lockout_model.go b/internal/v2/command/org_policy_password_lockout_model.go index b3a78f183b..29d8eea9b9 100644 --- a/internal/v2/command/org_policy_password_lockout_model.go +++ b/internal/v2/command/org_policy_password_lockout_model.go @@ -30,8 +30,8 @@ func (wm *OrgPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore. wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) case *org.PasswordLockoutPolicyChangedEvent: wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) - case *org.PasswordComplexityPolicyRemovedEvent: - wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyRemovedEvent) + case *org.PasswordLockoutPolicyRemovedEvent: + wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyRemovedEvent) } } } @@ -43,10 +43,17 @@ func (wm *OrgPasswordLockoutPolicyWriteModel) Reduce() error { func (wm *OrgPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(org.PasswordLockoutPolicyAddedEventType, + org.PasswordLockoutPolicyChangedEventType, + org.PasswordLockoutPolicyRemovedEventType) } -func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) (*org.PasswordLockoutPolicyChangedEvent, bool) { +func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + maxAttempts uint64, + showLockoutFailure bool) (*org.PasswordLockoutPolicyChangedEvent, bool) { changes := make([]policy.PasswordLockoutPolicyChanges, 0) if wm.MaxAttempts != maxAttempts { changes = append(changes, policy.ChangeMaxAttempts(maxAttempts)) @@ -57,7 +64,7 @@ func (wm *OrgPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Contex if len(changes) == 0 { return nil, false } - changedEvent, err := org.NewPasswordLockoutPolicyChangedEvent(ctx, changes) + changedEvent, err := org.NewPasswordLockoutPolicyChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false } diff --git a/internal/v2/command/project.go b/internal/v2/command/project.go index 983dc7fed3..153aec374d 100644 --- a/internal/v2/command/project.go +++ b/internal/v2/command/project.go @@ -3,27 +3,29 @@ package command import ( "context" "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore/v2" - caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/project" ) func (r *CommandSide) AddProject(ctx context.Context, project *domain.Project, resourceOwner, ownerUserID string) (_ *domain.Project, err error) { - projectAgg, addedProject, err := r.addProject(ctx, project, resourceOwner, ownerUserID) + events, addedProject, err := r.addProject(ctx, project, resourceOwner, ownerUserID) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedProject, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedProject, pushedEvents...) if err != nil { return nil, err } - return projectWriteModelToProject(addedProject), nil } -func (r *CommandSide) addProject(ctx context.Context, projectAdd *domain.Project, resourceOwner, ownerUserID string) (_ *project.Aggregate, _ *ProjectWriteModel, err error) { +func (r *CommandSide) addProject(ctx context.Context, projectAdd *domain.Project, resourceOwner, ownerUserID string) (_ []eventstore.EventPusher, _ *ProjectWriteModel, err error) { if !projectAdd.IsValid() { return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-IOVCC", "Errors.Project.Invalid") } @@ -42,11 +44,11 @@ func (r *CommandSide) addProject(ctx context.Context, projectAdd *domain.Project if iam.GlobalOrgID == resourceOwner { projectRole = domain.RoleProjectOwnerGlobal } - projectAgg.PushEvents( - project.NewProjectAddedEvent(ctx, projectAdd.Name, resourceOwner), - project.NewProjectMemberAddedEvent(ctx, ownerUserID, projectRole), - ) - return projectAgg, addedProject, nil + events := []eventstore.EventPusher{ + project.NewProjectAddedEvent(ctx, projectAgg, projectAdd.Name), + project.NewProjectMemberAddedEvent(ctx, projectAgg, ownerUserID, projectRole), + } + return events, addedProject, nil } func (r *CommandSide) getProjectByID(ctx context.Context, projectID, resourceOwner string) (*domain.Project, error) { @@ -84,21 +86,22 @@ func (r *CommandSide) ChangeProject(ctx context.Context, projectChange *domain.P return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } - changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, existingProject.ResourceOwner, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck) + projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) + changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, projectAgg, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck) if err != nil { return nil, err } if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0fs", "Errors.NoChangesFound") } - projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - projectAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingProject, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingProject, pushedEvents...) if err != nil { return nil, err } - return projectWriteModelToProject(existingProject), nil } @@ -119,9 +122,8 @@ func (r *CommandSide) DeactivateProject(ctx context.Context, projectID string, r } projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - projectAgg.PushEvents(project.NewProjectDeactivatedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, existingProject, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewProjectDeactivatedEvent(ctx, projectAgg)) + return err } func (r *CommandSide) ReactivateProject(ctx context.Context, projectID string, resourceOwner string) error { @@ -141,9 +143,8 @@ func (r *CommandSide) ReactivateProject(ctx context.Context, projectID string, r } projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - projectAgg.PushEvents(project.NewProjectReactivatedEvent(ctx)) - - return r.eventstore.PushAggregate(ctx, existingProject, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewProjectReactivatedEvent(ctx, projectAgg)) + return err } func (r *CommandSide) RemoveProject(ctx context.Context, projectID, resourceOwner string, cascadingUserGrantIDs ...string) error { @@ -158,22 +159,21 @@ func (r *CommandSide) RemoveProject(ctx context.Context, projectID, resourceOwne if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } - - aggregates := make([]eventstore.Aggregater, 0) projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - projectAgg.PushEvents(project.NewProjectRemovedEvent(ctx, existingProject.Name, existingProject.ResourceOwner)) - aggregates = append(aggregates, projectAgg) + events := []eventstore.EventPusher{ + project.NewProjectRemovedEvent(ctx, projectAgg, existingProject.Name), + } for _, grantID := range cascadingUserGrantIDs { - grantAgg, _, err := r.removeUserGrant(ctx, grantID, "", true) + event, err := r.removeUserGrant(ctx, grantID, "", true) if err != nil { logging.LogWithFields("COMMAND-b8Djf", "usergrantid", grantID).WithError(err).Warn("could not cascade remove user grant") continue } - aggregates = append(aggregates, grantAgg) + events = append(events, event) } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/project_application.go b/internal/v2/command/project_application.go index 09f5d12f1e..c3b87ac4fd 100644 --- a/internal/v2/command/project_application.go +++ b/internal/v2/command/project_application.go @@ -2,7 +2,6 @@ package command import ( "context" - caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/project" @@ -24,15 +23,16 @@ func (r *CommandSide) ChangeApplication(ctx context.Context, projectID string, a return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2m8vx", "Errors.NoChangesFound") } projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel) - projectAgg.PushEvents( - project.NewApplicationChangedEvent(ctx, appChange.GetAppID(), existingApp.Name, appChange.GetApplicationName(), projectID), - ) - - err = r.eventstore.PushAggregate(ctx, existingApp, projectAgg) + pushedEvents, err := r.eventstore.PushEvents( + ctx, + project.NewApplicationChangedEvent(ctx, projectAgg, appChange.GetAppID(), existingApp.Name, appChange.GetApplicationName(), projectID)) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingApp, pushedEvents...) if err != nil { return nil, err } - return applicationWriteModelToApplication(existingApp), nil } @@ -52,9 +52,8 @@ func (r *CommandSide) DeactivateApplication(ctx context.Context, projectID, appI return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dsh35", "Errors.Project.App.NotActive") } projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel) - projectAgg.PushEvents(project.NewApplicationDeactivatedEvent(ctx, appID)) - - return r.eventstore.PushAggregate(ctx, existingApp, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewApplicationDeactivatedEvent(ctx, projectAgg, appID)) + return err } func (r *CommandSide) ReactivateApplication(ctx context.Context, projectID, appID, resourceOwner string) error { @@ -73,9 +72,9 @@ func (r *CommandSide) ReactivateApplication(ctx context.Context, projectID, appI return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1n8cM", "Errors.Project.App.NotInactive") } projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel) - projectAgg.PushEvents(project.NewApplicationReactivatedEvent(ctx, appID)) - return r.eventstore.PushAggregate(ctx, existingApp, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewApplicationReactivatedEvent(ctx, projectAgg, appID)) + return err } func (r *CommandSide) RemoveApplication(ctx context.Context, projectID, appID, resourceOwner string) error { @@ -91,9 +90,9 @@ func (r *CommandSide) RemoveApplication(ctx context.Context, projectID, appID, r return caos_errs.ThrowNotFound(nil, "COMMAND-0po9s", "Errors.Project.App.NotExisting") } projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel) - projectAgg.PushEvents(project.NewApplicationRemovedEvent(ctx, appID, existingApp.Name, projectID)) - return r.eventstore.PushAggregate(ctx, existingApp, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewApplicationRemovedEvent(ctx, projectAgg, appID, existingApp.Name, projectID)) + return err } func (r *CommandSide) getApplicationWriteModel(ctx context.Context, projectID, appID, resourceOwner string) (*ApplicationWriteModel, error) { diff --git a/internal/v2/command/project_application_model.go b/internal/v2/command/project_application_model.go index 9ae62d391b..31c9288b1f 100644 --- a/internal/v2/command/project_application_model.go +++ b/internal/v2/command/project_application_model.go @@ -96,13 +96,13 @@ func (wm *ApplicationWriteModel) Reduce() error { func (wm *ApplicationWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) - //EventTypes( - // project.ApplicationAddedType, - // project.ApplicationChangedType, - // project.ApplicationDeactivatedType, - // project.ApplicationReactivatedType, - // project.ApplicationRemovedType, - // project.ProjectRemovedType, - //) + ResourceOwner(wm.ResourceOwner). + EventTypes( + project.ApplicationAddedType, + project.ApplicationChangedType, + project.ApplicationDeactivatedType, + project.ApplicationReactivatedType, + project.ApplicationRemovedType, + project.ProjectRemovedType, + ) } diff --git a/internal/v2/command/project_application_oidc.go b/internal/v2/command/project_application_oidc.go index 92ba61e9b5..c63ba33665 100644 --- a/internal/v2/command/project_application_oidc.go +++ b/internal/v2/command/project_application_oidc.go @@ -3,6 +3,7 @@ package command import ( "context" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/project" ) @@ -14,43 +15,49 @@ func (r *CommandSide) AddOIDCApplication(ctx context.Context, application *domai } addedApplication := NewOIDCApplicationWriteModel(application.AggregateID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&addedApplication.WriteModel) - stringPw, err := r.addOIDCApplication(ctx, projectAgg, project, application, resourceOwner) + events, stringPw, err := r.addOIDCApplication(ctx, projectAgg, project, application, resourceOwner) if err != nil { return nil, err } addedApplication.AppID = application.AppID - err = r.eventstore.PushAggregate(ctx, addedApplication, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedApplication, pushedEvents...) if err != nil { return nil, err } - result := oidcWriteModelToOIDCConfig(addedApplication) result.ClientSecretString = stringPw result.FillCompliance() return result, nil } -func (r *CommandSide) addOIDCApplication(ctx context.Context, projectAgg *project.Aggregate, proj *domain.Project, oidcApp *domain.OIDCApp, resourceOwner string) (stringPW string, err error) { +func (r *CommandSide) addOIDCApplication(ctx context.Context, projectAgg *eventstore.Aggregate, proj *domain.Project, oidcApp *domain.OIDCApp, resourceOwner string) (events []eventstore.EventPusher, stringPW string, err error) { if !oidcApp.IsValid() { - return "", caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Application.Invalid") + return nil, "", caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Application.Invalid") } oidcApp.AppID, err = r.idGenerator.Next() if err != nil { - return "", err + return nil, "", err } - projectAgg.PushEvents(project.NewApplicationAddedEvent(ctx, oidcApp.AppID, oidcApp.AppName, resourceOwner)) + events = []eventstore.EventPusher{ + project.NewApplicationAddedEvent(ctx, projectAgg, oidcApp.AppID, oidcApp.AppName, resourceOwner), + } var stringPw string err = oidcApp.GenerateNewClientID(r.idGenerator, proj) if err != nil { - return "", err + return nil, "", err } stringPw, err = oidcApp.GenerateClientSecretIfNeeded(r.applicationSecretGenerator) if err != nil { - return "", err + return nil, "", err } - projectAgg.PushEvents(project.NewOIDCConfigAddedEvent(ctx, + events = append(events, project.NewOIDCConfigAddedEvent(ctx, + projectAgg, oidcApp.OIDCVersion, oidcApp.AppID, oidcApp.ClientID, @@ -68,7 +75,7 @@ func (r *CommandSide) addOIDCApplication(ctx context.Context, projectAgg *projec oidcApp.IDTokenUserinfoAssertion, oidcApp.ClockSkew)) - return stringPw, nil + return events, stringPw, nil } func (r *CommandSide) ChangeOIDCApplication(ctx context.Context, oidc *domain.OIDCApp, resourceOwner string) (*domain.OIDCApp, error) { @@ -83,8 +90,10 @@ func (r *CommandSide) ChangeOIDCApplication(ctx context.Context, oidc *domain.OI if existingOIDC.State == domain.AppStateUnspecified || existingOIDC.State == domain.AppStateRemoved { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-2n8uU", "Errors.Project.App.NotExisting") } + projectAgg := ProjectAggregateFromWriteModel(&existingOIDC.WriteModel) changedEvent, hasChanged, err := existingOIDC.NewChangedEvent( ctx, + projectAgg, oidc.AppID, oidc.ClientID, oidc.RedirectUris, @@ -106,13 +115,16 @@ func (r *CommandSide) ChangeOIDCApplication(ctx context.Context, oidc *domain.OI if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1m88i", "Errors.NoChangesFound") } - projectAgg := ProjectAggregateFromWriteModel(&existingOIDC.WriteModel) - projectAgg.PushEvents(changedEvent) - err = r.eventstore.PushAggregate(ctx, existingOIDC, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) if err != nil { return nil, err } + err = AppendAndReduce(existingOIDC, pushedEvents...) + if err != nil { + return nil, err + } + result := oidcWriteModelToOIDCConfig(existingOIDC) result.FillCompliance() return result, nil @@ -136,9 +148,12 @@ func (r *CommandSide) ChangeOIDCApplicationSecret(ctx context.Context, projectID } projectAgg := ProjectAggregateFromWriteModel(&existingOIDC.WriteModel) - projectAgg.PushEvents(project.NewOIDCConfigSecretChangedEvent(ctx, appID, cryptoSecret)) - err = r.eventstore.PushAggregate(ctx, existingOIDC, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, project.NewOIDCConfigSecretChangedEvent(ctx, projectAgg, appID, cryptoSecret)) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingOIDC, pushedEvents...) if err != nil { return nil, err } diff --git a/internal/v2/command/project_application_oidc_model.go b/internal/v2/command/project_application_oidc_model.go index 4904dfbef4..1393ab7efa 100644 --- a/internal/v2/command/project_application_oidc_model.go +++ b/internal/v2/command/project_application_oidc_model.go @@ -201,22 +201,23 @@ func (wm *OIDCApplicationWriteModel) appendChangeOIDCEvent(e *project.OIDCConfig func (wm *OIDCApplicationWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) - //EventTypes( - // project.ApplicationAddedType, - // project.ApplicationChangedType, - // project.ApplicationDeactivatedType, - // project.ApplicationReactivatedType, - // project.ApplicationRemovedType, - // project.OIDCConfigAddedType, - // project.OIDCConfigChangedType, - // project.OIDCConfigSecretChangedType, - // project.ProjectRemovedType, - //) + ResourceOwner(wm.ResourceOwner). + EventTypes( + project.ApplicationAddedType, + project.ApplicationChangedType, + project.ApplicationDeactivatedType, + project.ApplicationReactivatedType, + project.ApplicationRemovedType, + project.OIDCConfigAddedType, + project.OIDCConfigChangedType, + project.OIDCConfigSecretChangedType, + project.ProjectRemovedType, + ) } func (wm *OIDCApplicationWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, appID, clientID string, redirectURIS, @@ -281,7 +282,7 @@ func (wm *OIDCApplicationWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false, nil } - changeEvent, err := project.NewOIDCConfigChangedEvent(ctx, appID, changes) + changeEvent, err := project.NewOIDCConfigChangedEvent(ctx, aggregate, appID, changes) if err != nil { return nil, false, err } diff --git a/internal/v2/command/project_grant.go b/internal/v2/command/project_grant.go index 53a8737196..433d5fd4d6 100644 --- a/internal/v2/command/project_grant.go +++ b/internal/v2/command/project_grant.go @@ -29,17 +29,16 @@ func (r *CommandSide) AddProjectGrant(ctx context.Context, grant *domain.Project } addedGrant := NewProjectGrantWriteModel(grant.GrantID, grant.AggregateID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&addedGrant.WriteModel) - - projectAgg.PushEvents(project.NewGrantAddedEvent(ctx, grant.GrantID, grant.GrantedOrgID, grant.AggregateID, grant.RoleKeys)) - + pushedEvents, err := r.eventstore.PushEvents( + ctx, + project.NewGrantAddedEvent(ctx, projectAgg, grant.GrantID, grant.GrantedOrgID, grant.AggregateID, grant.RoleKeys)) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedGrant, projectAgg) + err = AppendAndReduce(addedGrant, pushedEvents...) if err != nil { return nil, err } - return projectGrantWriteModelToProjectGrant(addedGrant), nil } @@ -61,45 +60,48 @@ func (r *CommandSide) ChangeProjectGrant(ctx context.Context, grant *domain.Proj return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-0o0pL", "Errors.NoChangesFoundc") } - projectAgg.PushEvents(project.NewGrantChangedEvent(ctx, grant.GrantID, grant.RoleKeys)) + events := []eventstore.EventPusher{ + project.NewGrantChangedEvent(ctx, projectAgg, grant.GrantID, grant.RoleKeys), + } removedRoles := domain.GetRemovedRoles(existingGrant.RoleKeys, grant.RoleKeys) if len(removedRoles) == 0 { - err = r.eventstore.PushAggregate(ctx, existingGrant, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingGrant, pushedEvents...) if err != nil { return nil, err } return projectGrantWriteModelToProjectGrant(existingGrant), nil } - aggregates := make([]eventstore.Aggregater, 0) - aggregates = append(aggregates, projectAgg) for _, userGrantID := range cascadeUserGrantIDs { - grantAgg, _, err := r.removeRoleFromUserGrant(ctx, userGrantID, removedRoles, true) + event, err := r.removeRoleFromUserGrant(ctx, userGrantID, removedRoles, true) if err != nil { continue } - aggregates = append(aggregates, grantAgg) + events = append(events, event) } - resultEvents, err := r.eventstore.PushAggregates(ctx, aggregates...) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) if err != nil { return nil, err } - existingGrant.AppendEvents(resultEvents...) - err = existingGrant.Reduce() + err = AppendAndReduce(existingGrant, pushedEvents...) if err != nil { return nil, err } return projectGrantWriteModelToProjectGrant(existingGrant), nil } -func (r *CommandSide) removeRoleFromProjectGrant(ctx context.Context, projectAgg *project.Aggregate, projectID, projectGrantID, roleKey string, cascade bool) (_ *ProjectGrantWriteModel, err error) { +func (r *CommandSide) removeRoleFromProjectGrant(ctx context.Context, projectAgg *eventstore.Aggregate, projectID, projectGrantID, roleKey string, cascade bool) (_ eventstore.EventPusher, _ *ProjectGrantWriteModel, err error) { existingProjectGrant, err := r.projectGrantWriteModelByID(ctx, projectID, projectGrantID, "") if err != nil { - return nil, err + return nil, nil, err } if existingProjectGrant.State == domain.ProjectGrantStateUnspecified || existingProjectGrant.State == domain.ProjectGrantStateRemoved { - return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.Grant.NotFound") + return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.Grant.NotFound") } keyExists := false for i, key := range existingProjectGrant.RoleKeys { @@ -112,21 +114,15 @@ func (r *CommandSide) removeRoleFromProjectGrant(ctx context.Context, projectAgg } } if !keyExists { - return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5m8g9", "Errors.Project.Grant.RoleKeyNotFound") + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5m8g9", "Errors.Project.Grant.RoleKeyNotFound") } changedProjectGrant := NewProjectGrantWriteModel(projectGrantID, projectID, existingProjectGrant.ResourceOwner) - if !cascade { - projectAgg.PushEvents( - project.NewGrantChangedEvent(ctx, projectGrantID, existingProjectGrant.RoleKeys), - ) - } else { - projectAgg.PushEvents( - project.NewGrantCascadeChangedEvent(ctx, projectGrantID, existingProjectGrant.RoleKeys), - ) + if cascade { + return project.NewGrantCascadeChangedEvent(ctx, projectAgg, projectGrantID, existingProjectGrant.RoleKeys), changedProjectGrant, nil } - return changedProjectGrant, nil + return project.NewGrantChangedEvent(ctx, projectAgg, projectGrantID, existingProjectGrant.RoleKeys), changedProjectGrant, nil } func (r *CommandSide) DeactivateProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string) (err error) { @@ -146,8 +142,8 @@ func (r *CommandSide) DeactivateProjectGrant(ctx context.Context, projectID, gra } projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel) - projectAgg.PushEvents(project.NewGrantDeactivateEvent(ctx, grantID)) - return r.eventstore.PushAggregate(ctx, existingGrant, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewGrantDeactivateEvent(ctx, projectAgg, grantID)) + return err } func (r *CommandSide) ReactivateProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string) (err error) { @@ -166,8 +162,8 @@ func (r *CommandSide) ReactivateProjectGrant(ctx context.Context, projectID, gra return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-47fu8", "Errors.Project.Grant.NotInactive") } projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel) - projectAgg.PushEvents(project.NewGrantReactivatedEvent(ctx, grantID)) - return r.eventstore.PushAggregate(ctx, existingGrant, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewGrantReactivatedEvent(ctx, projectAgg, grantID)) + return err } func (r *CommandSide) RemoveProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string, cascadeUserGrantIDs ...string) (err error) { @@ -182,20 +178,19 @@ func (r *CommandSide) RemoveProjectGrant(ctx context.Context, projectID, grantID if err != nil { return err } - aggregates := make([]eventstore.Aggregater, 0) + events := make([]eventstore.EventPusher, 0) projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel) - projectAgg.PushEvents(project.NewGrantRemovedEvent(ctx, grantID, existingGrant.GrantedOrgID, projectID)) - aggregates = append(aggregates, projectAgg) + events = append(events, project.NewGrantRemovedEvent(ctx, projectAgg, grantID, existingGrant.GrantedOrgID, projectID)) for _, userGrantID := range cascadeUserGrantIDs { - grantAgg, _, err := r.removeUserGrant(ctx, userGrantID, "", true) + event, err := r.removeUserGrant(ctx, userGrantID, "", true) if err != nil { logging.LogWithFields("COMMAND-3m8sG", "usergrantid", grantID).WithError(err).Warn("could not cascade remove user grant") continue } - aggregates = append(aggregates, grantAgg) + events = append(events, event) } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/project_grant_member.go b/internal/v2/command/project_grant_member.go index 60c0f64006..0f366ff824 100644 --- a/internal/v2/command/project_grant_member.go +++ b/internal/v2/command/project_grant_member.go @@ -28,9 +28,13 @@ func (r *CommandSide) AddProjectGrantMember(ctx context.Context, member *domain. return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-16dVN", "Errors.Project.Member.AlreadyExists") } projectAgg := ProjectAggregateFromWriteModel(&addedMember.WriteModel) - projectAgg.PushEvents(project.NewProjectGrantMemberAddedEvent(ctx, member.AggregateID, member.UserID, member.GrantID, member.Roles...)) - - err = r.eventstore.PushAggregate(ctx, addedMember, projectAgg) + pushedEvents, err := r.eventstore.PushEvents( + ctx, + project.NewProjectGrantMemberAddedEvent(ctx, projectAgg, member.AggregateID, member.UserID, member.GrantID, member.Roles...)) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedMember, pushedEvents...) if err != nil { return nil, err } @@ -55,15 +59,14 @@ func (r *CommandSide) ChangeProjectGrantMember(ctx context.Context, member *doma return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-2n8vx", "Errors.Project.Member.RolesNotChanged") } projectAgg := ProjectAggregateFromWriteModel(&existingMember.WriteModel) - projectAgg.PushEvents(project.NewProjectGrantMemberChangedEvent(ctx, member.UserID, member.GrantID, member.Roles...)) - - events, err := r.eventstore.PushAggregates(ctx, projectAgg) + pushedEvents, err := r.eventstore.PushEvents( + ctx, + project.NewProjectGrantMemberChangedEvent(ctx, projectAgg, member.UserID, member.GrantID, member.Roles...)) if err != nil { return nil, err } - - existingMember.AppendEvents(events...) - if err = existingMember.Reduce(); err != nil { + err = AppendAndReduce(existingMember, pushedEvents...) + if err != nil { return nil, err } @@ -77,9 +80,8 @@ func (r *CommandSide) RemoveProjectGrantMember(ctx context.Context, projectID, u } projectAgg := ProjectAggregateFromWriteModel(&m.WriteModel) - projectAgg.PushEvents(project.NewProjectGrantMemberRemovedEvent(ctx, projectID, userID, grantID)) - - return r.eventstore.PushAggregate(ctx, m, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewProjectGrantMemberRemovedEvent(ctx, projectAgg, projectID, userID, grantID)) + return err } func (r *CommandSide) projectGrantMemberWriteModelByID(ctx context.Context, projectID, userID, grantID string) (member *ProjectGrantMemberWriteModel, err error) { diff --git a/internal/v2/command/project_grant_member_model.go b/internal/v2/command/project_grant_member_model.go index f7d03861d3..128ed067f5 100644 --- a/internal/v2/command/project_grant_member_model.go +++ b/internal/v2/command/project_grant_member_model.go @@ -49,6 +49,8 @@ func (wm *ProjectGrantMemberWriteModel) AppendEvents(events ...eventstore.EventR continue } wm.WriteModel.AppendEvents(e) + case *project.ProjectRemovedEvent: + wm.WriteModel.AppendEvents(e) } } } @@ -72,11 +74,11 @@ func (wm *ProjectGrantMemberWriteModel) Reduce() error { func (wm *ProjectGrantMemberWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). - AggregateIDs(wm.AggregateID) - //EventTypes( - // project.GrantMemberAddedType, - // project.GrantMemberChangedType, - // project.GrantMemberRemovedType, - // project.GrantRemovedType, - // project.ProjectRemovedType) + AggregateIDs(wm.AggregateID). + EventTypes( + project.GrantMemberAddedType, + project.GrantMemberChangedType, + project.GrantMemberRemovedType, + project.GrantRemovedType, + project.ProjectRemovedType) } diff --git a/internal/v2/command/project_member.go b/internal/v2/command/project_member.go index 24b5ed351e..23c7f2ed41 100644 --- a/internal/v2/command/project_member.go +++ b/internal/v2/command/project_member.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "reflect" "github.com/caos/zitadel/internal/errors" @@ -14,12 +15,16 @@ import ( func (r *CommandSide) AddProjectMember(ctx context.Context, member *domain.Member, resourceOwner string) (*domain.Member, error) { addedMember := NewProjectMemberWriteModel(member.AggregateID, member.UserID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&addedMember.WriteModel) - err := r.addProjectMember(ctx, projectAgg, addedMember, member) + event, err := r.addProjectMember(ctx, projectAgg, addedMember, member) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedMember, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedMember, pushedEvents...) if err != nil { return nil, err } @@ -27,28 +32,26 @@ func (r *CommandSide) AddProjectMember(ctx context.Context, member *domain.Membe return memberWriteModelToMember(&addedMember.MemberWriteModel), nil } -func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *project.Aggregate, addedMember *ProjectMemberWriteModel, member *domain.Member) error { +func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *eventstore.Aggregate, addedMember *ProjectMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) { //TODO: check if roles valid if !member.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid") } err := r.checkUserExists(ctx, addedMember.UserID, "") if err != nil { - return err + return nil, err } err = r.eventstore.FilterToQueryReducer(ctx, addedMember) if err != nil { - return err + return nil, err } if addedMember.State == domain.MemberStateActive { - return errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists") + return nil, errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists") } - projectAgg.PushEvents(project.NewProjectMemberAddedEvent(ctx, projectAgg.ID(), member.UserID, member.Roles...)) - - return nil + return project.NewProjectMemberAddedEvent(ctx, projectAgg, member.UserID, member.Roles...), nil } //ChangeProjectMember updates an existing member @@ -68,15 +71,13 @@ func (r *CommandSide) ChangeProjectMember(ctx context.Context, member *domain.Me return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged") } projectAgg := ProjectAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) - projectAgg.PushEvents(project.NewProjectMemberChangedEvent(ctx, member.UserID, member.Roles...)) - - events, err := r.eventstore.PushAggregates(ctx, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, project.NewProjectMemberChangedEvent(ctx, projectAgg, member.UserID, member.Roles...)) if err != nil { return nil, err } - existingMember.AppendEvents(events...) - if err = existingMember.Reduce(); err != nil { + err = AppendAndReduce(existingMember, pushedEvents...) + if err != nil { return nil, err } @@ -93,9 +94,8 @@ func (r *CommandSide) RemoveProjectMember(ctx context.Context, projectID, userID } projectAgg := ProjectAggregateFromWriteModel(&m.MemberWriteModel.WriteModel) - projectAgg.PushEvents(project.NewProjectMemberRemovedEvent(ctx, projectAgg.ID(), userID)) - - return r.eventstore.PushAggregate(ctx, m, projectAgg) + _, err = r.eventstore.PushEvents(ctx, project.NewProjectMemberRemovedEvent(ctx, projectAgg, userID)) + return err } func (r *CommandSide) projectMemberWriteModelByID(ctx context.Context, projectID, userID, resourceOwner string) (member *ProjectMemberWriteModel, err error) { diff --git a/internal/v2/command/project_member_model.go b/internal/v2/command/project_member_model.go index d17e8f62ea..becfd9b743 100644 --- a/internal/v2/command/project_member_model.go +++ b/internal/v2/command/project_member_model.go @@ -50,5 +50,8 @@ func (wm *ProjectMemberWriteModel) Reduce() error { func (wm *ProjectMemberWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.MemberWriteModel.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(project.MemberAddedType, + project.MemberChangedType, + project.MemberRemovedType) } diff --git a/internal/v2/command/project_model.go b/internal/v2/command/project_model.go index 28dd702663..1a853be8ee 100644 --- a/internal/v2/command/project_model.go +++ b/internal/v2/command/project_model.go @@ -25,10 +25,6 @@ func NewProjectWriteModel(projectID string, resourceOwner string) *ProjectWriteM } } -func (wm *ProjectWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *ProjectWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -67,12 +63,17 @@ func (wm *ProjectWriteModel) Reduce() error { func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(project.ProjectAddedType, + project.ProjectChangedType, + project.ProjectDeactivatedType, + project.ProjectReactivatedType, + project.ProjectRemovedType) } func (wm *ProjectWriteModel) NewChangedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, name string, projectRoleAssertion, projectRoleCheck bool, @@ -94,15 +95,13 @@ func (wm *ProjectWriteModel) NewChangedEvent( if len(changes) == 0 { return nil, false, nil } - changeEvent, err := project.NewProjectChangeEvent(ctx, resourceOwner, oldName, changes) + changeEvent, err := project.NewProjectChangeEvent(ctx, aggregate, oldName, changes) if err != nil { return nil, false, err } return changeEvent, true, nil } -func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *project.Aggregate { - return &project.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion), - } +func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion) } diff --git a/internal/v2/command/project_role.go b/internal/v2/command/project_role.go index 74b74fd317..0c32f848ce 100644 --- a/internal/v2/command/project_role.go +++ b/internal/v2/command/project_role.go @@ -17,9 +17,15 @@ func (r *CommandSide) AddProjectRole(ctx context.Context, projectRole *domain.Pr roleWriteModel := NewProjectRoleWriteModelWithKey(projectRole.Key, projectRole.AggregateID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&roleWriteModel.WriteModel) - r.addProjectRoles(ctx, projectAgg, projectRole.AggregateID, resourceOwner, projectRole) - - err = r.eventstore.PushAggregate(ctx, roleWriteModel, projectAgg) + events, err := r.addProjectRoles(ctx, projectAgg, projectRole.AggregateID, projectRole) + if err != nil { + return nil, err + } + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(roleWriteModel, pushedEvents...) if err != nil { return nil, err } @@ -34,28 +40,32 @@ func (r *CommandSide) BulkAddProjectRole(ctx context.Context, projectID, resourc roleWriteModel := NewProjectRoleWriteModel(projectID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&roleWriteModel.WriteModel) - r.addProjectRoles(ctx, projectAgg, projectID, resourceOwner, projectRoles...) - - return r.eventstore.PushAggregate(ctx, roleWriteModel, projectAgg) -} - -func (r *CommandSide) addProjectRoles(ctx context.Context, projectAgg *project.Aggregate, projectID, resourceOwner string, projectRoles ...*domain.ProjectRole) error { - for _, projectRole := range projectRoles { - if !projectRole.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Invalid") - } - projectAgg.PushEvents( - project.NewRoleAddedEvent( - ctx, - projectRole.Key, - projectRole.DisplayName, - projectRole.Group, - projectID, - ), - ) + events, err := r.addProjectRoles(ctx, projectAgg, projectID, projectRoles...) + if err != nil { + return err } - return nil + _, err = r.eventstore.PushEvents(ctx, events...) + return err +} + +func (r *CommandSide) addProjectRoles(ctx context.Context, projectAgg *eventstore.Aggregate, projectID string, projectRoles ...*domain.ProjectRole) ([]eventstore.EventPusher, error) { + var events []eventstore.EventPusher + for _, projectRole := range projectRoles { + if !projectRole.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Invalid") + } + events = append(events, project.NewRoleAddedEvent( + ctx, + projectAgg, + projectRole.Key, + projectRole.DisplayName, + projectRole.Group, + projectID, + )) + } + + return events, nil } func (r *CommandSide) ChangeProjectRole(ctx context.Context, projectRole *domain.ProjectRole, resourceOwner string) (_ *domain.ProjectRole, err error) { @@ -77,16 +87,19 @@ func (r *CommandSide) ChangeProjectRole(ctx context.Context, projectRole *domain projectAgg := ProjectAggregateFromWriteModel(&existingRole.WriteModel) - changeEvent, changed, err := existingRole.NewProjectRoleChangedEvent(ctx, projectRole.Key, projectRole.DisplayName, projectRole.Group) + changeEvent, changed, err := existingRole.NewProjectRoleChangedEvent(ctx, projectAgg, projectRole.Key, projectRole.DisplayName, projectRole.Group) if err != nil { return nil, err } if !changed { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0cs", "Errors.NoChangesFound") } - projectAgg.PushEvents(changeEvent) - err = r.eventstore.PushAggregate(ctx, existingRole, projectAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changeEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingRole, pushedEvents...) if err != nil { return nil, err } @@ -104,28 +117,30 @@ func (r *CommandSide) RemoveProjectRole(ctx context.Context, projectID, key, res if existingRole.State == domain.ProjectRoleStateUnspecified || existingRole.State == domain.ProjectRoleStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-m9vMf", "Errors.Project.Role.NotExisting") } - aggregates := make([]eventstore.Aggregater, 0) projectAgg := ProjectAggregateFromWriteModel(&existingRole.WriteModel) - projectAgg.PushEvents(project.NewRoleRemovedEvent(ctx, key, projectID)) + events := []eventstore.EventPusher{ + project.NewRoleRemovedEvent(ctx, projectAgg, key, projectID), + } + for _, projectGrantID := range cascadingProjectGrantIds { - _, err = r.removeRoleFromProjectGrant(ctx, projectAgg, projectID, projectGrantID, key, true) + event, _, err := r.removeRoleFromProjectGrant(ctx, projectAgg, projectID, projectGrantID, key, true) if err != nil { logging.LogWithFields("COMMAND-6n77g", "projectgrantid", projectGrantID).WithError(err).Warn("could not cascade remove role from project grant") continue } + events = append(events, event) } - aggregates = append(aggregates, projectAgg) for _, grantID := range cascadeUserGrantIDs { - grantAgg, _, err := r.removeRoleFromUserGrant(ctx, grantID, []string{key}, true) + event, err := r.removeRoleFromUserGrant(ctx, grantID, []string{key}, true) if err != nil { logging.LogWithFields("COMMAND-mK0of", "usergrantid", grantID).WithError(err).Warn("could not cascade remove role on user grant") continue } - aggregates = append(aggregates, grantAgg) + events = append(events, event) } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/project_role_model.go b/internal/v2/command/project_role_model.go index dc54d912a1..9aa03ca46a 100644 --- a/internal/v2/command/project_role_model.go +++ b/internal/v2/command/project_role_model.go @@ -82,20 +82,19 @@ func (wm *ProjectRoleWriteModel) Reduce() error { } func (wm *ProjectRoleWriteModel) Query() *eventstore.SearchQueryBuilder { - //types := []eventstore.EventType{ - // project.RoleAddedType, - // project.RoleChangedType, - // project.RoleRemovedType, - // project.ProjectRemovedType, - //} return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) - //EventTypes(types...) + ResourceOwner(wm.ResourceOwner). + EventTypes( + project.RoleAddedType, + project.RoleChangedType, + project.RoleRemovedType, + project.ProjectRemovedType) } func (wm *ProjectRoleWriteModel) NewProjectRoleChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, key, displayName, group string, @@ -113,7 +112,7 @@ func (wm *ProjectRoleWriteModel) NewProjectRoleChangedEvent( if len(changes) == 0 { return nil, false, nil } - changeEvent, err := project.NewRoleChangedEvent(ctx, changes) + changeEvent, err := project.NewRoleChangedEvent(ctx, aggregate, changes) if err != nil { return nil, false, err } diff --git a/internal/v2/command/setup.go b/internal/v2/command/setup.go index 250ed584fd..1e7154ed88 100644 --- a/internal/v2/command/setup.go +++ b/internal/v2/command/setup.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" @@ -63,16 +64,20 @@ func (r *CommandSide) StartSetup(ctx context.Context, step domain.Step) (*domain if iamWriteModel.SetUpStarted >= step || iamWriteModel.SetUpStarted != iamWriteModel.SetUpDone { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error") } - aggregate := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel).PushEvents(iam_repo.NewSetupStepStartedEvent(ctx, step)) - err = r.eventstore.PushAggregate(ctx, iamWriteModel, aggregate) + aggregate := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel) + pushedEvents, err := r.eventstore.PushEvents(ctx, iam_repo.NewSetupStepStartedEvent(ctx, aggregate, step)) if err != nil { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Grgh1", "Setup start failed") } + err = AppendAndReduce(iamWriteModel, pushedEvents...) + if err != nil { + return nil, err + } logging.LogWithFields("SETUP-fhh21", "step", step).Info("setup step started") return writeModelToIAM(iamWriteModel), nil } -func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider func(*IAMWriteModel) (*iam_repo.Aggregate, error)) error { +func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider func(*IAMWriteModel) ([]eventstore.EventPusher, error)) error { iam, err := r.getIAMWriteModel(ctx) if err != nil && !caos_errs.IsNotFound(err) { return err @@ -80,13 +85,14 @@ func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider if iam.SetUpStarted != step.Step() && iam.SetUpDone+1 != step.Step() { return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dge32", "wrong step") } - iamAgg, err := iamAggregateProvider(iam) + events, err := iamAggregateProvider(iam) if err != nil { return err } - iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, step.Step())) + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + events = append(events, iam_repo.NewSetupStepDoneEvent(ctx, iamAgg, step.Step())) - _, err = r.eventstore.PushAggregates(ctx, iamAgg) + _, err = r.eventstore.PushEvents(ctx, events...) if err != nil { return caos_errs.ThrowPreconditionFailedf(nil, "EVENT-dbG31", "Setup %v failed", step.Step()) } diff --git a/internal/v2/command/setup_step1.go b/internal/v2/command/setup_step1.go index aff1001220..f2406b5a7e 100644 --- a/internal/v2/command/setup_step1.go +++ b/internal/v2/command/setup_step1.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/logging" @@ -10,7 +11,6 @@ import ( "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/project" ) const ( @@ -84,10 +84,11 @@ type OIDCApp struct { } func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error { + var events []eventstore.EventPusher iamWriteModel := NewIAMWriteModel() iamAgg := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel) //create default login policy - err := r.addDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(), + loginPolicyEvent, err := r.addDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(), &domain.LoginPolicy{ AllowUsernamePassword: step1.DefaultLoginPolicy.AllowUsernamePassword, AllowRegister: step1.DefaultLoginPolicy.AllowRegister, @@ -96,11 +97,11 @@ func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error { if err != nil { return err } + events = append(events, loginPolicyEvent) logging.Log("SETUP-sd2hj").Info("default login policy set up") //create orgs - aggregates := make([]eventstore.Aggregater, 0) for _, organisation := range step1.Orgs { - orgAgg, userAgg, orgMemberAgg, claimedUsers, err := r.setUpOrg(ctx, + orgAgg, humanWriteModel, _, setUpOrgEvents, err := r.setUpOrg(ctx, &domain.Org{ Name: organisation.Name, Domains: []*domain.OrgDomain{{Domain: organisation.Domain}}, @@ -122,66 +123,70 @@ func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error { if err != nil { return err } - logging.LogWithFields("SETUP-Gdsfg", "id", orgAgg.ID(), "name", organisation.Name).Info("org set up") + events = append(events, setUpOrgEvents...) + logging.LogWithFields("SETUP-Gdsfg", "id", orgAgg.ID, "name", organisation.Name).Info("org set up") if organisation.OrgIamPolicy { - err = r.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID()), &domain.OrgIAMPolicy{UserLoginMustBeDomain: false}) + orgIAMPolicyEvent, err := r.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID), &domain.OrgIAMPolicy{UserLoginMustBeDomain: false}) if err != nil { return err } + events = append(events, orgIAMPolicyEvent) } - aggregates = append(aggregates, orgAgg, userAgg, orgMemberAgg) - aggregates = append(aggregates, claimedUsers...) if organisation.Name == step1.GlobalOrg { - err = r.setGlobalOrg(ctx, iamAgg, iamWriteModel, orgAgg.ID()) + globalOrgEvent, err := r.setGlobalOrg(ctx, iamAgg, iamWriteModel, orgAgg.ID) if err != nil { return err } + events = append(events, globalOrgEvent) logging.Log("SETUP-BDn52").Info("global org set") } //projects for _, proj := range organisation.Projects { project := &domain.Project{Name: proj.Name} - projectAgg, _, err := r.addProject(ctx, project, orgAgg.ID(), userAgg.ID()) + projectEvents, projectWriteModel, err := r.addProject(ctx, project, orgAgg.ID, humanWriteModel.AggregateID) if err != nil { return err } + events = append(events, projectEvents...) if project.Name == step1.IAMProject { - err = r.setIAMProject(ctx, iamAgg, iamWriteModel, projectAgg.ID()) + iamProjectEvent, err := r.setIAMProject(ctx, iamAgg, iamWriteModel, projectWriteModel.AggregateID) if err != nil { return err } + events = append(events, iamProjectEvent) logging.Log("SETUP-Bdfs1").Info("IAM project set") - err = r.addIAMMember(ctx, iamAgg, NewIAMMemberWriteModel(userAgg.ID()), domain.NewMember(iamAgg.ID(), userAgg.ID(), domain.RoleIAMOwner)) + iamEvent, err := r.addIAMMember(ctx, iamAgg, NewIAMMemberWriteModel(humanWriteModel.AggregateID), domain.NewMember(iamAgg.ID, humanWriteModel.AggregateID, domain.RoleIAMOwner)) if err != nil { return err } + events = append(events, iamEvent) logging.Log("SETUP-BSf2h").Info("IAM owner set") } //create applications for _, app := range proj.OIDCApps { - err = setUpApplication(ctx, r, projectAgg, project, app, orgAgg.ID()) + applicationEvents, err := setUpApplication(ctx, r, projectWriteModel, project, app, orgAgg.ID) if err != nil { return err } + events = append(events, applicationEvents...) } - aggregates = append(aggregates, projectAgg) } } - iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1)) + events = append(events, iam_repo.NewSetupStepDoneEvent(ctx, iamAgg, domain.Step1)) - _, err = r.eventstore.PushAggregates(ctx, append(aggregates, iamAgg)...) + _, err = r.eventstore.PushEvents(ctx, events...) if err != nil { return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Gr2hh", "Setup Step1 failed") } return nil } -func setUpApplication(ctx context.Context, r *CommandSide, projectAgg *project.Aggregate, project *domain.Project, oidcApp OIDCApp, resourceOwner string) error { +func setUpApplication(ctx context.Context, r *CommandSide, projectWriteModel *ProjectWriteModel, project *domain.Project, oidcApp OIDCApp, resourceOwner string) ([]eventstore.EventPusher, error) { app := &domain.OIDCApp{ ObjectRoot: models.ObjectRoot{ - AggregateID: projectAgg.ID(), + AggregateID: projectWriteModel.AggregateID, }, AppName: oidcApp.Name, RedirectUris: oidcApp.RedirectUris, @@ -192,12 +197,13 @@ func setUpApplication(ctx context.Context, r *CommandSide, projectAgg *project.A DevMode: oidcApp.DevMode, } - _, err := r.addOIDCApplication(ctx, projectAgg, project, app, resourceOwner) + projectAgg := ProjectAggregateFromWriteModel(&projectWriteModel.WriteModel) + events, _, err := r.addOIDCApplication(ctx, projectAgg, project, app, resourceOwner) if err != nil { - return err + return nil, err } logging.LogWithFields("SETUP-Edgw4", "name", app.AppName, "clientID", app.ClientID).Info("application set up") - return nil + return events, nil } func getOIDCResponseTypes(responseTypes []string) []domain.OIDCResponseType { diff --git a/internal/v2/command/setup_step10.go b/internal/v2/command/setup_step10.go index 47e93af9e1..677669ac87 100644 --- a/internal/v2/command/setup_step10.go +++ b/internal/v2/command/setup_step10.go @@ -3,8 +3,8 @@ package command import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step10 struct { @@ -21,20 +21,24 @@ func (s *Step10) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep10(ctx context.Context, step *Step10) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultMailTemplate(ctx, iamAgg, NewIAMMailTemplateWriteModel(), &step.DefaultMailTemplate) + mailTemplateEvent, err := r.addDefaultMailTemplate(ctx, iamAgg, NewIAMMailTemplateWriteModel(), &step.DefaultMailTemplate) if err != nil { return nil, err } + events := []eventstore.EventPusher{ + mailTemplateEvent, + } for _, text := range step.DefaultMailTexts { - r.addDefaultMailText(ctx, iamAgg, NewIAMMailTextWriteModel(text.MailTextType, text.Language), &text) + defaultTextEvent, err := r.addDefaultMailText(ctx, iamAgg, NewIAMMailTextWriteModel(text.MailTextType, text.Language), &text) if err != nil { return nil, err } + events = append(events, defaultTextEvent) } logging.Log("SETUP-3N9fs").Info("default mail template/text set up") - return iamAgg, nil + return events, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step11.go b/internal/v2/command/setup_step11.go index 9b70533cc9..9f735d305d 100644 --- a/internal/v2/command/setup_step11.go +++ b/internal/v2/command/setup_step11.go @@ -3,6 +3,7 @@ package command import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) @@ -20,7 +21,7 @@ func (s *Step11) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep11(ctx context.Context, step *Step11) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) var uniqueContraintMigrations []*domain.UniqueConstraintMigration if step.MigrateV1EventstoreToV2 { @@ -31,9 +32,8 @@ func (r *CommandSide) SetupStep11(ctx context.Context, step *Step11) error { } uniqueContraintMigrations = uniqueConstraints.UniqueConstraints } - iamAgg.PushEvents(iam_repo.NewMigrateUniqueConstraintEvent(ctx, uniqueContraintMigrations)) logging.Log("SETUP-M9fsd").Info("migrate v1 eventstore to v2") - return iamAgg, nil + return []eventstore.EventPusher{iam_repo.NewMigrateUniqueConstraintEvent(ctx, iamAgg, uniqueContraintMigrations)}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step2.go b/internal/v2/command/setup_step2.go index 039cf750c4..47279602ee 100644 --- a/internal/v2/command/setup_step2.go +++ b/internal/v2/command/setup_step2.go @@ -2,12 +2,12 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step2 struct { @@ -23,9 +23,9 @@ func (s *Step2) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep2(ctx context.Context, step *Step2) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, NewIAMPasswordComplexityPolicyWriteModel(), &domain.PasswordComplexityPolicy{ + event, err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, NewIAMPasswordComplexityPolicyWriteModel(), &domain.PasswordComplexityPolicy{ MinLength: step.DefaultPasswordComplexityPolicy.MinLength, HasLowercase: step.DefaultPasswordComplexityPolicy.HasLowercase, HasUppercase: step.DefaultPasswordComplexityPolicy.HasUppercase, @@ -36,7 +36,7 @@ func (r *CommandSide) SetupStep2(ctx context.Context, step *Step2) error { return nil, err } logging.Log("SETUP-ADgd2").Info("default password complexity policy set up") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step3.go b/internal/v2/command/setup_step3.go index c1e3b3f8a0..1ed0f664aa 100644 --- a/internal/v2/command/setup_step3.go +++ b/internal/v2/command/setup_step3.go @@ -2,12 +2,12 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step3 struct { @@ -23,9 +23,9 @@ func (s *Step3) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep3(ctx context.Context, step *Step3) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, NewIAMPasswordAgePolicyWriteModel(), &domain.PasswordAgePolicy{ + event, err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, NewIAMPasswordAgePolicyWriteModel(), &domain.PasswordAgePolicy{ MaxAgeDays: step.DefaultPasswordAgePolicy.MaxAgeDays, ExpireWarnDays: step.DefaultPasswordAgePolicy.ExpireWarnDays, }) @@ -33,7 +33,7 @@ func (r *CommandSide) SetupStep3(ctx context.Context, step *Step3) error { return nil, err } logging.Log("SETUP-DBqgq").Info("default password age policy set up") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step4.go b/internal/v2/command/setup_step4.go index c1502c67ec..b516ebd192 100644 --- a/internal/v2/command/setup_step4.go +++ b/internal/v2/command/setup_step4.go @@ -2,12 +2,12 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step4 struct { @@ -23,9 +23,9 @@ func (s *Step4) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep4(ctx context.Context, step *Step4) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(), &domain.PasswordLockoutPolicy{ + event, err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(), &domain.PasswordLockoutPolicy{ MaxAttempts: step.DefaultPasswordLockoutPolicy.MaxAttempts, ShowLockOutFailures: step.DefaultPasswordLockoutPolicy.ShowLockOutFailures, }) @@ -33,7 +33,7 @@ func (r *CommandSide) SetupStep4(ctx context.Context, step *Step4) error { return nil, err } logging.Log("SETUP-Bfnge").Info("default password lockout policy set up") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step5.go b/internal/v2/command/setup_step5.go index 69c4b6733f..3f36738ad5 100644 --- a/internal/v2/command/setup_step5.go +++ b/internal/v2/command/setup_step5.go @@ -2,12 +2,12 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step5 struct { @@ -23,16 +23,16 @@ func (s *Step5) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep5(ctx context.Context, step *Step5) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, NewIAMOrgIAMPolicyWriteModel(), &domain.OrgIAMPolicy{ + event, err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, NewIAMOrgIAMPolicyWriteModel(), &domain.OrgIAMPolicy{ UserLoginMustBeDomain: step.DefaultOrgIAMPolicy.UserLoginMustBeDomain, }) if err != nil { return nil, err } logging.Log("SETUP-ADgd2").Info("default org iam policy set up") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step6.go b/internal/v2/command/setup_step6.go index 6bde7db1a6..ddcff9023d 100644 --- a/internal/v2/command/setup_step6.go +++ b/internal/v2/command/setup_step6.go @@ -2,12 +2,12 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step6 struct { @@ -23,9 +23,9 @@ func (s *Step6) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep6(ctx context.Context, step *Step6) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) - err := r.addDefaultLabelPolicy(ctx, iamAgg, NewIAMLabelPolicyWriteModel(), &domain.LabelPolicy{ + event, err := r.addDefaultLabelPolicy(ctx, iamAgg, NewIAMLabelPolicyWriteModel(), &domain.LabelPolicy{ PrimaryColor: step.DefaultLabelPolicy.PrimaryColor, SecondaryColor: step.DefaultLabelPolicy.SecondaryColor, }) @@ -33,7 +33,7 @@ func (r *CommandSide) SetupStep6(ctx context.Context, step *Step6) error { return nil, err } logging.Log("SETUP-ADgd2").Info("default label policy set up") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step7.go b/internal/v2/command/setup_step7.go index e917857ac9..cdc55ee2c8 100644 --- a/internal/v2/command/setup_step7.go +++ b/internal/v2/command/setup_step7.go @@ -2,11 +2,11 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step7 struct { @@ -22,18 +22,18 @@ func (s *Step7) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep7(ctx context.Context, step *Step7) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { secondFactorModel := NewIAMSecondFactorWriteModel() iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) if !step.OTP { - return iamAgg, nil + return []eventstore.EventPusher{}, nil } - err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, domain.SecondFactorTypeOTP) + event, err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, domain.SecondFactorTypeOTP) if err != nil { return nil, err } logging.Log("SETUP-Dggsg").Info("added OTP to 2FA login policy") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step8.go b/internal/v2/command/setup_step8.go index 6db58e0957..c0f8cf4322 100644 --- a/internal/v2/command/setup_step8.go +++ b/internal/v2/command/setup_step8.go @@ -2,11 +2,11 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step8 struct { @@ -22,18 +22,18 @@ func (s *Step8) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep8(ctx context.Context, step *Step8) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { secondFactorModel := NewIAMSecondFactorWriteModel() iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) if !step.U2F { - return iamAgg, nil + return []eventstore.EventPusher{}, nil } - err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, domain.SecondFactorTypeU2F) + event, err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, domain.SecondFactorTypeU2F) if err != nil { return nil, err } logging.Log("SETUP-BDhne").Info("added U2F to 2FA login policy") - return iamAgg, nil + return []eventstore.EventPusher{event}, nil } return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step9.go b/internal/v2/command/setup_step9.go index 21791bfd98..d5494f626d 100644 --- a/internal/v2/command/setup_step9.go +++ b/internal/v2/command/setup_step9.go @@ -2,11 +2,11 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/logging" "github.com/caos/zitadel/internal/v2/domain" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) type Step9 struct { @@ -22,31 +22,31 @@ func (s *Step9) execute(ctx context.Context, commandSide *CommandSide) error { } func (r *CommandSide) SetupStep9(ctx context.Context, step *Step9) error { - fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + fn := func(iam *IAMWriteModel) ([]eventstore.EventPusher, error) { multiFactorModel := NewIAMMultiFactorWriteModel() iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) if !step.Passwordless { - return iamAgg, nil + return []eventstore.EventPusher{}, nil } - err := setPasswordlessAllowedInPolicy(ctx, r, iamAgg) + passwordlessEvent, err := setPasswordlessAllowedInPolicy(ctx, r, iamAgg) if err != nil { return nil, err } logging.Log("SETUP-AEG2t").Info("allowed passwordless in login policy") - err = r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, domain.MultiFactorTypeU2FWithPIN) + multifactorEvent, err := r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, domain.MultiFactorTypeU2FWithPIN) if err != nil { return nil, err } logging.Log("SETUP-ADfng").Info("added passwordless to MFA login policy") - return iamAgg, err + return []eventstore.EventPusher{passwordlessEvent, multifactorEvent}, nil } return r.setup(ctx, step, fn) } -func setPasswordlessAllowedInPolicy(ctx context.Context, c *CommandSide, iamAgg *iam_repo.Aggregate) error { +func setPasswordlessAllowedInPolicy(ctx context.Context, c *CommandSide, iamAgg *eventstore.Aggregate) (eventstore.EventPusher, error) { policy, err := c.getDefaultLoginPolicy(ctx) if err != nil { - return err + return nil, err } policy.PasswordlessType = domain.PasswordlessTypeAllowed return c.changeDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(), policy) diff --git a/internal/v2/command/unique_constraints_model.go b/internal/v2/command/unique_constraints_model.go index 0c5bf3a9e9..d13c0ead57 100644 --- a/internal/v2/command/unique_constraints_model.go +++ b/internal/v2/command/unique_constraints_model.go @@ -42,123 +42,129 @@ func (rm *UniqueConstraintReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { case *org.OrgAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, org.NewAddOrgNameUniqueConstraint(e.Name)) case *org.OrgChangedEvent: - rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name)) + rm.changeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, org.NewAddOrgNameUniqueConstraint(e.Name)) case *org.DomainVerifiedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Domain)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, org.NewAddOrgNameUniqueConstraint(e.Domain)) case *org.DomainRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.UniqueOrgDomain) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, org.UniqueOrgDomain) case *iam.IDPConfigAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner())) + rm.addUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)) case *iam.IDPConfigChangedEvent: - rm.changeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner())) + rm.changeUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.Aggregate().ResourceOwner)) case *iam.IDPConfigRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.UniqueIDPConfigNameType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.UniqueIDPConfigNameType) case *org.IDPConfigAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner())) + rm.addUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)) case *org.IDPConfigChangedEvent: - rm.changeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner())) + rm.changeUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.Aggregate().ResourceOwner)) case *org.IDPConfigRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.UniqueIDPConfigNameType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.ConfigID, idpconfig.UniqueIDPConfigNameType) case *iam.MailTextAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.AggregateID(), e.MailTextType, e.Language)) + rm.addUniqueConstraint(e.Aggregate().ID, e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.Aggregate().ID, e.MailTextType, e.Language)) case *org.MailTextAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.AggregateID(), e.MailTextType, e.Language)) + rm.addUniqueConstraint(e.Aggregate().ID, e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.Aggregate().ID, e.MailTextType, e.Language)) case *org.MailTextRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.UniqueMailText) + rm.removeUniqueConstraint(e.Aggregate().ID, e.MailTextType+e.Language, policy.UniqueMailText) case *project.ProjectAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), project.NewAddProjectNameUniqueConstraint(e.Name, e.ResourceOwner())) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, project.NewAddProjectNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)) case *project.ProjectChangeEvent: - rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), project.NewAddProjectNameUniqueConstraint(*e.Name, e.ResourceOwner())) + rm.changeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, project.NewAddProjectNameUniqueConstraint(*e.Name, e.Aggregate().ResourceOwner)) case *project.ProjectRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), project.UniqueProjectnameType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, project.UniqueProjectnameType) case *project.ApplicationAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.AggregateID())) + rm.addUniqueConstraint(e.Aggregate().ID, e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.Aggregate().ID)) case *project.ApplicationChangedEvent: - rm.changeUniqueConstraint(e.AggregateID(), e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.AggregateID())) + rm.changeUniqueConstraint(e.Aggregate().ID, e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.Aggregate().ID)) case *project.ApplicationRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AppID, project.UniqueAppNameType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.AppID, project.UniqueAppNameType) case *project.GrantAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.GrantID, project.NewAddProjectGrantUniqueConstraint(e.GrantedOrgID, e.AggregateID())) + rm.addUniqueConstraint(e.Aggregate().ID, e.GrantID, project.NewAddProjectGrantUniqueConstraint(e.GrantedOrgID, e.Aggregate().ID)) case *project.GrantRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.GrantID, project.UniqueGrantType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.GrantID, project.UniqueGrantType) case *project.GrantMemberAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.GrantID+e.UserID, project.NewAddProjectGrantMemberUniqueConstraint(e.AggregateID(), e.UserID, e.GrantID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.GrantID+e.UserID, project.NewAddProjectGrantMemberUniqueConstraint(e.Aggregate().ID, e.UserID, e.GrantID)) case *project.GrantMemberRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.GrantID+e.UserID, project.UniqueProjectGrantMemberType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.GrantID+e.UserID, project.UniqueProjectGrantMemberType) case *project.RoleAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.Key, project.NewAddProjectRoleUniqueConstraint(e.Key, e.AggregateID())) + rm.addUniqueConstraint(e.Aggregate().ID, e.Key, project.NewAddProjectRoleUniqueConstraint(e.Key, e.Aggregate().ID)) case *project.RoleRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.Key, project.UniqueRoleType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Key, project.UniqueRoleType) case *user.HumanAddedEvent: - policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner()) + policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner) if err != nil { logging.Log("COMMAND-0k9Gs").WithError(err).Error("could not read policy for human added event unique constraint") continue } - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain)) case *user.HumanRegisteredEvent: - policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner()) + policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner) if err != nil { logging.Log("COMMAND-m9fod").WithError(err).Error("could not read policy for human registered event unique constraint") continue } - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain)) case *user.MachineAddedEvent: - policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner()) + policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner) if err != nil { logging.Log("COMMAND-2n8vs").WithError(err).Error("could not read policy for machine added event unique constraint") continue } - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain)) case *user.UserRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.UniqueUsername) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.UniqueUsername) case *user.UsernameChangedEvent: - policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner()) + policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner) if err != nil { logging.Log("COMMAND-5n8gk").WithError(err).Error("could not read policy for username changed event unique constraint") continue } - rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain)) + rm.changeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain)) case *user.DomainClaimedEvent: - policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner()) + policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner) if err != nil { logging.Log("COMMAND-xb8uf").WithError(err).Error("could not read policy for domain claimed event unique constraint") continue } - rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain)) + rm.changeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain)) case *user.HumanExternalIDPAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)) case *user.HumanExternalIDPRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType) case *user.HumanExternalIDPCascadeRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType) + rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType) case *usergrant.UserGrantAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID, e.ProjectGrantID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, usergrant.NewAddUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.UserID, e.ProjectID, e.ProjectGrantID)) case *usergrant.UserGrantRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.UniqueUserGrant) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, usergrant.UniqueUserGrant) case *usergrant.UserGrantCascadeRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.UniqueUserGrant) + rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, usergrant.UniqueUserGrant) case *iam.MemberAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.UserID, member.NewAddMemberUniqueConstraint(e.Aggregate().ID, e.UserID)) case *iam.MemberRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember) + rm.removeUniqueConstraint(e.Aggregate().ID, e.UserID, member.UniqueMember) case *org.MemberAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.UserID, member.NewAddMemberUniqueConstraint(e.Aggregate().ID, e.UserID)) case *org.MemberRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember) + rm.removeUniqueConstraint(e.Aggregate().ID, e.UserID, member.UniqueMember) case *project.MemberAddedEvent: - rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID)) + rm.addUniqueConstraint(e.Aggregate().ID, e.UserID, member.NewAddMemberUniqueConstraint(e.Aggregate().ID, e.UserID)) case *project.MemberRemovedEvent: - rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember) + rm.removeUniqueConstraint(e.Aggregate().ID, e.UserID, member.UniqueMember) } } return nil } func (rm *UniqueConstraintReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType, org.AggregateType, project.AggregateType, user.AggregateType, usergrant.AggregateType). + return eventstore.NewSearchQueryBuilder( + eventstore.ColumnsEvent, + iam.AggregateType, + org.AggregateType, + project.AggregateType, + user.AggregateType, + usergrant.AggregateType). EventTypes( org.OrgAddedEventType, org.OrgChangedEventType, diff --git a/internal/v2/command/user.go b/internal/v2/command/user.go index a4b2ca41e0..5f73de504c 100644 --- a/internal/v2/command/user.go +++ b/internal/v2/command/user.go @@ -3,196 +3,203 @@ package command import ( "context" "fmt" - "github.com/caos/logging" - auth_req_model "github.com/caos/zitadel/internal/auth_request/model" - "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/v2" - "strings" "time" + "github.com/caos/zitadel/internal/eventstore/models" + + "github.com/caos/logging" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" ) -func (r *CommandSide) ChangeUsername(ctx context.Context, orgID, userID, userName string) error { +func (cs *CommandSide) ChangeUsername(ctx context.Context, orgID, userID, userName string) error { if orgID == "" || userID == "" || userName == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2N9fs", "Errors.IDMissing") } - existingUser, err := r.userWriteModelByID(ctx, userID, orgID) + + existingUser, err := cs.userWriteModelByID(ctx, userID, orgID) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-5N9ds", "Errors.User.NotFound") } + if existingUser.UserName == userName { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6m9gs", "Errors.User.UsernameNotChanged") } - orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID) + orgIAMPolicy, err := cs.getOrgIAMPolicy(ctx, orgID) if err != nil { return err } + if err := CheckOrgIAMPolicyForUserName(userName, orgIAMPolicy); err != nil { return err } userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUsernameChangedEvent(ctx, existingUser.UserName, userName, orgIAMPolicy.UserLoginMustBeDomain)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = cs.eventstore.PushEvents(ctx, + user.NewUsernameChangedEvent(ctx, userAgg, existingUser.UserName, userName, orgIAMPolicy.UserLoginMustBeDomain)) + + return err } func (r *CommandSide) DeactivateUser(ctx context.Context, userID, resourceOwner string) error { if userID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-m0gDf", "Errors.User.UserIDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-3M9ds", "Errors.User.NotFound") } - if existingUser.UserState == domain.UserStateInactive { + if isUserStateInactive(existingUser.UserState) { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0sf", "Errors.User.AlreadyInactive") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserDeactivatedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = r.eventstore.PushEvents(ctx, + user.NewUserDeactivatedEvent(ctx, UserAggregateFromWriteModel(&existingUser.WriteModel))) + return err } func (r *CommandSide) ReactivateUser(ctx context.Context, userID, resourceOwner string) error { if userID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9ds", "Errors.User.UserIDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-4M0sd", "Errors.User.NotFound") } - if existingUser.UserState != domain.UserStateInactive { + if !isUserStateInactive(existingUser.UserState) { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M0sf", "Errors.User.NotInactive") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserReactivatedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = r.eventstore.PushEvents(ctx, + user.NewUserReactivatedEvent(ctx, UserAggregateFromWriteModel(&existingUser.WriteModel))) + return err } func (r *CommandSide) LockUser(ctx context.Context, userID, resourceOwner string) error { if userID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0sd", "Errors.User.UserIDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-5M9fs", "Errors.User.NotFound") } - if existingUser.UserState != domain.UserStateActive && existingUser.UserState != domain.UserStateInitial { + if !hasUserState(existingUser.UserState, domain.UserStateActive, domain.UserStateInitial) { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3NN8v", "Errors.User.ShouldBeActiveOrInitial") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserLockedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = r.eventstore.PushEvents(ctx, + user.NewUserLockedEvent(ctx, UserAggregateFromWriteModel(&existingUser.WriteModel))) + return err } func (r *CommandSide) UnlockUser(ctx context.Context, userID, resourceOwner string) error { if userID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-M0dse", "Errors.User.UserIDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-M0dos", "Errors.User.NotFound") } - if existingUser.UserState != domain.UserStateLocked { + if !hasUserState(existingUser.UserState, domain.UserStateLocked) { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0ds", "Errors.User.NotLocked") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserUnlockedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = r.eventstore.PushEvents(ctx, + user.NewUserUnlockedEvent(ctx, UserAggregateFromWriteModel(&existingUser.WriteModel))) + return err } func (r *CommandSide) RemoveUser(ctx context.Context, userID, resourceOwner string, cascadingGrantIDs ...string) error { if userID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0ds", "Errors.User.UserIDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-5M0od", "Errors.User.NotFound") } + orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, existingUser.ResourceOwner) if err != nil { return err } - aggregates := make([]eventstore.Aggregater, 0) + var events []eventstore.EventPusher userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserRemovedEvent(ctx, existingUser.ResourceOwner, existingUser.UserName, orgIAMPolicy.UserLoginMustBeDomain)) - aggregates = append(aggregates, userAgg) + events = append(events, user.NewUserRemovedEvent(ctx, userAgg, existingUser.UserName, orgIAMPolicy.UserLoginMustBeDomain)) for _, grantID := range cascadingGrantIDs { - grantAgg, _, err := r.removeUserGrant(ctx, grantID, "", true) + removeEvent, err := r.removeUserGrant(ctx, grantID, "", true) if err != nil { logging.LogWithFields("COMMAND-5m9oL", "usergrantid", grantID).WithError(err).Warn("could not cascade remove role on user grant") continue } - aggregates = append(aggregates, grantAgg) + events = append(events, removeEvent) } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, events...) return err } -func (r *CommandSide) CreateUserToken(ctx context.Context, orgID, agentID, clientID, userID string, audience, scopes []string, lifetime time.Duration) (*domain.Token, error) { +func (r *CommandSide) AddUserToken(ctx context.Context, orgID, agentID, clientID, userID string, audience, scopes []string, lifetime time.Duration) (*domain.Token, error) { if orgID == "" || userID == "" { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-55n8M", "Errors.IDMissing") } + existingUser, err := r.userWriteModelByID(ctx, userID, orgID) if err != nil { return nil, err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-1d6Gg", "Errors.User.NotFound") } - for _, scope := range scopes { - if strings.HasPrefix(scope, auth_req_model.ProjectIDScope) && strings.HasSuffix(scope, auth_req_model.AudSuffix) { - audience = append(audience, strings.TrimSuffix(strings.TrimPrefix(scope, auth_req_model.ProjectIDScope), auth_req_model.AudSuffix)) - } - } + audience = domain.AddAudScopeToAudience(audience, scopes) preferredLanguage := "" existingHuman, err := r.getHumanWriteModelByID(ctx, userID, orgID) if existingHuman != nil { preferredLanguage = existingHuman.PreferredLanguage.String() } - now := time.Now().UTC() + expiration := time.Now().UTC().Add(lifetime) tokenID, err := r.idGenerator.Next() if err != nil { return nil, err } userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewUserTokenAddedEvent(ctx, tokenID, clientID, agentID, preferredLanguage, audience, scopes, now.Add(lifetime))) - - err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + _, err = r.eventstore.PushEvents(ctx, + user.NewUserTokenAddedEvent(ctx, userAgg, tokenID, clientID, agentID, preferredLanguage, audience, scopes, expiration)) if err != nil { return nil, err } + return &domain.Token{ ObjectRoot: models.ObjectRoot{ AggregateID: userID, @@ -202,12 +209,12 @@ func (r *CommandSide) CreateUserToken(ctx context.Context, orgID, agentID, clien ApplicationID: clientID, Audience: audience, Scopes: scopes, - Expiration: now.Add(lifetime), + Expiration: expiration, PreferredLanguage: preferredLanguage, }, nil } -func (r *CommandSide) userDomainClaimed(ctx context.Context, userID string) (_ *user.Aggregate, _ *UserWriteModel, err error) { +func (r *CommandSide) userDomainClaimed(ctx context.Context, userID string) (events []eventstore.EventPusher, _ *UserWriteModel, err error) { existingUser, err := r.userWriteModelByID(ctx, userID, "") if err != nil { return nil, nil, err @@ -227,8 +234,14 @@ func (r *CommandSide) userDomainClaimed(ctx context.Context, userID string) (_ * if err != nil { return nil, nil, err } - userAgg.PushEvents(user.NewDomainClaimedEvent(ctx, fmt.Sprintf("%s@temporary.%s", id, r.iamDomain), existingUser.UserName, orgIAMPolicy.UserLoginMustBeDomain)) - return userAgg, changedUserGrant, nil + return []eventstore.EventPusher{ + user.NewDomainClaimedEvent( + ctx, + userAgg, + fmt.Sprintf("%s@temporary.%s", id, r.iamDomain), + existingUser.UserName, + orgIAMPolicy.UserLoginMustBeDomain), + }, changedUserGrant, nil } func (r *CommandSide) UserDomainClaimedSent(ctx context.Context, orgID, userID string) (err error) { @@ -236,20 +249,21 @@ func (r *CommandSide) UserDomainClaimedSent(ctx context.Context, orgID, userID s if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-5m9gK", "Errors.User.NotFound") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewDomainClaimedSentEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingUser, userAgg) + + _, err = r.eventstore.PushEvents(ctx, + user.NewDomainClaimedSentEvent(ctx, UserAggregateFromWriteModel(&existingUser.WriteModel))) + return err } func (r *CommandSide) checkUserExists(ctx context.Context, userID, resourceOwner string) error { - userWriteModel, err := r.userWriteModelByID(ctx, userID, resourceOwner) + existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner) if err != nil { return err } - if userWriteModel.UserState == domain.UserStateUnspecified || userWriteModel.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.User.NotFound") } return nil @@ -266,15 +280,3 @@ func (r *CommandSide) userWriteModelByID(ctx context.Context, userID, resourceOw } return writeModel, nil } - -func (r *CommandSide) userReadModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel = NewUserWriteModel(userID, resourceOwner) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/command/user_grant.go b/internal/v2/command/user_grant.go index e83108c946..304b56357f 100644 --- a/internal/v2/command/user_grant.go +++ b/internal/v2/command/user_grant.go @@ -2,28 +2,33 @@ package command import ( "context" + "reflect" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/usergrant" - "reflect" ) func (r *CommandSide) AddUserGrant(ctx context.Context, usergrant *domain.UserGrant, resourceOwner string) (_ *domain.UserGrant, err error) { - userGrantAgg, addedUserGrant, err := r.addUserGrant(ctx, usergrant, resourceOwner) + event, addedUserGrant, err := r.addUserGrant(ctx, usergrant, resourceOwner) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedUserGrant, userGrantAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) if err != nil { return nil, err } + err = AppendAndReduce(addedUserGrant, pushedEvents...) + if err != nil { + return nil, err + } return userGrantWriteModelToUserGrant(addedUserGrant), nil } -func (r *CommandSide) addUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { +func (r *CommandSide) addUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string) (pusher eventstore.EventPusher, _ *UserGrantWriteModel, err error) { err = checkExplicitProjectPermission(ctx, userGrant.ProjectGrantID, userGrant.ProjectID) if err != nil { return nil, nil, err @@ -43,36 +48,37 @@ func (r *CommandSide) addUserGrant(ctx context.Context, userGrant *domain.UserGr if err != nil { return nil, nil, err } + addedUserGrant := NewUserGrantWriteModel(userGrant.AggregateID, resourceOwner) userGrantAgg := UserGrantAggregateFromWriteModel(&addedUserGrant.WriteModel) - - userGrantAgg.PushEvents( - usergrant.NewUserGrantAddedEvent( - ctx, - resourceOwner, - userGrant.UserID, - userGrant.ProjectID, - userGrant.ProjectGrantID, - userGrant.RoleKeys, - ), + pusher = usergrant.NewUserGrantAddedEvent( + ctx, + userGrantAgg, + userGrant.UserID, + userGrant.ProjectID, + userGrant.ProjectGrantID, + userGrant.RoleKeys, ) - return userGrantAgg, addedUserGrant, nil + return pusher, addedUserGrant, nil } func (r *CommandSide) ChangeUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string) (_ *domain.UserGrant, err error) { - userGrantAgg, addedUserGrant, err := r.changeUserGrant(ctx, userGrant, resourceOwner, false) + event, changedUserGrant, err := r.changeUserGrant(ctx, userGrant, resourceOwner, false) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedUserGrant, userGrantAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, event) if err != nil { return nil, err } - - return userGrantWriteModelToUserGrant(addedUserGrant), nil + err = AppendAndReduce(changedUserGrant, pushedEvents...) + if err != nil { + return nil, err + } + return userGrantWriteModelToUserGrant(changedUserGrant), nil } -func (r *CommandSide) changeUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string, cascade bool) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { +func (r *CommandSide) changeUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string, cascade bool) (_ eventstore.EventPusher, _ *UserGrantWriteModel, err error) { err = checkExplicitProjectPermission(ctx, userGrant.ProjectGrantID, userGrant.ProjectID) if err != nil { return nil, nil, err @@ -95,26 +101,19 @@ func (r *CommandSide) changeUserGrant(ctx context.Context, userGrant *domain.Use changedUserGrant := NewUserGrantWriteModel(userGrant.AggregateID, resourceOwner) userGrantAgg := UserGrantAggregateFromWriteModel(&changedUserGrant.WriteModel) - if !cascade { - userGrantAgg.PushEvents( - usergrant.NewUserGrantChangedEvent(ctx, userGrant.RoleKeys), - ) - } else { - userGrantAgg.PushEvents( - usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrant.RoleKeys), - ) + if cascade { + return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, userGrant.RoleKeys), existingUserGrant, nil } - - return userGrantAgg, changedUserGrant, nil + return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, userGrant.RoleKeys), existingUserGrant, nil } -func (r *CommandSide) removeRoleFromUserGrant(ctx context.Context, userGrantID string, roleKeys []string, cascade bool) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { +func (r *CommandSide) removeRoleFromUserGrant(ctx context.Context, userGrantID string, roleKeys []string, cascade bool) (_ eventstore.EventPusher, err error) { existingUserGrant, err := r.userGrantWriteModelByID(ctx, userGrantID, "") if err != nil { - return nil, nil, err + return nil, err } if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { - return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.UserGrant.NotFound") + return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.UserGrant.NotFound") } keyExists := false for i, key := range existingUserGrant.RoleKeys { @@ -129,22 +128,16 @@ func (r *CommandSide) removeRoleFromUserGrant(ctx context.Context, userGrantID s } } if !keyExists { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5m8g9", "Errors.UserGrant.RoleKeyNotFound") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5m8g9", "Errors.UserGrant.RoleKeyNotFound") } changedUserGrant := NewUserGrantWriteModel(userGrantID, "") userGrantAgg := UserGrantAggregateFromWriteModel(&changedUserGrant.WriteModel) - if !cascade { - userGrantAgg.PushEvents( - usergrant.NewUserGrantChangedEvent(ctx, existingUserGrant.RoleKeys), - ) - } else { - userGrantAgg.PushEvents( - usergrant.NewUserGrantCascadeChangedEvent(ctx, existingUserGrant.RoleKeys), - ) + if cascade { + return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, existingUserGrant.RoleKeys), nil } - return userGrantAgg, changedUserGrant, nil + return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, existingUserGrant.RoleKeys), nil } func (r *CommandSide) DeactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { @@ -169,11 +162,8 @@ func (r *CommandSide) DeactivateUserGrant(ctx context.Context, grantID, resource deactivateUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) userGrantAgg := UserGrantAggregateFromWriteModel(&deactivateUserGrant.WriteModel) - userGrantAgg.PushEvents( - usergrant.NewUserGrantDeactivatedEvent(ctx), - ) - - return r.eventstore.PushAggregate(ctx, deactivateUserGrant, userGrantAgg) + _, err = r.eventstore.PushEvents(ctx, usergrant.NewUserGrantDeactivatedEvent(ctx, userGrantAgg)) + return err } func (r *CommandSide) ReactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { @@ -198,78 +188,69 @@ func (r *CommandSide) ReactivateUserGrant(ctx context.Context, grantID, resource deactivateUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) userGrantAgg := UserGrantAggregateFromWriteModel(&deactivateUserGrant.WriteModel) - userGrantAgg.PushEvents( - usergrant.NewUserGrantReactivatedEvent(ctx), - ) - - return r.eventstore.PushAggregate(ctx, deactivateUserGrant, userGrantAgg) + _, err = r.eventstore.PushEvents(ctx, usergrant.NewUserGrantReactivatedEvent(ctx, userGrantAgg)) + return err } func (r *CommandSide) RemoveUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { - userGrantAgg, removeUserGrant, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) + event, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) if err != nil { return nil } - return r.eventstore.PushAggregate(ctx, removeUserGrant, userGrantAgg) -} - -func (r *CommandSide) BulkRemoveUserGrant(ctx context.Context, grantIDs []string, resourceOwner string) (err error) { - aggregates := make([]eventstore.Aggregater, len(grantIDs)) - for i, grantID := range grantIDs { - userGrantAgg, _, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) - if err != nil { - return nil - } - aggregates[i] = userGrantAgg - } - _, err = r.eventstore.PushAggregates(ctx, aggregates...) + _, err = r.eventstore.PushEvents(ctx, event) return err } -func (r *CommandSide) removeUserGrant(ctx context.Context, grantID, resourceOwner string, cascade bool) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { +func (r *CommandSide) BulkRemoveUserGrant(ctx context.Context, grantIDs []string, resourceOwner string) (err error) { + events := make([]eventstore.EventPusher, len(grantIDs)) + for i, grantID := range grantIDs { + event, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) + if err != nil { + return nil + } + events[i] = event + } + _, err = r.eventstore.PushEvents(ctx, events...) + return err +} + +func (r *CommandSide) removeUserGrant(ctx context.Context, grantID, resourceOwner string, cascade bool) (_ eventstore.EventPusher, err error) { if grantID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J9sc5", "Errors.UserGrant.IDMissing") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J9sc5", "Errors.UserGrant.IDMissing") } existingUserGrant, err := r.userGrantWriteModelByID(ctx, grantID, resourceOwner) if err != nil { - return nil, nil, err + return nil, err } if !cascade { err = checkExplicitProjectPermission(ctx, existingUserGrant.ProjectGrantID, existingUserGrant.ProjectID) if err != nil { - return nil, nil, err + return nil, err } } if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { - return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-1My0t", "Errors.UserGrant.NotFound") + return nil, caos_errs.ThrowNotFound(nil, "COMMAND-1My0t", "Errors.UserGrant.NotFound") } removeUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) userGrantAgg := UserGrantAggregateFromWriteModel(&removeUserGrant.WriteModel) - if !cascade { - userGrantAgg.PushEvents( - usergrant.NewUserGrantRemovedEvent( - ctx, - existingUserGrant.ResourceOwner, - existingUserGrant.UserID, - existingUserGrant.ProjectID, - existingUserGrant.ProjectGrantID), - ) - } else { - userGrantAgg.PushEvents( - usergrant.NewUserGrantCascadeRemovedEvent( - ctx, - existingUserGrant.ResourceOwner, - existingUserGrant.UserID, - existingUserGrant.ProjectID, - existingUserGrant.ProjectGrantID), - ) + if cascade { + return usergrant.NewUserGrantCascadeRemovedEvent( + ctx, + userGrantAgg, + existingUserGrant.UserID, + existingUserGrant.ProjectID, + existingUserGrant.ProjectGrantID), nil } - - return userGrantAgg, removeUserGrant, nil + return usergrant.NewUserGrantRemovedEvent( + ctx, + userGrantAgg, + existingUserGrant.UserID, + existingUserGrant.ProjectID, + existingUserGrant.ProjectGrantID), nil } func (r *CommandSide) userGrantWriteModelByID(ctx context.Context, userGrantID, resourceOwner string) (writeModel *UserGrantWriteModel, err error) { ctx, span := tracing.NewSpan(ctx) diff --git a/internal/v2/command/user_grant_model.go b/internal/v2/command/user_grant_model.go index 0641210f5a..61d825dc34 100644 --- a/internal/v2/command/user_grant_model.go +++ b/internal/v2/command/user_grant_model.go @@ -25,10 +25,6 @@ func NewUserGrantWriteModel(userGrantID string, resourceOwner string) *UserGrant } } -func (wm *UserGrantWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *UserGrantWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -63,15 +59,20 @@ func (wm *UserGrantWriteModel) Reduce() error { func (wm *UserGrantWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, usergrant.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes(usergrant.UserGrantAddedType, + usergrant.UserGrantChangedType, + usergrant.UserGrantCascadeChangedType, + usergrant.UserGrantDeactivatedType, + usergrant.UserGrantReactivatedType, + usergrant.UserGrantRemovedType, + usergrant.UserGrantCascadeRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } return query } -func UserGrantAggregateFromWriteModel(wm *eventstore.WriteModel) *usergrant.Aggregate { - return &usergrant.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, usergrant.AggregateType, usergrant.AggregateVersion), - } +func UserGrantAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, usergrant.AggregateType, usergrant.AggregateVersion) } diff --git a/internal/v2/command/user_human.go b/internal/v2/command/user_human.go index a0f2112635..c35cff51e9 100644 --- a/internal/v2/command/user_human.go +++ b/internal/v2/command/user_human.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/v2" @@ -11,22 +12,27 @@ import ( ) func (r *CommandSide) getHuman(ctx context.Context, userID, resourceowner string) (*domain.Human, error) { - writeModel, err := r.getHumanWriteModelByID(ctx, userID, resourceowner) + human, err := r.getHumanWriteModelByID(ctx, userID, resourceowner) if err != nil { return nil, err } - if writeModel.UserState == domain.UserStateUnspecified || writeModel.UserState == domain.UserStateDeleted { + if !isUserStateExists(human.UserState) { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-M9dsd", "Errors.User.NotFound") } - return writeModelToHuman(writeModel), nil + return writeModelToHuman(human), nil } func (r *CommandSide) AddHuman(ctx context.Context, orgID string, human *domain.Human) (*domain.Human, error) { - userAgg, addedHuman, err := r.addHuman(ctx, orgID, human) + events, addedHuman, err := r.addHuman(ctx, orgID, human) if err != nil { return nil, err } - err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + + err = AppendAndReduce(addedHuman, pushedEvents...) if err != nil { return nil, err } @@ -34,7 +40,7 @@ func (r *CommandSide) AddHuman(ctx context.Context, orgID string, human *domain. return writeModelToHuman(addedHuman), nil } -func (r *CommandSide) addHuman(ctx context.Context, orgID string, human *domain.Human) (*user.Aggregate, *HumanWriteModel, error) { +func (r *CommandSide) addHuman(ctx context.Context, orgID string, human *domain.Human) ([]eventstore.EventPusher, *HumanWriteModel, error) { if !human.IsValid() { return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid") } @@ -42,46 +48,48 @@ func (r *CommandSide) addHuman(ctx context.Context, orgID string, human *domain. } func (r *CommandSide) RegisterHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, orgMemberRoles []string) (*domain.Human, error) { - aggregates := make([]eventstore.Aggregater, 2) - - userAgg, addedHuman, err := r.registerHuman(ctx, orgID, human, externalIDP) + userEvents, registeredHuman, err := r.registerHuman(ctx, orgID, human, externalIDP) if err != nil { return nil, err } - aggregates[0] = userAgg - orgMemberWriteModel := NewOrgMemberWriteModel(orgID, addedHuman.AggregateID) + orgMemberWriteModel := NewOrgMemberWriteModel(orgID, registeredHuman.AggregateID) orgAgg := OrgAggregateFromWriteModel(&orgMemberWriteModel.WriteModel) - if orgMemberRoles != nil { + if len(orgMemberRoles) > 0 { orgMember := &domain.Member{ ObjectRoot: models.ObjectRoot{ AggregateID: orgID, }, - UserID: userAgg.ID(), + UserID: human.AggregateID, Roles: orgMemberRoles, } - r.addOrgMember(ctx, orgAgg, orgMemberWriteModel, orgMember) + memberEvent, err := r.addOrgMember(ctx, orgAgg, orgMemberWriteModel, orgMember) + if err != nil { + return nil, err + } + userEvents = append(userEvents, memberEvent) } - aggregates[1] = orgAgg - - eventReader, err := r.eventstore.PushAggregates(ctx, aggregates...) + pushedEvents, err := r.eventstore.PushEvents(ctx, userEvents...) if err != nil { return nil, err } - addedHuman.AppendEvents(eventReader...) - addedHuman.Reduce() - return writeModelToHuman(addedHuman), nil + + err = AppendAndReduce(registeredHuman, pushedEvents...) + if err != nil { + return nil, err + } + return writeModelToHuman(registeredHuman), nil } -func (r *CommandSide) registerHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP) (*user.Aggregate, *HumanWriteModel, error) { +func (r *CommandSide) registerHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP) ([]eventstore.EventPusher, *HumanWriteModel, error) { if !human.IsValid() || externalIDP == nil && (human.Password == nil || human.SecretString == "") { return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-9dk45", "Errors.User.Invalid") } return r.createHuman(ctx, orgID, human, externalIDP, true) } -func (r *CommandSide) createHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, selfregister bool) (*user.Aggregate, *HumanWriteModel, error) { +func (r *CommandSide) createHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, selfregister bool) ([]eventstore.EventPusher, *HumanWriteModel, error) { userID, err := r.idGenerator.Next() if err != nil { return nil, nil, err @@ -95,8 +103,6 @@ func (r *CommandSide) createHuman(ctx context.Context, orgID string, human *doma if err != nil { return nil, nil, err } - - addedHuman := NewHumanWriteModel(human.AggregateID, orgID) if err := human.CheckOrgIAMPolicy(orgIAMPolicy); err != nil { return nil, nil, err } @@ -104,43 +110,48 @@ func (r *CommandSide) createHuman(ctx context.Context, orgID string, human *doma if err := human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true); err != nil { return nil, nil, err } - + addedHuman := NewHumanWriteModel(human.AggregateID, orgID) + //TODO: adlerhurst maybe we could simplify the code below userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel) - var createEvent eventstore.EventPusher + var events []eventstore.EventPusher + if selfregister { - createEvent = createRegisterHumanEvent(ctx, orgID, human, orgIAMPolicy.UserLoginMustBeDomain) + events = append(events, createRegisterHumanEvent(ctx, userAgg, human, orgIAMPolicy.UserLoginMustBeDomain)) } else { - createEvent = createAddHumanEvent(ctx, orgID, human, orgIAMPolicy.UserLoginMustBeDomain) + events = append(events, createAddHumanEvent(ctx, userAgg, human, orgIAMPolicy.UserLoginMustBeDomain)) } - userAgg.PushEvents(createEvent) if externalIDP != nil { - err = r.addHumanExternalIDP(ctx, userAgg, externalIDP) + event, err := r.addHumanExternalIDP(ctx, userAgg, externalIDP) if err != nil { return nil, nil, err } + events = append(events, event) } + if human.IsInitialState() { initCode, err := domain.NewInitUserCode(r.initializeUserCode) if err != nil { return nil, nil, err } - userAgg.PushEvents(user.NewHumanInitialCodeAddedEvent(ctx, initCode.Code, initCode.Expiry)) + events = append(events, user.NewHumanInitialCodeAddedEvent(ctx, userAgg, initCode.Code, initCode.Expiry)) } + if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified { - userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) + events = append(events, user.NewHumanEmailVerifiedEvent(ctx, userAgg)) } + if human.Phone != nil && human.PhoneNumber != "" && !human.IsPhoneVerified { phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode) if err != nil { return nil, nil, err } - userAgg.PushEvents(user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)) + events = append(events, user.NewHumanPhoneCodeAddedEvent(ctx, userAgg, phoneCode.Code, phoneCode.Expiry)) } else if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified { - userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx)) + events = append(events, user.NewHumanPhoneVerifiedEvent(ctx, userAgg)) } - return userAgg, addedHuman, nil + return events, addedHuman, nil } func (r *CommandSide) HumanSkipMFAInit(ctx context.Context, userID, resourceowner string) (err error) { @@ -152,18 +163,20 @@ func (r *CommandSide) HumanSkipMFAInit(ctx context.Context, userID, resourceowne if err != nil { return err } - if existingHuman.UserState == domain.UserStateUnspecified || existingHuman.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingHuman.UserState) { return caos_errs.ThrowNotFound(nil, "COMMAND-m9cV8", "Errors.User.NotFound") } - userAgg := UserAggregateFromWriteModel(&existingHuman.WriteModel) - userAgg.PushEvents(user.NewHumanMFAInitSkippedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingHuman, userAgg) + + _, err = r.eventstore.PushEvents(ctx, + user.NewHumanMFAInitSkippedEvent(ctx, UserAggregateFromWriteModel(&existingHuman.WriteModel))) + return err } -func createAddHumanEvent(ctx context.Context, orgID string, human *domain.Human, userLoginMustBeDomain bool) *user.HumanAddedEvent { +///TODO: adlerhurst maybe we can simplify createAddHumanEvent and createRegisterHumanEvent +func createAddHumanEvent(ctx context.Context, aggregate *eventstore.Aggregate, human *domain.Human, userLoginMustBeDomain bool) *user.HumanAddedEvent { addEvent := user.NewHumanAddedEvent( ctx, - orgID, + aggregate, human.Username, human.FirstName, human.LastName, @@ -191,10 +204,10 @@ func createAddHumanEvent(ctx context.Context, orgID string, human *domain.Human, return addEvent } -func createRegisterHumanEvent(ctx context.Context, orgID string, human *domain.Human, userLoginMustBeDomain bool) *user.HumanRegisteredEvent { +func createRegisterHumanEvent(ctx context.Context, aggregate *eventstore.Aggregate, human *domain.Human, userLoginMustBeDomain bool) *user.HumanRegisteredEvent { addEvent := user.NewHumanRegisteredEvent( ctx, - orgID, + aggregate, human.Username, human.FirstName, human.LastName, @@ -226,21 +239,22 @@ func (r *CommandSide) HumansSignOut(ctx context.Context, agentID string, userIDs if agentID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0ds", "Errors.User.UserIDMissing") } - aggregates := make([]eventstore.Aggregater, len(userIDs)) + events := make([]eventstore.EventPusher, len(userIDs)) for i, userID := range userIDs { existingUser, err := r.getHumanWriteModelByID(ctx, userID, "") if err != nil { return err } - if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted { + if !isUserStateExists(existingUser.UserState) { continue } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(user.NewHumanSignedOutEvent(ctx, agentID)) - aggregates[i] = userAgg + events[i] = user.NewHumanSignedOutEvent( + ctx, + UserAggregateFromWriteModel(&existingUser.WriteModel), + agentID) } - _, err := r.eventstore.PushAggregates(ctx, aggregates...) + _, err := r.eventstore.PushEvents(ctx, events...) return err } diff --git a/internal/v2/command/user_human_address.go b/internal/v2/command/user_human_address.go index beeb6f330b..2c877961c3 100644 --- a/internal/v2/command/user_human_address.go +++ b/internal/v2/command/user_human_address.go @@ -15,18 +15,19 @@ func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *domain.Ad if existingAddress.State == domain.AddressStateUnspecified || existingAddress.State == domain.AddressStateRemoved { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-0pLdo", "Errors.User.Address.NotFound") } - changedEvent, hasChanged := existingAddress.NewChangedEvent(ctx, address.Country, address.Locality, address.PostalCode, address.Region, address.StreetAddress) + userAgg := UserAggregateFromWriteModel(&existingAddress.WriteModel) + changedEvent, hasChanged := existingAddress.NewChangedEvent(ctx, userAgg, address.Country, address.Locality, address.PostalCode, address.Region, address.StreetAddress) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0cs", "Errors.User.Address.NotChanged") } - userAgg := UserAggregateFromWriteModel(&existingAddress.WriteModel) - userAgg.PushEvents(changedEvent) - - err = r.eventstore.PushAggregate(ctx, existingAddress, userAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingAddress, pushedEvents...) if err != nil { return nil, err } - return writeModelToAddress(existingAddress), nil } diff --git a/internal/v2/command/user_human_address_model.go b/internal/v2/command/user_human_address_model.go index 57b3374b67..dbf0328f54 100644 --- a/internal/v2/command/user_human_address_model.go +++ b/internal/v2/command/user_human_address_model.go @@ -29,10 +29,6 @@ func NewHumanAddressWriteModel(userID, resourceOwner string) *HumanAddressWriteM } } -func (wm *HumanAddressWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanAddressWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -76,11 +72,16 @@ func (wm *HumanAddressWriteModel) Reduce() error { func (wm *HumanAddressWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanAddressChangedType, + user.UserRemovedType) } func (wm *HumanAddressWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, country, locality, postalCode, @@ -88,7 +89,7 @@ func (wm *HumanAddressWriteModel) NewChangedEvent( streetAddress string, ) (*user.HumanAddressChangedEvent, bool) { hasChanged := false - changedEvent := user.NewHumanAddressChangedEvent(ctx) + changedEvent := user.NewHumanAddressChangedEvent(ctx, aggregate) if wm.Country != country { hasChanged = true changedEvent.Country = &country diff --git a/internal/v2/command/user_human_email.go b/internal/v2/command/user_human_email.go index 913804c57f..a6da180b68 100644 --- a/internal/v2/command/user_human_email.go +++ b/internal/v2/command/user_human_email.go @@ -5,6 +5,7 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/crypto" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" @@ -22,28 +23,32 @@ func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *domain.Email) if existingEmail.UserState == domain.UserStateUnspecified || existingEmail.UserState == domain.UserStateDeleted { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-0Pe4r", "Errors.User.Email.NotFound") } - changedEvent, hasChanged := existingEmail.NewChangedEvent(ctx, email.EmailAddress) + userAgg := UserAggregateFromWriteModel(&existingEmail.WriteModel) + changedEvent, hasChanged := existingEmail.NewChangedEvent(ctx, userAgg, email.EmailAddress) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2b7fM", "Errors.User.Email.NotChanged") } - userAgg := UserAggregateFromWriteModel(&existingEmail.WriteModel) - userAgg.PushEvents(changedEvent) + + events := []eventstore.EventPusher{changedEvent} if email.IsEmailVerified { - userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) + events = append(events, user.NewHumanEmailVerifiedEvent(ctx, userAgg)) } else { emailCode, err := domain.NewEmailCode(r.emailVerificationCode) if err != nil { return nil, err } - userAgg.PushEvents(user.NewHumanEmailCodeAddedEvent(ctx, emailCode.Code, emailCode.Expiry)) + events = append(events, user.NewHumanEmailCodeAddedEvent(ctx, userAgg, emailCode.Code, emailCode.Expiry)) } - err = r.eventstore.PushAggregate(ctx, existingEmail, userAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingEmail, pushedEvents...) if err != nil { return nil, err } - return writeModelToEmail(existingEmail), nil } @@ -66,12 +71,12 @@ func (r *CommandSide) VerifyHumanEmail(ctx context.Context, userID, code, resour userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, r.emailVerificationCode) if err == nil { - userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingCode, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanEmailVerifiedEvent(ctx, userAgg)) + return err } - userAgg.PushEvents(user.NewHumanEmailVerificationFailedEvent(ctx)) - err = r.eventstore.PushAggregate(ctx, existingCode, userAgg) - logging.LogWithFields("COMMAND-Dg2z5", "userID", userAgg.ID()).OnError(err).Error("NewHumanEmailVerificationFailedEvent push failed") + + _, err = r.eventstore.PushEvents(ctx, user.NewHumanEmailVerificationFailedEvent(ctx, userAgg)) + logging.LogWithFields("COMMAND-Dg2z5", "userID", userAgg.ID).OnError(err).Error("NewHumanEmailVerificationFailedEvent push failed") return caos_errs.ThrowInvalidArgument(err, "COMMAND-Gdsgs", "Errors.User.Code.Invalid") } @@ -98,9 +103,8 @@ func (r *CommandSide) CreateHumanEmailVerificationCode(ctx context.Context, user if err != nil { return err } - userAgg.PushEvents(user.NewHumanEmailCodeAddedEvent(ctx, emailCode.Code, emailCode.Expiry)) - - return r.eventstore.PushAggregate(ctx, existingEmail, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanEmailCodeAddedEvent(ctx, userAgg, emailCode.Code, emailCode.Expiry)) + return err } func (r *CommandSide) HumanEmailVerificationCodeSent(ctx context.Context, orgID, userID string) (err error) { @@ -112,8 +116,8 @@ func (r *CommandSide) HumanEmailVerificationCodeSent(ctx context.Context, orgID, return caos_errs.ThrowNotFound(nil, "COMMAND-6n8uH", "Errors.User.Email.NotFound") } userAgg := UserAggregateFromWriteModel(&existingEmail.WriteModel) - userAgg.PushEvents(user.NewHumanEmailCodeSentEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingEmail, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanEmailCodeSentEvent(ctx, userAgg)) + return err } func (r *CommandSide) emailWriteModel(ctx context.Context, userID, resourceOwner string) (writeModel *HumanEmailWriteModel, err error) { diff --git a/internal/v2/command/user_human_email_model.go b/internal/v2/command/user_human_email_model.go index a7ce888b48..3907db3ade 100644 --- a/internal/v2/command/user_human_email_model.go +++ b/internal/v2/command/user_human_email_model.go @@ -2,11 +2,12 @@ package command import ( "context" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) type HumanEmailWriteModel struct { @@ -31,10 +32,6 @@ func NewHumanEmailWriteModel(userID, resourceOwner string) *HumanEmailWriteModel } } -func (wm *HumanEmailWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanEmailWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -67,7 +64,13 @@ func (wm *HumanEmailWriteModel) Reduce() error { func (wm *HumanEmailWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanEmailChangedType, + user.HumanEmailCodeAddedType, + user.HumanEmailVerifiedType, + user.UserRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } @@ -76,10 +79,11 @@ func (wm *HumanEmailWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *HumanEmailWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, email string, ) (*user.HumanEmailChangedEvent, bool) { hasChanged := false - changedEvent := user.NewHumanEmailChangedEvent(ctx) + changedEvent := user.NewHumanEmailChangedEvent(ctx, aggregate) if wm.Email != email { hasChanged = true changedEvent.EmailAddress = email diff --git a/internal/v2/command/user_human_externalidp.go b/internal/v2/command/user_human_externalidp.go index 7edbcc5863..ef77c83f0d 100644 --- a/internal/v2/command/user_human_externalidp.go +++ b/internal/v2/command/user_human_externalidp.go @@ -2,6 +2,7 @@ package command import ( "context" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" @@ -9,65 +10,60 @@ import ( "github.com/caos/zitadel/internal/v2/repository/user" ) -func (r *CommandSide) BulkAddedHumanExternalIDP(ctx context.Context, userID, resourceOwner string, externalIDPs []*domain.ExternalIDP) error { - if externalIDPs == nil || len(externalIDPs) == 0 { +func (r *CommandSide) BulkAddedHumanExternalIDP(ctx context.Context, userID, resourceOwner string, externalIDPs []*domain.ExternalIDP) (err error) { + if len(externalIDPs) == 0 { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Ek9s", "Errors.User.ExternalIDP.MinimumExternalIDPNeeded") } - aggregates := make([]eventstore.Aggregater, len(externalIDPs)) + events := make([]eventstore.EventPusher, len(externalIDPs)) for i, externalIDP := range externalIDPs { externalIDPWriteModel := NewHumanExternalIDPWriteModel(userID, externalIDP.IDPConfigID, externalIDP.ExternalUserID, resourceOwner) userAgg := UserAggregateFromWriteModel(&externalIDPWriteModel.WriteModel) - err := r.addHumanExternalIDP(ctx, userAgg, externalIDP) + + events[i], err = r.addHumanExternalIDP(ctx, userAgg, externalIDP) if err != nil { return err } - aggregates[i] = userAgg } - _, err := r.eventstore.PushAggregates(ctx, aggregates...) + + _, err = r.eventstore.PushEvents(ctx, events...) return err } -func (r *CommandSide) addHumanExternalIDP(ctx context.Context, userAgg *user.Aggregate, externalIDP *domain.ExternalIDP) error { +func (r *CommandSide) addHumanExternalIDP(ctx context.Context, aggregate *eventstore.Aggregate, externalIDP *domain.ExternalIDP) (eventstore.EventPusher, error) { if !externalIDP.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid") } //TODO: check if idpconfig exists - userAgg.PushEvents(user.NewHumanExternalIDPAddedEvent(ctx, externalIDP.IDPConfigID, externalIDP.DisplayName, externalIDP.ExternalUserID)) - return nil + return user.NewHumanExternalIDPAddedEvent(ctx, aggregate, externalIDP.IDPConfigID, externalIDP.DisplayName, externalIDP.ExternalUserID), nil } func (r *CommandSide) RemoveHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP) error { - userAgg, writemodel, err := r.removeHumanExternalIDP(ctx, externalIDP, false) + event, err := r.removeHumanExternalIDP(ctx, externalIDP, false) if err != nil { return err } - return r.eventstore.PushAggregate(ctx, writemodel, userAgg) + _, err = r.eventstore.PushEvents(ctx, event) + return err } -func (r *CommandSide) removeHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP, cascade bool) (*user.Aggregate, *HumanExternalIDPWriteModel, error) { +func (r *CommandSide) removeHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP, cascade bool) (eventstore.EventPusher, error) { if externalIDP.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M9ds", "Errors.IDMissing") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M9ds", "Errors.IDMissing") } existingExternalIDP, err := r.externalIDPWriteModelByID(ctx, externalIDP.AggregateID, externalIDP.IDPConfigID, externalIDP.ExternalUserID, externalIDP.ResourceOwner) if err != nil { - return nil, nil, err + return nil, err } if existingExternalIDP.State == domain.ExternalIDPStateUnspecified || existingExternalIDP.State == domain.ExternalIDPStateRemoved { - return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-1M9xR", "Errors.User.ExternalIDP.NotFound") + return nil, caos_errs.ThrowNotFound(nil, "COMMAND-1M9xR", "Errors.User.ExternalIDP.NotFound") } userAgg := UserAggregateFromWriteModel(&existingExternalIDP.WriteModel) - if !cascade { - userAgg.PushEvents( - user.NewHumanExternalIDPRemovedEvent(ctx, externalIDP.IDPConfigID, externalIDP.ExternalUserID), - ) - } else { - userAgg.PushEvents( - user.NewHumanExternalIDPCascadeRemovedEvent(ctx, externalIDP.IDPConfigID, externalIDP.ExternalUserID), - ) + if cascade { + return user.NewHumanExternalIDPCascadeRemovedEvent(ctx, userAgg, externalIDP.IDPConfigID, externalIDP.ExternalUserID), nil } - return userAgg, existingExternalIDP, nil + return user.NewHumanExternalIDPRemovedEvent(ctx, userAgg, externalIDP.IDPConfigID, externalIDP.ExternalUserID), nil } func (r *CommandSide) HumanExternalLoginChecked(ctx context.Context, orgID, userID string, authRequest *domain.AuthRequest) (err error) { @@ -84,8 +80,8 @@ func (r *CommandSide) HumanExternalLoginChecked(ctx context.Context, orgID, user } userAgg := UserAggregateFromWriteModel(&existingHuman.WriteModel) - userAgg.PushEvents(user.NewHumanExternalIDPCheckSucceededEvent(ctx, authRequestDomainToAuthRequestInfo(authRequest))) - return r.eventstore.PushAggregate(ctx, existingHuman, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanExternalIDPCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest))) + return err } func (r *CommandSide) externalIDPWriteModelByID(ctx context.Context, userID, idpConfigID, externalUserID, resourceOwner string) (writeModel *HumanExternalIDPWriteModel, err error) { diff --git a/internal/v2/command/user_human_externalidp_model.go b/internal/v2/command/user_human_externalidp_model.go index 4551df2b3c..662cce535d 100644 --- a/internal/v2/command/user_human_externalidp_model.go +++ b/internal/v2/command/user_human_externalidp_model.go @@ -27,10 +27,6 @@ func NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resource } } -func (wm *HumanExternalIDPWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanExternalIDPWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -53,5 +49,9 @@ func (wm *HumanExternalIDPWriteModel) Reduce() error { func (wm *HumanExternalIDPWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanExternalIDPAddedType, + user.HumanExternalIDPRemovedType, + user.HumanExternalIDPCascadeRemovedType, + user.UserRemovedType) } diff --git a/internal/v2/command/user_human_init.go b/internal/v2/command/user_human_init.go index eac761c442..bcaafd3e23 100644 --- a/internal/v2/command/user_human_init.go +++ b/internal/v2/command/user_human_init.go @@ -5,6 +5,7 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/crypto" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" ) @@ -25,17 +26,19 @@ func (r *CommandSide) ResendInitialMail(ctx context.Context, userID, email, reso if existingCode.UserState != domain.UserStateInitial { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9sd", "Errors.User.AlreadyInitialised") } + var events []eventstore.EventPusher userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) if email != "" && existingCode.Email != email { - changedEvent, _ := existingCode.NewChangedEvent(ctx, email) - userAgg.PushEvents(changedEvent) + changedEvent, _ := existingCode.NewChangedEvent(ctx, userAgg, email) + events = append(events, changedEvent) } initCode, err := domain.NewInitUserCode(r.initializeUserCode) if err != nil { return err } - userAgg.PushEvents(user.NewHumanInitialCodeAddedEvent(ctx, initCode.Code, initCode.Expiry)) - return r.eventstore.PushAggregate(ctx, existingCode, userAgg) + events = append(events, user.NewHumanInitialCodeAddedEvent(ctx, userAgg, initCode.Code, initCode.Expiry)) + _, err = r.eventstore.PushEvents(ctx, events...) + return err } func (r *CommandSide) HumanVerifyInitCode(ctx context.Context, userID, resourceOwner, code, passwordString string) error { @@ -57,15 +60,15 @@ func (r *CommandSide) HumanVerifyInitCode(ctx context.Context, userID, resourceO userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, r.initializeUserCode) if err != nil { - userAgg.PushEvents(user.NewHumanInitializedCheckFailedEvent(ctx)) - err = r.eventstore.PushAggregate(ctx, existingCode, userAgg) - logging.LogWithFields("COMMAND-Dg2z5", "userID", userAgg.ID()).OnError(err).Error("NewHumanInitializedCheckFailedEvent push failed") + _, err = r.eventstore.PushEvents(ctx, user.NewHumanInitializedCheckFailedEvent(ctx, userAgg)) + logging.LogWithFields("COMMAND-Dg2z5", "userID", userAgg.ID).OnError(err).Error("NewHumanInitializedCheckFailedEvent push failed") return caos_errs.ThrowInvalidArgument(err, "COMMAND-11v6G", "Errors.User.Code.Invalid") } - - userAgg.PushEvents(user.NewHumanInitializedCheckSucceededEvent(ctx)) + events := []eventstore.EventPusher{ + user.NewHumanInitializedCheckSucceededEvent(ctx, userAgg), + } if !existingCode.IsEmailVerified { - userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) + events = append(events, user.NewHumanEmailVerifiedEvent(ctx, userAgg)) } if passwordString != "" { passwordWriteModel := NewHumanPasswordWriteModel(userID, existingCode.ResourceOwner) @@ -73,12 +76,15 @@ func (r *CommandSide) HumanVerifyInitCode(ctx context.Context, userID, resourceO SecretString: passwordString, ChangeRequired: false, } - err = r.changePassword(ctx, existingCode.ResourceOwner, userID, "", password, userAgg, passwordWriteModel) + passwordEvent, err := r.changePassword(ctx, "", password, userAgg, passwordWriteModel) if err != nil { return err } + events = append(events, passwordEvent) } - return r.eventstore.PushAggregate(ctx, existingCode, userAgg) + events = append(events, user.NewHumanInitialCodeSentEvent(ctx, userAgg)) + _, err = r.eventstore.PushEvents(ctx, events...) + return err } func (r *CommandSide) HumanInitCodeSent(ctx context.Context, orgID, userID string) (err error) { @@ -90,8 +96,8 @@ func (r *CommandSide) HumanInitCodeSent(ctx context.Context, orgID, userID strin return caos_errs.ThrowNotFound(nil, "COMMAND-556zg", "Errors.User.Code.NotFound") } userAgg := UserAggregateFromWriteModel(&existingInitCode.WriteModel) - userAgg.PushEvents(user.NewHumanInitialCodeSentEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingInitCode, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanInitialCodeSentEvent(ctx, userAgg)) + return err } func (r *CommandSide) getHumanInitWriteModelByID(ctx context.Context, userID, resourceowner string) (*HumanInitCodeWriteModel, error) { diff --git a/internal/v2/command/user_human_init_model.go b/internal/v2/command/user_human_init_model.go index 20edecf4cc..f6e2a868fc 100644 --- a/internal/v2/command/user_human_init_model.go +++ b/internal/v2/command/user_human_init_model.go @@ -2,11 +2,12 @@ package command import ( "context" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) type HumanInitCodeWriteModel struct { @@ -31,10 +32,6 @@ func NewHumanInitCodeWriteModel(userID, resourceOwner string) *HumanInitCodeWrit } } -func (wm *HumanInitCodeWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanInitCodeWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -68,7 +65,14 @@ func (wm *HumanInitCodeWriteModel) Reduce() error { func (wm *HumanInitCodeWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanEmailChangedType, + user.HumanEmailVerifiedType, + user.HumanInitialCodeAddedType, + user.HumanInitializedCheckSucceededType, + user.UserRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } @@ -77,10 +81,11 @@ func (wm *HumanInitCodeWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *HumanInitCodeWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, email string, ) (*user.HumanEmailChangedEvent, bool) { hasChanged := false - changedEvent := user.NewHumanEmailChangedEvent(ctx) + changedEvent := user.NewHumanEmailChangedEvent(ctx, aggregate) if wm.Email != email { hasChanged = true changedEvent.EmailAddress = email diff --git a/internal/v2/command/user_human_model.go b/internal/v2/command/user_human_model.go index 79f3d227b0..3fe424c1a9 100644 --- a/internal/v2/command/user_human_model.go +++ b/internal/v2/command/user_human_model.go @@ -47,11 +47,6 @@ func NewHumanWriteModel(userID, resourceOwner string) *HumanWriteModel { } } -func (wm *HumanWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - -//TODO: Compute OTPState? initial/active func (wm *HumanWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -99,7 +94,21 @@ func (wm *HumanWriteModel) Reduce() error { func (wm *HumanWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.UserUserNameChangedType, + user.HumanProfileChangedType, + user.HumanEmailChangedType, + user.HumanEmailVerifiedType, + user.HumanPhoneChangedType, + user.HumanPhoneVerifiedType, + user.HumanPasswordChangedType, + user.UserLockedType, + user.UserUnlockedType, + user.UserDeactivatedType, + user.UserReactivatedType, + user.UserRemovedType) } func (wm *HumanWriteModel) reduceHumanAddedEvent(e *user.HumanAddedEvent) { diff --git a/internal/v2/command/user_human_otp.go b/internal/v2/command/user_human_otp.go index b0a0151c31..10fbd01f13 100644 --- a/internal/v2/command/user_human_otp.go +++ b/internal/v2/command/user_human_otp.go @@ -45,11 +45,8 @@ func (r *CommandSide) AddHumanOTP(ctx context.Context, userID, resourceowner str if err != nil { return nil, err } - userAgg.PushEvents( - user.NewHumanOTPAddedEvent(ctx, secret), - ) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanOTPAddedEvent(ctx, userAgg, secret)) - err = r.eventstore.PushAggregate(ctx, otpWriteModel, userAgg) if err != nil { return nil, err } @@ -81,11 +78,9 @@ func (r *CommandSide) HumanCheckMFAOTPSetup(ctx context.Context, userID, code, u return err } userAgg := UserAggregateFromWriteModel(&existingOTP.WriteModel) - userAgg.PushEvents( - user.NewHumanOTPVerifiedEvent(ctx, userAgentID), - ) - return r.eventstore.PushAggregate(ctx, existingOTP, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanOTPVerifiedEvent(ctx, userAgg, userAgentID)) + return err } func (r *CommandSide) HumanCheckMFAOTP(ctx context.Context, userID, code, resourceowner string, authRequest *domain.AuthRequest) error { @@ -102,13 +97,10 @@ func (r *CommandSide) HumanCheckMFAOTP(ctx context.Context, userID, code, resour userAgg := UserAggregateFromWriteModel(&existingOTP.WriteModel) err = domain.VerifyMFAOTP(code, existingOTP.Secret, r.multifactors.OTP.CryptoMFA) if err == nil { - userAgg.PushEvents( - user.NewHumanOTPCheckSucceededEvent(ctx, authRequestDomainToAuthRequestInfo(authRequest)), - ) - return r.eventstore.PushAggregate(ctx, existingOTP, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanOTPCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest))) + return err } - userAgg.PushEvents(user.NewHumanOTPCheckFailedEvent(ctx, authRequestDomainToAuthRequestInfo(authRequest))) - pushErr := r.eventstore.PushAggregate(ctx, existingOTP, userAgg) + _, pushErr := r.eventstore.PushEvents(ctx, user.NewHumanOTPCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest))) logging.Log("COMMAND-9fj7s").OnError(pushErr).Error("error create password check failed event") return err } @@ -126,11 +118,8 @@ func (r *CommandSide) HumanRemoveOTP(ctx context.Context, userID, resourceOwner return caos_errs.ThrowNotFound(nil, "COMMAND-Hd9sd", "Errors.User.MFA.OTP.NotExisting") } userAgg := UserAggregateFromWriteModel(&existingOTP.WriteModel) - userAgg.PushEvents( - user.NewHumanOTPRemovedEvent(ctx), - ) - - return r.eventstore.PushAggregate(ctx, existingOTP, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanOTPRemovedEvent(ctx, userAgg)) + return err } func (r *CommandSide) otpWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *HumanOTPWriteModel, err error) { diff --git a/internal/v2/command/user_human_otp_model.go b/internal/v2/command/user_human_otp_model.go index 2e37e4699a..fb0ca7eee2 100644 --- a/internal/v2/command/user_human_otp_model.go +++ b/internal/v2/command/user_human_otp_model.go @@ -23,10 +23,6 @@ func NewHumanOTPWriteModel(userID, resourceOwner string) *HumanOTPWriteModel { } } -func (wm *HumanOTPWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanOTPWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -46,7 +42,11 @@ func (wm *HumanOTPWriteModel) Reduce() error { func (wm *HumanOTPWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes(user.HumanMFAOTPAddedType, + user.HumanMFAOTPVerifiedType, + user.HumanMFAOTPRemovedType, + user.UserRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } diff --git a/internal/v2/command/user_human_password.go b/internal/v2/command/user_human_password.go index 0a0d0a316c..1ae2f88ad2 100644 --- a/internal/v2/command/user_human_password.go +++ b/internal/v2/command/user_human_password.go @@ -2,6 +2,8 @@ package command import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/logging" "github.com/caos/zitadel/internal/crypto" caos_errs "github.com/caos/zitadel/internal/errors" @@ -23,7 +25,12 @@ func (r *CommandSide) SetOneTimePassword(ctx context.Context, orgID, userID, pas ChangeRequired: true, } userAgg := UserAggregateFromWriteModel(&existingPassword.WriteModel) - return r.changePassword(ctx, orgID, userID, "", password, userAgg, existingPassword) + passwordEvent, err := r.changePassword(ctx, "", password, userAgg, existingPassword) + if err != nil { + return err + } + _, err = r.eventstore.PushEvents(ctx, passwordEvent) + return err } func (r *CommandSide) SetPassword(ctx context.Context, orgID, userID, code, passwordString, userAgentID string) (err error) { @@ -49,7 +56,12 @@ func (r *CommandSide) SetPassword(ctx context.Context, orgID, userID, code, pass ChangeRequired: false, } userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) - return r.changePassword(ctx, existingCode.ResourceOwner, userID, userAgentID, password, userAgg, existingCode) + passwordEvent, err := r.changePassword(ctx, userAgentID, password, userAgg, existingCode) + if err != nil { + return err + } + _, err = r.eventstore.PushEvents(ctx, passwordEvent) + return err } func (r *CommandSide) ChangePassword(ctx context.Context, orgID, userID, oldPassword, newPassword, userAgentID string) (err error) { @@ -76,31 +88,32 @@ func (r *CommandSide) ChangePassword(ctx context.Context, orgID, userID, oldPass } userAgg := UserAggregateFromWriteModel(&existingPassword.WriteModel) - return r.changePassword(ctx, orgID, userID, userAgentID, password, userAgg, existingPassword) -} - -func (r *CommandSide) changePassword(ctx context.Context, orgID, userID, userAgentID string, password *domain.Password, userAgg *user.Aggregate, existingPassword *HumanPasswordWriteModel) (err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - if userID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-B8hY3", "Errors.User.UserIDMissing") - } - if existingPassword.UserState == domain.UserStateUnspecified || existingPassword.UserState == domain.UserStateDeleted { - return caos_errs.ThrowNotFound(nil, "COMMAND-G8dh3", "Errors.User.Email.NotFound") - } - if existingPassword.UserState == domain.UserStateInitial { - return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-M9dse", "Errors.User.NotInitialised") - } - pwPolicy, err := r.getOrgPasswordComplexityPolicy(ctx, orgID) + eventPusher, err := r.changePassword(ctx, userAgentID, password, userAgg, existingPassword) if err != nil { return err } - if err := password.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg); err != nil { - return err + _, err = r.eventstore.PushEvents(ctx, eventPusher) + return err +} + +func (r *CommandSide) changePassword(ctx context.Context, userAgentID string, password *domain.Password, userAgg *eventstore.Aggregate, existingPassword *HumanPasswordWriteModel) (event eventstore.EventPusher, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + if existingPassword.UserState == domain.UserStateUnspecified || existingPassword.UserState == domain.UserStateDeleted { + return nil, caos_errs.ThrowNotFound(nil, "COMMAND-G8dh3", "Errors.User.Email.NotFound") } - userAgg.PushEvents(user.NewHumanPasswordChangedEvent(ctx, password.SecretCrypto, password.ChangeRequired, userAgentID)) - return r.eventstore.PushAggregate(ctx, existingPassword, userAgg) + if existingPassword.UserState == domain.UserStateInitial { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-M9dse", "Errors.User.NotInitialised") + } + pwPolicy, err := r.getOrgPasswordComplexityPolicy(ctx, userAgg.ResourceOwner) + if err != nil { + return nil, err + } + if err := password.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg); err != nil { + return nil, err + } + return user.NewHumanPasswordChangedEvent(ctx, userAgg, password.SecretCrypto, password.ChangeRequired, userAgentID), nil } func (r *CommandSide) RequestSetPassword(ctx context.Context, userID, resourceOwner string, notifyType domain.NotificationType) (err error) { @@ -119,8 +132,8 @@ func (r *CommandSide) RequestSetPassword(ctx context.Context, userID, resourceOw if err != nil { return err } - userAgg.PushEvents(user.NewHumanPasswordCodeAddedEvent(ctx, passwordCode.Code, passwordCode.Expiry, notifyType)) - return r.eventstore.PushAggregate(ctx, existingHuman, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPasswordCodeAddedEvent(ctx, userAgg, passwordCode.Code, passwordCode.Expiry, notifyType)) + return err } func (r *CommandSide) PasswordCodeSent(ctx context.Context, orgID, userID string) (err error) { @@ -132,8 +145,8 @@ func (r *CommandSide) PasswordCodeSent(ctx context.Context, orgID, userID string return caos_errs.ThrowNotFound(nil, "COMMAND-3n77z", "Errors.User.NotFound") } userAgg := UserAggregateFromWriteModel(&existingPassword.WriteModel) - userAgg.PushEvents(user.NewHumanPasswordCodeSentEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPassword, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPasswordCodeSentEvent(ctx, userAgg)) + return err } func (r *CommandSide) HumanCheckPassword(ctx context.Context, orgID, userID, password string, authRequest *domain.AuthRequest) (err error) { @@ -161,12 +174,10 @@ func (r *CommandSide) HumanCheckPassword(ctx context.Context, orgID, userID, pas err = crypto.CompareHash(existingPassword.Secret, []byte(password), r.userPasswordAlg) spanPasswordComparison.EndWithError(err) if err == nil { - userAgg.PushEvents(user.NewHumanPasswordCheckSucceededEvent(ctx, authRequestDomainToAuthRequestInfo(authRequest))) - return r.eventstore.PushAggregate(ctx, existingPassword, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest))) + return err } - - userAgg.PushEvents(user.NewHumanPasswordCheckFailedEvent(ctx, authRequestDomainToAuthRequestInfo(authRequest))) - err = r.eventstore.PushAggregate(ctx, existingPassword, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPasswordCheckFailedEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest))) logging.Log("COMMAND-9fj7s").OnError(err).Error("error create password check failed event") return caos_errs.ThrowInvalidArgument(nil, "COMMAND-452ad", "Errors.User.Password.Invalid") } diff --git a/internal/v2/command/user_human_password_model.go b/internal/v2/command/user_human_password_model.go index c03f60f4bf..707eb0c3df 100644 --- a/internal/v2/command/user_human_password_model.go +++ b/internal/v2/command/user_human_password_model.go @@ -1,11 +1,12 @@ package command import ( + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) type HumanPasswordWriteModel struct { @@ -30,10 +31,6 @@ func NewHumanPasswordWriteModel(userID, resourceOwner string) *HumanPasswordWrit } } -func (wm *HumanPasswordWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanPasswordWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -66,7 +63,13 @@ func (wm *HumanPasswordWriteModel) Reduce() error { func (wm *HumanPasswordWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanPasswordChangedType, + user.HumanPasswordCodeAddedType, + user.HumanEmailVerifiedType, + user.UserRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } diff --git a/internal/v2/command/user_human_phone.go b/internal/v2/command/user_human_phone.go index 1f00e99e35..561a77cf81 100644 --- a/internal/v2/command/user_human_phone.go +++ b/internal/v2/command/user_human_phone.go @@ -2,9 +2,11 @@ package command import ( "context" + "github.com/caos/logging" "github.com/caos/zitadel/internal/crypto" caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" @@ -22,24 +24,29 @@ func (r *CommandSide) ChangeHumanPhone(ctx context.Context, phone *domain.Phone) if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-aM9cs", "Errors.User.Phone.NotFound") } - changedEvent, hasChanged := existingPhone.NewChangedEvent(ctx, phone.PhoneNumber) + + userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) + changedEvent, hasChanged := existingPhone.NewChangedEvent(ctx, userAgg, phone.PhoneNumber) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-wF94r", "Errors.User.Phone.NotChanged") } - userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) - userAgg.PushEvents(changedEvent) + events := []eventstore.EventPusher{changedEvent} if phone.IsPhoneVerified { - userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx)) + events = append(events, user.NewHumanPhoneVerifiedEvent(ctx, userAgg)) } else { phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode) if err != nil { return nil, err } - userAgg.PushEvents(user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)) + events = append(events, user.NewHumanPhoneCodeAddedEvent(ctx, userAgg, phoneCode.Code, phoneCode.Expiry)) } - err = r.eventstore.PushAggregate(ctx, existingPhone, userAgg) + pushedEvents, err := r.eventstore.PushEvents(ctx, events...) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingPhone, pushedEvents...) if err != nil { return nil, err } @@ -64,22 +71,14 @@ func (r *CommandSide) VerifyHumanPhone(ctx context.Context, userID, code, resour } userAgg := UserAggregateFromWriteModel(&existingCode.WriteModel) - err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, r.emailVerificationCode) + err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, r.phoneVerificationCode) if err == nil { - userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingCode, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPhoneVerifiedEvent(ctx, userAgg)) + return err } - userAgg.PushEvents(user.NewHumanPhoneVerificationFailedEvent(ctx)) - err = r.eventstore.PushAggregate(ctx, existingCode, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPhoneVerificationFailedEvent(ctx, userAgg)) - err = crypto.VerifyCode(existingCode.CodeCreationDate, existingCode.CodeExpiry, existingCode.Code, code, r.emailVerificationCode) - if err == nil { - userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingCode, userAgg) - } - userAgg.PushEvents(user.NewHumanEmailVerificationFailedEvent(ctx)) - err = r.eventstore.PushAggregate(ctx, existingCode, userAgg) - logging.LogWithFields("COMMAND-5M9ds", "userID", userAgg.ID()).OnError(err).Error("NewHumanEmailVerificationFailedEvent push failed") + logging.LogWithFields("COMMAND-5M9ds", "userID", userAgg.ID).OnError(err).Error("NewHumanPhoneVerificationFailedEvent push failed") return caos_errs.ThrowInvalidArgument(err, "COMMAND-sM0cs", "Errors.User.Code.Invalid") } @@ -92,19 +91,23 @@ func (r *CommandSide) CreateHumanPhoneVerificationCode(ctx context.Context, user if err != nil { return err } + + //TODO: code like the following if is written many times find way to simplify if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-2b7Hf", "Errors.User.Phone.NotFound") } if existingPhone.IsPhoneVerified { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9sf", "Errors.User.Phone.AlreadyVerified") } - userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) + phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode) if err != nil { return err } - userAgg.PushEvents(user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)) - return r.eventstore.PushAggregate(ctx, existingPhone, userAgg) + + userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPhoneCodeAddedEvent(ctx, userAgg, phoneCode.Code, phoneCode.Expiry)) + return err } func (r *CommandSide) HumanPhoneVerificationCodeSent(ctx context.Context, orgID, userID string) (err error) { @@ -115,9 +118,10 @@ func (r *CommandSide) HumanPhoneVerificationCodeSent(ctx context.Context, orgID, if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-66n8J", "Errors.User.Phone.NotFound") } + userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) - userAgg.PushEvents(user.NewHumanPhoneCodeSentEvent(ctx)) - return r.eventstore.PushAggregate(ctx, existingPhone, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPhoneCodeSentEvent(ctx, userAgg)) + return err } func (r *CommandSide) RemoveHumanPhone(ctx context.Context, userID, resourceOwner string) error { @@ -132,11 +136,10 @@ func (r *CommandSide) RemoveHumanPhone(ctx context.Context, userID, resourceOwne if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-p6rsc", "Errors.User.Phone.NotFound") } + userAgg := UserAggregateFromWriteModel(&existingPhone.WriteModel) - userAgg.PushEvents( - user.NewHumanPhoneRemovedEvent(ctx), - ) - return r.eventstore.PushAggregate(ctx, existingPhone, userAgg) + _, err = r.eventstore.PushEvents(ctx, user.NewHumanPhoneRemovedEvent(ctx, userAgg)) + return err } func (r *CommandSide) phoneWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *HumanPhoneWriteModel, err error) { diff --git a/internal/v2/command/user_human_phone_model.go b/internal/v2/command/user_human_phone_model.go index 381ff6ff18..d74e260ec5 100644 --- a/internal/v2/command/user_human_phone_model.go +++ b/internal/v2/command/user_human_phone_model.go @@ -2,11 +2,12 @@ package command import ( "context" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) type HumanPhoneWriteModel struct { @@ -31,10 +32,6 @@ func NewHumanPhoneWriteModel(userID, resourceOwner string) *HumanPhoneWriteModel } } -func (wm *HumanPhoneWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanPhoneWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -72,15 +69,23 @@ func (wm *HumanPhoneWriteModel) Reduce() error { func (wm *HumanPhoneWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanPhoneChangedType, + user.HumanPhoneVerifiedType, + user.HumanPhoneCodeAddedType, + user.HumanPhoneRemovedType, + user.UserRemovedType) } func (wm *HumanPhoneWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, phone string, ) (*user.HumanPhoneChangedEvent, bool) { hasChanged := false - changedEvent := user.NewHumanPhoneChangedEvent(ctx) + changedEvent := user.NewHumanPhoneChangedEvent(ctx, aggregate) if wm.Phone != phone { hasChanged = true changedEvent.PhoneNumber = phone diff --git a/internal/v2/command/user_human_profile.go b/internal/v2/command/user_human_profile.go index 9388407bc8..b9f900985d 100644 --- a/internal/v2/command/user_human_profile.go +++ b/internal/v2/command/user_human_profile.go @@ -2,6 +2,7 @@ package command import ( "context" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" @@ -23,10 +24,12 @@ func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *domain.Pr if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0fs", "Errors.User.Profile.NotChanged") } - userAgg := UserAggregateFromWriteModel(&existingProfile.WriteModel) - userAgg.PushEvents(changedEvent) - err = r.eventstore.PushAggregate(ctx, existingProfile, userAgg) + events, err := r.eventstore.PushEvents(ctx, changedEvent) + if err != nil { + return nil, err + } + err = AppendAndReduce(existingProfile, events...) if err != nil { return nil, err } diff --git a/internal/v2/command/user_human_profile_model.go b/internal/v2/command/user_human_profile_model.go index 8d15988833..17e08effe9 100644 --- a/internal/v2/command/user_human_profile_model.go +++ b/internal/v2/command/user_human_profile_model.go @@ -32,10 +32,6 @@ func NewHumanProfileWriteModel(userID, resourceOwner string) *HumanProfileWriteM } } -func (wm *HumanProfileWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - func (wm *HumanProfileWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { @@ -84,7 +80,11 @@ func (wm *HumanProfileWriteModel) Reduce() error { func (wm *HumanProfileWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanAddedType, + user.HumanRegisteredType, + user.HumanProfileChangedType, + user.UserRemovedType) } func (wm *HumanProfileWriteModel) NewChangedEvent( @@ -97,7 +97,7 @@ func (wm *HumanProfileWriteModel) NewChangedEvent( gender domain.Gender, ) (*user.HumanProfileChangedEvent, bool) { hasChanged := false - changedEvent := user.NewHumanProfileChangedEvent(ctx) + changedEvent := user.NewHumanProfileChangedEvent(ctx, UserAggregateFromWriteModel(&wm.WriteModel)) if wm.FirstName != firstName { hasChanged = true changedEvent.FirstName = firstName diff --git a/internal/v2/command/user_human_webauthn.go b/internal/v2/command/user_human_webauthn.go index ebdf81bb32..e0aa2c5f2f 100644 --- a/internal/v2/command/user_human_webauthn.go +++ b/internal/v2/command/user_human_webauthn.go @@ -2,6 +2,7 @@ package command import ( "context" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/telemetry/tracing" @@ -70,12 +71,16 @@ func (r *CommandSide) HumanAddU2FSetup(ctx context.Context, userID, resourceowne if err != nil { return nil, err } - userAgg.PushEvents(usr_repo.NewHumanU2FAddedEvent(ctx, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) - err = r.eventstore.PushAggregate(ctx, addWebAuthN, userAgg) + events, err := r.eventstore.PushEvents(ctx, usr_repo.NewHumanU2FAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) if err != nil { return nil, err } + err = AppendAndReduce(addWebAuthN, events...) + if err != nil { + return nil, err + } + createdWebAuthN := writeModelToWebAuthN(addWebAuthN) createdWebAuthN.CredentialCreationData = webAuthN.CredentialCreationData createdWebAuthN.AllowedCredentialIDs = webAuthN.AllowedCredentialIDs @@ -92,12 +97,16 @@ func (r *CommandSide) HumanAddPasswordlessSetup(ctx context.Context, userID, res if err != nil { return nil, err } - userAgg.PushEvents(usr_repo.NewHumanPasswordlessAddedEvent(ctx, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) - err = r.eventstore.PushAggregate(ctx, addWebAuthN, userAgg) + events, err := r.eventstore.PushEvents(ctx, usr_repo.NewHumanPasswordlessAddedEvent(ctx, userAgg, addWebAuthN.WebauthNTokenID, webAuthN.Challenge)) if err != nil { return nil, err } + err = AppendAndReduce(addWebAuthN, events...) + if err != nil { + return nil, err + } + createdWebAuthN := writeModelToWebAuthN(addWebAuthN) createdWebAuthN.CredentialCreationData = webAuthN.CredentialCreationData createdWebAuthN.AllowedCredentialIDs = webAuthN.AllowedCredentialIDs @@ -105,7 +114,7 @@ func (r *CommandSide) HumanAddPasswordlessSetup(ctx context.Context, userID, res return createdWebAuthN, nil } -func (r *CommandSide) addHumanWebAuthN(ctx context.Context, userID, resourceowner string, isLoginUI bool, tokens []*domain.WebAuthNToken) (*HumanWebAuthNWriteModel, *usr_repo.Aggregate, *domain.WebAuthNToken, error) { +func (r *CommandSide) addHumanWebAuthN(ctx context.Context, userID, resourceowner string, isLoginUI bool, tokens []*domain.WebAuthNToken) (*HumanWebAuthNWriteModel, *eventstore.Aggregate, *domain.WebAuthNToken, error) { if userID == "" || resourceowner == "" { return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0od", "Errors.IDMissing") } @@ -147,14 +156,16 @@ func (r *CommandSide) HumanVerifyU2FSetup(ctx context.Context, userID, resourceo if err != nil { return err } - verifyWebAuthN, userAgg, webAuthN, err := r.verifyHumanWebAuthN(ctx, userID, resourceowner, tokenName, userAgentID, credentialData, u2fTokens) + userAgg, webAuthN, verifyWebAuthN, err := r.verifyHumanWebAuthN(ctx, userID, resourceowner, tokenName, userAgentID, credentialData, u2fTokens) if err != nil { return err } - userAgg.PushEvents( + + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanU2FVerifiedEvent( ctx, - verifyWebAuthN.WebauthNTokenID, + userAgg, + verifyWebAuthN.WebauthNTokenID, //TODO: webAuthN andverifyWebAuthN same TokenID? webAuthN.WebAuthNTokenName, webAuthN.AttestationType, webAuthN.KeyID, @@ -163,8 +174,7 @@ func (r *CommandSide) HumanVerifyU2FSetup(ctx context.Context, userID, resourceo webAuthN.SignCount, ), ) - - return r.eventstore.PushAggregate(ctx, verifyWebAuthN, userAgg) + return err } func (r *CommandSide) HumanHumanPasswordlessSetup(ctx context.Context, userID, resourceowner, tokenName, userAgentID string, credentialData []byte) error { @@ -172,14 +182,16 @@ func (r *CommandSide) HumanHumanPasswordlessSetup(ctx context.Context, userID, r if err != nil { return err } - verifyWebAuthN, userAgg, webAuthN, err := r.verifyHumanWebAuthN(ctx, userID, resourceowner, tokenName, userAgentID, credentialData, u2fTokens) + userAgg, webAuthN, verifyWebAuthN, err := r.verifyHumanWebAuthN(ctx, userID, resourceowner, tokenName, userAgentID, credentialData, u2fTokens) if err != nil { return err } - userAgg.PushEvents( + + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanPasswordlessVerifiedEvent( ctx, - verifyWebAuthN.WebauthNTokenID, + userAgg, + verifyWebAuthN.WebauthNTokenID, //TODO: webAuthN andverifyWebAuthN same TokenID? webAuthN.WebAuthNTokenName, webAuthN.AttestationType, webAuthN.KeyID, @@ -188,10 +200,10 @@ func (r *CommandSide) HumanHumanPasswordlessSetup(ctx context.Context, userID, r webAuthN.SignCount, ), ) - return r.eventstore.PushAggregate(ctx, verifyWebAuthN, userAgg) + return err } -func (r *CommandSide) verifyHumanWebAuthN(ctx context.Context, userID, resourceowner, tokenName, userAgentID string, credentialData []byte, tokens []*domain.WebAuthNToken) (*HumanWebAuthNWriteModel, *usr_repo.Aggregate, *domain.WebAuthNToken, error) { +func (r *CommandSide) verifyHumanWebAuthN(ctx context.Context, userID, resourceowner, tokenName, userAgentID string, credentialData []byte, tokens []*domain.WebAuthNToken) (*eventstore.Aggregate, *domain.WebAuthNToken, *HumanWebAuthNWriteModel, error) { if userID == "" || resourceowner == "" { return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0od", "Errors.IDMissing") } @@ -211,7 +223,7 @@ func (r *CommandSide) verifyHumanWebAuthN(ctx context.Context, userID, resourceo } userAgg := UserAggregateFromWriteModel(&verifyWebAuthN.WriteModel) - return verifyWebAuthN, userAgg, webAuthN, nil + return userAgg, webAuthN, verifyWebAuthN, nil } func (r *CommandSide) HumanBeginU2FLogin(ctx context.Context, userID, resourceOwner string, authRequest *domain.AuthRequest, isLoginUI bool) (*domain.WebAuthNLogin, error) { @@ -220,19 +232,20 @@ func (r *CommandSide) HumanBeginU2FLogin(ctx context.Context, userID, resourceOw return nil, err } - writeModel, userAgg, webAuthNLogin, err := r.beginWebAuthNLogin(ctx, userID, resourceOwner, u2fTokens, isLoginUI) + userAgg, webAuthNLogin, err := r.beginWebAuthNLogin(ctx, userID, resourceOwner, u2fTokens, isLoginUI) if err != nil { return nil, err } - userAgg.PushEvents( + + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanU2FBeginLoginEvent( ctx, + userAgg, webAuthNLogin.Challenge, authRequestDomainToAuthRequestInfo(authRequest), ), ) - err = r.eventstore.PushAggregate(ctx, writeModel, userAgg) return webAuthNLogin, err } @@ -242,42 +255,42 @@ func (r *CommandSide) HumanBeginPasswordlessLogin(ctx context.Context, userID, r return nil, err } - writeModel, userAgg, webAuthNLogin, err := r.beginWebAuthNLogin(ctx, userID, resourceOwner, u2fTokens, isLoginUI) + userAgg, webAuthNLogin, err := r.beginWebAuthNLogin(ctx, userID, resourceOwner, u2fTokens, isLoginUI) if err != nil { return nil, err } - userAgg.PushEvents( + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanPasswordlessBeginLoginEvent( ctx, + userAgg, webAuthNLogin.Challenge, authRequestDomainToAuthRequestInfo(authRequest), ), ) - - err = r.eventstore.PushAggregate(ctx, writeModel, userAgg) return webAuthNLogin, err } -func (r *CommandSide) beginWebAuthNLogin(ctx context.Context, userID, resourceOwner string, tokens []*domain.WebAuthNToken, isLoginUI bool) (*HumanWebAuthNWriteModel, *usr_repo.Aggregate, *domain.WebAuthNLogin, error) { +func (r *CommandSide) beginWebAuthNLogin(ctx context.Context, userID, resourceOwner string, tokens []*domain.WebAuthNToken, isLoginUI bool) (*eventstore.Aggregate, *domain.WebAuthNLogin, error) { if userID == "" { - return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-hh8K9", "Errors.IDMissing") + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-hh8K9", "Errors.IDMissing") } human, err := r.getHuman(ctx, userID, resourceOwner) if err != nil { - return nil, nil, nil, err + return nil, nil, err } webAuthNLogin, err := r.webauthn.BeginLogin(human, domain.UserVerificationRequirementDiscouraged, isLoginUI, tokens...) if err != nil { - return nil, nil, nil, err - } - writeModel, err := r.webauthNWriteModelByID(ctx, userID, "", resourceOwner) - if err != nil { - return nil, nil, nil, err + return nil, nil, err } + writeModel, err := r.webauthNWriteModelByID(ctx, userID, "", resourceOwner) + if err != nil { + return nil, nil, err + } userAgg := UserAggregateFromWriteModel(&writeModel.WriteModel) - return writeModel, userAgg, webAuthNLogin, nil + + return userAgg, webAuthNLogin, nil } func (r *CommandSide) HumanFinishU2FLogin(ctx context.Context, userID, resourceOwner string, credentialData []byte, authRequest *domain.AuthRequest, isLoginUI bool) error { @@ -290,19 +303,21 @@ func (r *CommandSide) HumanFinishU2FLogin(ctx context.Context, userID, resourceO return err } - writeModel, userAgg, token, signCount, err := r.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, u2fTokens, isLoginUI) + userAgg, token, signCount, err := r.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, u2fTokens, isLoginUI) if err != nil { return err } - userAgg.PushEvents( + + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanU2FSignCountChangedEvent( ctx, + userAgg, token.WebAuthNTokenID, signCount, ), ) - return r.eventstore.PushAggregate(ctx, writeModel, userAgg) + return err } func (r *CommandSide) HumanFinishPasswordlessLogin(ctx context.Context, userID, resourceOwner string, credentialData []byte, authRequest *domain.AuthRequest, isLoginUI bool) error { @@ -316,59 +331,61 @@ func (r *CommandSide) HumanFinishPasswordlessLogin(ctx context.Context, userID, return err } - writeModel, userAgg, token, signCount, err := r.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, passwordlessTokens, isLoginUI) + userAgg, token, signCount, err := r.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, passwordlessTokens, isLoginUI) if err != nil { return err } - userAgg.PushEvents( + + _, err = r.eventstore.PushEvents(ctx, usr_repo.NewHumanPasswordlessSignCountChangedEvent( ctx, + userAgg, token.WebAuthNTokenID, signCount, ), ) - - return r.eventstore.PushAggregate(ctx, writeModel, userAgg) + return err } -func (r *CommandSide) finishWebAuthNLogin(ctx context.Context, userID, resourceOwner string, credentialData []byte, webAuthN *domain.WebAuthNLogin, tokens []*domain.WebAuthNToken, isLoginUI bool) (*HumanWebAuthNWriteModel, *usr_repo.Aggregate, *domain.WebAuthNToken, uint32, error) { +func (r *CommandSide) finishWebAuthNLogin(ctx context.Context, userID, resourceOwner string, credentialData []byte, webAuthN *domain.WebAuthNLogin, tokens []*domain.WebAuthNToken, isLoginUI bool) (*eventstore.Aggregate, *domain.WebAuthNToken, uint32, error) { if userID == "" { - return nil, nil, nil, 0, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-hh8K9", "Errors.IDMissing") + return nil, nil, 0, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-hh8K9", "Errors.IDMissing") } human, err := r.getHuman(ctx, userID, resourceOwner) if err != nil { - return nil, nil, nil, 0, err + return nil, nil, 0, err } keyID, signCount, err := r.webauthn.FinishLogin(human, webAuthN, credentialData, isLoginUI, tokens...) if err != nil && keyID == nil { - return nil, nil, nil, 0, err + return nil, nil, 0, err } _, token := domain.GetTokenByKeyID(tokens, keyID) if token == nil { - return nil, nil, nil, 0, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3b7zs", "Errors.User.WebAuthN.NotFound") - } - writeModel, err := r.webauthNWriteModelByID(ctx, userID, "", resourceOwner) - if err != nil { - return nil, nil, nil, 0, err + return nil, nil, 0, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3b7zs", "Errors.User.WebAuthN.NotFound") } + writeModel, err := r.webauthNWriteModelByID(ctx, userID, "", resourceOwner) + if err != nil { + return nil, nil, 0, err + } userAgg := UserAggregateFromWriteModel(&writeModel.WriteModel) - return writeModel, userAgg, token, signCount, nil + + return userAgg, token, signCount, nil } func (r *CommandSide) HumanRemoveU2F(ctx context.Context, userID, webAuthNID, resourceOwner string) error { - event := usr_repo.NewHumanU2FRemovedEvent(ctx, webAuthNID) + event := usr_repo.PrepareHumanU2FRemovedEvent(ctx, webAuthNID) return r.removeHumanWebAuthN(ctx, userID, webAuthNID, resourceOwner, event) } func (r *CommandSide) HumanRemovePasswordless(ctx context.Context, userID, webAuthNID, resourceOwner string) error { - event := usr_repo.NewHumanPasswordlessRemovedEvent(ctx, webAuthNID) + event := usr_repo.PrepareHumanPasswordlessRemovedEvent(ctx, webAuthNID) return r.removeHumanWebAuthN(ctx, userID, webAuthNID, resourceOwner, event) } -func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNID, resourceOwner string, event eventstore.EventPusher) error { +func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNID, resourceOwner string, preparedEvent func(*eventstore.Aggregate) eventstore.EventPusher) error { if userID == "" || webAuthNID == "" { return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M9de", "Errors.IDMissing") } @@ -380,10 +397,10 @@ func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNI if existingWebAuthN.State == domain.MFAStateUnspecified || existingWebAuthN.State == domain.MFAStateRemoved { return caos_errs.ThrowNotFound(nil, "COMMAND-2M9ds", "Errors.User.ExternalIDP.NotFound") } - userAgg := UserAggregateFromWriteModel(&existingWebAuthN.WriteModel) - userAgg.PushEvents(event) - return r.eventstore.PushAggregate(ctx, existingWebAuthN, userAgg) + userAgg := UserAggregateFromWriteModel(&existingWebAuthN.WriteModel) + _, err = r.eventstore.PushEvents(ctx, preparedEvent(userAgg)) + return err } func (r *CommandSide) webauthNWriteModelByID(ctx context.Context, userID, webAuthNID, resourceOwner string) (writeModel *HumanWebAuthNWriteModel, err error) { diff --git a/internal/v2/command/user_human_webauthn_model.go b/internal/v2/command/user_human_webauthn_model.go index 85f17b0d5a..2874c6ad9c 100644 --- a/internal/v2/command/user_human_webauthn_model.go +++ b/internal/v2/command/user_human_webauthn_model.go @@ -22,13 +22,13 @@ type HumanWebAuthNWriteModel struct { State domain.MFAState } -func NewHumanWebAuthNWriteModel(userID, wbAuthNTokenID, resourceOwner string) *HumanWebAuthNWriteModel { +func NewHumanWebAuthNWriteModel(userID, webAuthNTokenID, resourceOwner string) *HumanWebAuthNWriteModel { return &HumanWebAuthNWriteModel{ WriteModel: eventstore.WriteModel{ AggregateID: userID, ResourceOwner: resourceOwner, }, - WebauthNTokenID: wbAuthNTokenID, + WebauthNTokenID: webAuthNTokenID, } } @@ -94,7 +94,16 @@ func (wm *HumanWebAuthNWriteModel) appendVerifiedEvent(e *user.HumanWebAuthNVeri func (wm *HumanWebAuthNWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.HumanU2FTokenAddedType, + user.HumanPasswordlessTokenAddedType, + user.HumanU2FTokenAddedType, + user.HumanPasswordlessTokenAddedType, + user.HumanU2FTokenSignCountChangedType, + user.HumanPasswordlessTokenSignCountChangedType, + user.HumanU2FTokenRemovedType, + user.HumanPasswordlessTokenRemovedType, + user.UserRemovedType) } type HumanU2FTokensReadModel struct { @@ -124,7 +133,7 @@ func (wm *HumanU2FTokensReadModel) Reduce() error { token := &HumanWebAuthNWriteModel{} token.appendAddedEvent(&e.HumanWebAuthNAddedEvent) token.WriteModel = eventstore.WriteModel{ - AggregateID: e.AggregateID(), + AggregateID: e.Aggregate().ID, } replaced := false for i, existingTokens := range wm.WebAuthNTokens { @@ -204,7 +213,7 @@ func (wm *HumanPasswordlessTokensReadModel) Reduce() error { token := &HumanWebAuthNWriteModel{} token.appendAddedEvent(&e.HumanWebAuthNAddedEvent) token.WriteModel = eventstore.WriteModel{ - AggregateID: e.AggregateID(), + AggregateID: e.Aggregate().ID, } replaced := false for i, existingTokens := range wm.WebAuthNTokens { diff --git a/internal/v2/command/user_machine.go b/internal/v2/command/user_machine.go index b7620481e6..70fb865b16 100644 --- a/internal/v2/command/user_machine.go +++ b/internal/v2/command/user_machine.go @@ -2,6 +2,7 @@ package command import ( "context" + caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" @@ -12,57 +13,69 @@ func (r *CommandSide) AddMachine(ctx context.Context, orgID string, machine *dom if !machine.IsValid() { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-bm9Ds", "Errors.User.Invalid") } + userID, err := r.idGenerator.Next() if err != nil { return nil, err } machine.AggregateID = userID + orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID) if err != nil { return nil, err } + //TODO: adlerhurst are no machines allowed in global org? or what if I create an org which allowes all suffixes? if !orgIAMPolicy.UserLoginMustBeDomain { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6M0ds", "Errors.User.Invalid") } addedMachine := NewMachineWriteModel(machine.AggregateID, orgID) userAgg := UserAggregateFromWriteModel(&addedMachine.WriteModel) - userAgg.PushEvents( - user.NewMachineAddedEvent( - ctx, - machine.Username, - machine.Name, - machine.Description, - orgIAMPolicy.UserLoginMustBeDomain, - ), - ) - err = r.eventstore.PushAggregate(ctx, addedMachine, userAgg) + events, err := r.eventstore.PushEvents(ctx, user.NewMachineAddedEvent( + ctx, + userAgg, + machine.Username, + machine.Name, + machine.Description, + orgIAMPolicy.UserLoginMustBeDomain, + )) + if err != nil { + return nil, err + } + err = AppendAndReduce(addedMachine, events...) + if err != nil { + return nil, err + } return writeModelToMachine(addedMachine), nil } func (r *CommandSide) ChangeMachine(ctx context.Context, machine *domain.Machine) (*domain.Machine, error) { - existingUser, err := r.machineWriteModelByID(ctx, machine.AggregateID, machine.ResourceOwner) + existingMachine, err := r.machineWriteModelByID(ctx, machine.AggregateID, machine.ResourceOwner) if err != nil { return nil, err } - if existingUser.UserState == domain.UserStateDeleted || existingUser.UserState == domain.UserStateUnspecified { + if !isUserStateExists(existingMachine.UserState) { return nil, caos_errs.ThrowNotFound(nil, "COMMAND-5M0od", "Errors.User.NotFound") } - changedEvent, hasChanged := existingUser.NewChangedEvent(ctx, machine.Name, machine.Description) + userAgg := UserAggregateFromWriteModel(&existingMachine.WriteModel) + changedEvent, hasChanged := existingMachine.NewChangedEvent(ctx, userAgg, machine.Name, machine.Description) if !hasChanged { - return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2n8vs", "Errors.User.Email.NotChanged") + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2n8vs", "Errors.User.NotChanged") } - userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) - userAgg.PushEvents(changedEvent) - err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + events, err := r.eventstore.PushEvents(ctx, changedEvent) if err != nil { return nil, err } - return writeModelToMachine(existingUser), nil + err = AppendAndReduce(existingMachine, events...) + if err != nil { + return nil, err + } + return writeModelToMachine(existingMachine), nil } +//TODO: adlerhurst we should check userID on the same level, in user.go userID is checked in public funcs func (r *CommandSide) machineWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *MachineWriteModel, err error) { if userID == "" { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-0Plof", "Errors.User.UserIDMissing") diff --git a/internal/v2/command/user_machine_key.go b/internal/v2/command/user_machine_key.go index 04d37dd192..71e62ba0c2 100644 --- a/internal/v2/command/user_machine_key.go +++ b/internal/v2/command/user_machine_key.go @@ -2,17 +2,17 @@ package command import ( "context" - "github.com/caos/logging" + "time" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) -const ( - yearLayout = "2006-01-02" - defaultExpirationDate = "9999-01-01" +var ( + //most of us won't survive until 12-31-9999 23:59:59, maybe ZITADEL does + defaultExpDate = time.Date(9999, time.December, 31, 23, 59, 59, 0, time.UTC) ) func (r *CommandSide) AddUserMachineKey(ctx context.Context, machineKey *domain.MachineKey, resourceOwner string) (*domain.MachineKey, error) { @@ -25,30 +25,39 @@ func (r *CommandSide) AddUserMachineKey(ctx context.Context, machineKey *domain. return nil, err } keyWriteModel := NewMachineKeyWriteModel(machineKey.AggregateID, keyID, resourceOwner) - userAgg := UserAggregateFromWriteModel(&keyWriteModel.WriteModel) err = r.eventstore.FilterToQueryReducer(ctx, keyWriteModel) if err != nil { return nil, err } if machineKey.ExpirationDate.IsZero() { - machineKey.ExpirationDate, err = time.Parse(yearLayout, defaultExpirationDate) - if err != nil { - logging.Log("COMMAND9-v8jMi").WithError(err).Warn("unable to set default date") - return nil, errors.ThrowInternal(err, "COMMAND-38jfus", "Errors.Internal") - } + machineKey.ExpirationDate = defaultExpDate } if machineKey.ExpirationDate.Before(time.Now()) { return nil, errors.ThrowInvalidArgument(nil, "COMMAND-38vns", "Errors.MachineKey.ExpireBeforeNow") } - machineKey.GenerateNewMachineKeyPair(r.machineKeySize) - - userAgg.PushEvents(user.NewMachineKeyAddedEvent(ctx, keyID, machineKey.Type, machineKey.ExpirationDate, machineKey.PublicKey)) - err = r.eventstore.PushAggregate(ctx, keyWriteModel, userAgg) + err = machineKey.GenerateNewMachineKeyPair(r.machineKeySize) if err != nil { return nil, err } + + events, err := r.eventstore.PushEvents(ctx, + user.NewMachineKeyAddedEvent( + ctx, + UserAggregateFromWriteModel(&keyWriteModel.WriteModel), + keyID, + machineKey.Type, + machineKey.ExpirationDate, + machineKey.PublicKey)) + if err != nil { + return nil, err + } + err = AppendAndReduce(keyWriteModel, events...) + if err != nil { + return nil, err + } + key := keyWriteModelToMachineKey(keyWriteModel) key.PrivateKey = machineKey.PrivateKey return key, nil @@ -59,12 +68,13 @@ func (r *CommandSide) RemoveUserMachineKey(ctx context.Context, userID, keyID, r if err != nil { return err } - if keyWriteModel.State == domain.MachineKeyStateUnspecified || keyWriteModel.State == domain.MachineKeyStateRemoved { + if !keyWriteModel.Exists() { return errors.ThrowNotFound(nil, "COMMAND-4m77G", "Errors.User.Machine.Key.NotFound") } - userAgg := UserAggregateFromWriteModel(&keyWriteModel.WriteModel) - userAgg.PushEvents(user.NewMachineKeyRemovedEvent(ctx, keyID)) - return r.eventstore.PushAggregate(ctx, keyWriteModel, userAgg) + + _, err = r.eventstore.PushEvents(ctx, + user.NewMachineKeyRemovedEvent(ctx, UserAggregateFromWriteModel(&keyWriteModel.WriteModel), keyID)) + return err } func (r *CommandSide) machineKeyWriteModelByID(ctx context.Context, userID, keyID, resourceOwner string) (writeModel *MachineKeyWriteModel, err error) { diff --git a/internal/v2/command/user_machine_key_model.go b/internal/v2/command/user_machine_key_model.go index 5fc20fbe65..475423b9e8 100644 --- a/internal/v2/command/user_machine_key_model.go +++ b/internal/v2/command/user_machine_key_model.go @@ -1,10 +1,11 @@ package command import ( + "time" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/user" - "time" ) type MachineKeyWriteModel struct { @@ -31,6 +32,8 @@ func (wm *MachineKeyWriteModel) AppendEvents(events ...eventstore.EventReader) { for _, event := range events { switch e := event.(type) { case *user.MachineKeyAddedEvent: + //TODO: adlerhurst we should decide who should handle the correct event appending + // IMO in this append events we should only get events with the correct keyID if wm.KeyID != e.KeyID { continue } @@ -72,3 +75,7 @@ func (wm *MachineKeyWriteModel) Query() *eventstore.SearchQueryBuilder { user.MachineKeyRemovedEventType, user.UserRemovedType) } + +func (wm *MachineKeyWriteModel) Exists() bool { + return wm.State != domain.MachineKeyStateUnspecified && wm.State != domain.MachineKeyStateRemoved +} diff --git a/internal/v2/command/user_machine_model.go b/internal/v2/command/user_machine_model.go index 31868aa816..3a64db0724 100644 --- a/internal/v2/command/user_machine_model.go +++ b/internal/v2/command/user_machine_model.go @@ -27,10 +27,6 @@ func NewMachineWriteModel(userID, resourceOwner string) *MachineWriteModel { } } -func (wm *MachineWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - //TODO: Compute OTPState? initial/active func (wm *MachineWriteModel) Reduce() error { for _, event := range wm.Events { @@ -75,16 +71,25 @@ func (wm *MachineWriteModel) Reduce() error { func (wm *MachineWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(wm.AggregateID). - ResourceOwner(wm.ResourceOwner) + ResourceOwner(wm.ResourceOwner). + EventTypes(user.MachineAddedEventType, + user.UserUserNameChangedType, + user.MachineChangedEventType, + user.UserLockedType, + user.UserUnlockedType, + user.UserDeactivatedType, + user.UserReactivatedType, + user.UserRemovedType) } func (wm *MachineWriteModel) NewChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, name, description string, ) (*user.MachineChangedEvent, bool) { hasChanged := false - changedEvent := user.NewMachineChangedEvent(ctx) + changedEvent := user.NewMachineChangedEvent(ctx, aggregate) if wm.Name != name { hasChanged = true changedEvent.Name = &name diff --git a/internal/v2/command/user_model.go b/internal/v2/command/user_model.go index b058396edc..1da601b5cd 100644 --- a/internal/v2/command/user_model.go +++ b/internal/v2/command/user_model.go @@ -25,10 +25,6 @@ func NewUserWriteModel(userID, resourceOwner string) *UserWriteModel { } } -func (wm *UserWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) -} - //TODO: Compute OTPState? initial/active func (wm *UserWriteModel) Reduce() error { for _, event := range wm.Events { @@ -71,17 +67,27 @@ func (wm *UserWriteModel) Reduce() error { func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). - AggregateIDs(wm.AggregateID) + AggregateIDs(wm.AggregateID). + EventTypes( + user.HumanAddedType, + user.HumanRegisteredType, + user.HumanInitializedCheckSucceededType, + user.MachineAddedEventType, + user.UserUserNameChangedType, + user.MachineChangedEventType, + user.UserLockedType, + user.UserUnlockedType, + user.UserDeactivatedType, + user.UserReactivatedType, + user.UserRemovedType) if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } return query } -func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *user.Aggregate { - return &user.Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, user.AggregateType, user.AggregateVersion), - } +func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { + return eventstore.AggregateFromWriteModel(wm, user.AggregateType, user.AggregateVersion) } func CheckOrgIAMPolicyForUserName(userName string, policy *domain.OrgIAMPolicy) error { @@ -93,3 +99,20 @@ func CheckOrgIAMPolicyForUserName(userName string, policy *domain.OrgIAMPolicy) } return nil } + +func isUserStateExists(state domain.UserState) bool { + return !hasUserState(state, domain.UserStateDeleted, domain.UserStateUnspecified) +} + +func isUserStateInactive(state domain.UserState) bool { + return hasUserState(state, domain.UserStateInactive) +} + +func hasUserState(check domain.UserState, states ...domain.UserState) bool { + for _, state := range states { + if check == state { + return true + } + } + return false +} diff --git a/internal/v2/domain/token.go b/internal/v2/domain/token.go index f5219d368e..b5d791089c 100644 --- a/internal/v2/domain/token.go +++ b/internal/v2/domain/token.go @@ -2,6 +2,7 @@ package domain import ( es_models "github.com/caos/zitadel/internal/eventstore/models" + "strings" "time" ) @@ -16,3 +17,12 @@ type Token struct { Scopes []string PreferredLanguage string } + +func AddAudScopeToAudience(audience, scopes []string) []string { + for _, scope := range scopes { + if strings.HasPrefix(scope, ProjectIDScope) && strings.HasSuffix(scope, AudSuffix) { + audience = append(audience, strings.TrimSuffix(strings.TrimPrefix(scope, ProjectIDScope), AudSuffix)) + } + } + return audience +} diff --git a/internal/v2/query/iam_model.go b/internal/v2/query/iam_model.go index 3b4ba50098..4548c6b0fe 100644 --- a/internal/v2/query/iam_model.go +++ b/internal/v2/query/iam_model.go @@ -130,14 +130,3 @@ func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error { func (rm *ReadModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).AggregateIDs(rm.AggregateID) } - -func IAMAggregateFromReadModel(rm *ReadModel) *iam.Aggregate { - return &iam.Aggregate{ - Aggregate: *eventstore.NewAggregate( - rm.AggregateID, - iam.AggregateType, - rm.ResourceOwner, - iam.AggregateVersion, - ), - } -} diff --git a/internal/v2/query/user_model.go b/internal/v2/query/user_model.go index 9115459bac..f7f4e9af31 100644 --- a/internal/v2/query/user_model.go +++ b/internal/v2/query/user_model.go @@ -52,17 +52,6 @@ func (rm *UserReadModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).AggregateIDs(rm.AggregateID) } -func UserAggregateFromReadModel(rm *UserReadModel) *user.Aggregate { - return &user.Aggregate{ - Aggregate: *eventstore.NewAggregate( - rm.AggregateID, - user.AggregateType, - rm.ResourceOwner, - user.AggregateVersion, - ), - } -} - func NewUserEventSearchQuery(userID, orgID string, sequence uint64) *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). AggregateIDs(userID).ResourceOwner(orgID).SequenceGreater(sequence) diff --git a/internal/v2/repository/iam/aggregate.go b/internal/v2/repository/iam/aggregate.go index a59e53ea9b..9ab7fdcb46 100644 --- a/internal/v2/repository/iam/aggregate.go +++ b/internal/v2/repository/iam/aggregate.go @@ -1,9 +1,7 @@ package iam import ( - "context" "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/domain" ) const ( @@ -18,13 +16,3 @@ const ( type Aggregate struct { eventstore.Aggregate } - -func (a *Aggregate) PushStepStarted(ctx context.Context, step domain.Step) *Aggregate { - a.Aggregate = *a.PushEvents(NewSetupStepStartedEvent(ctx, step)) - return a -} - -func (a *Aggregate) PushStepDone(ctx context.Context, step domain.Step) *Aggregate { - a.Aggregate = *a.PushEvents(NewSetupStepDoneEvent(ctx, step)) - return a -} diff --git a/internal/v2/repository/iam/event_iam_project_set.go b/internal/v2/repository/iam/event_iam_project_set.go index f3ba02bd12..b8ece01465 100644 --- a/internal/v2/repository/iam/event_iam_project_set.go +++ b/internal/v2/repository/iam/event_iam_project_set.go @@ -27,10 +27,15 @@ func (e *ProjectSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstrain return nil } -func NewIAMProjectSetEvent(ctx context.Context, projectID string) *ProjectSetEvent { +func NewIAMProjectSetEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + projectID string, +) *ProjectSetEvent { return &ProjectSetEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectSetEventType, ), ProjectID: projectID, diff --git a/internal/v2/repository/iam/event_org_set.go b/internal/v2/repository/iam/event_org_set.go index dc091885d5..356dd9fa97 100644 --- a/internal/v2/repository/iam/event_org_set.go +++ b/internal/v2/repository/iam/event_org_set.go @@ -27,10 +27,15 @@ func (e *GlobalOrgSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstra return nil } -func NewGlobalOrgSetEventEvent(ctx context.Context, orgID string) *GlobalOrgSetEvent { +func NewGlobalOrgSetEventEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + orgID string, +) *GlobalOrgSetEvent { return &GlobalOrgSetEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GlobalOrgSetEventType, ), OrgID: orgID, diff --git a/internal/v2/repository/iam/events_step.go b/internal/v2/repository/iam/events_step.go index a414220fb0..e6a1bfe812 100644 --- a/internal/v2/repository/iam/events_step.go +++ b/internal/v2/repository/iam/events_step.go @@ -45,12 +45,14 @@ func SetupStepMapper(event *repository.Event) (eventstore.EventReader, error) { func NewSetupStepDoneEvent( ctx context.Context, + aggregate *eventstore.Aggregate, step domain.Step, ) *SetupStepEvent { return &SetupStepEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, SetupDoneEventType, ), Step: step, @@ -59,12 +61,14 @@ func NewSetupStepDoneEvent( func NewSetupStepStartedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, step domain.Step, ) *SetupStepEvent { return &SetupStepEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, SetupStartedEventType, ), Step: step, diff --git a/internal/v2/repository/iam/idp_config.go b/internal/v2/repository/iam/idp_config.go index b01a6b8a3f..8a285baef0 100644 --- a/internal/v2/repository/iam/idp_config.go +++ b/internal/v2/repository/iam/idp_config.go @@ -23,6 +23,7 @@ type IDPConfigAddedEvent struct { func NewIDPConfigAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, configID, name string, configType domain.IDPConfigType, @@ -31,10 +32,10 @@ func NewIDPConfigAddedEvent( return &IDPConfigAddedEvent{ IDPConfigAddedEvent: *idpconfig.NewIDPConfigAddedEvent( - eventstore.NewBaseEventForPushWithResourceOwner( + eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigAddedEventType, - domain.IAMID, ), configID, name, @@ -59,13 +60,16 @@ type IDPConfigChangedEvent struct { func NewIDPConfigChangedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, oldName string, changes []idpconfig.IDPConfigChanges, ) (*IDPConfigChangedEvent, error) { changeEvent, err := idpconfig.NewIDPConfigChangedEvent( - eventstore.NewBaseEventForPushWithResourceOwner(ctx, IDPConfigChangedEventType, resourceOwner), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + IDPConfigChangedEventType), configID, oldName, changes, @@ -91,16 +95,16 @@ type IDPConfigRemovedEvent struct { func NewIDPConfigRemovedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, name string, ) *IDPConfigRemovedEvent { return &IDPConfigRemovedEvent{ IDPConfigRemovedEvent: *idpconfig.NewIDPConfigRemovedEvent( - eventstore.NewBaseEventForPushWithResourceOwner( + eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigRemovedEventType, - resourceOwner, ), configID, name, @@ -123,6 +127,7 @@ type IDPConfigDeactivatedEvent struct { func NewIDPConfigDeactivatedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, configID string, ) *IDPConfigDeactivatedEvent { @@ -130,6 +135,7 @@ func NewIDPConfigDeactivatedEvent( IDPConfigDeactivatedEvent: *idpconfig.NewIDPConfigDeactivatedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigDeactivatedEventType, ), configID, @@ -152,6 +158,7 @@ type IDPConfigReactivatedEvent struct { func NewIDPConfigReactivatedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, configID string, ) *IDPConfigReactivatedEvent { @@ -159,6 +166,7 @@ func NewIDPConfigReactivatedEvent( IDPConfigReactivatedEvent: *idpconfig.NewIDPConfigReactivatedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigReactivatedEventType, ), configID, diff --git a/internal/v2/repository/iam/idp_oidc_config.go b/internal/v2/repository/iam/idp_oidc_config.go index d1e9bbc89f..23506bc3c0 100644 --- a/internal/v2/repository/iam/idp_oidc_config.go +++ b/internal/v2/repository/iam/idp_oidc_config.go @@ -21,6 +21,7 @@ type IDPOIDCConfigAddedEvent struct { func NewIDPOIDCConfigAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, clientID, idpConfigID, issuer string, @@ -34,6 +35,7 @@ func NewIDPOIDCConfigAddedEvent( OIDCConfigAddedEvent: *idpconfig.NewOIDCConfigAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPOIDCConfigAddedEventType, ), clientID, @@ -62,11 +64,15 @@ type IDPOIDCConfigChangedEvent struct { func NewIDPOIDCConfigChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, changes []idpconfig.OIDCConfigChanges, ) (*IDPOIDCConfigChangedEvent, error) { changeEvent, err := idpconfig.NewOIDCConfigChangedEvent( - eventstore.NewBaseEventForPush(ctx, IDPOIDCConfigChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + IDPOIDCConfigChangedEventType), idpConfigID, changes, ) diff --git a/internal/v2/repository/iam/member.go b/internal/v2/repository/iam/member.go index 412a294ea3..e0ea6e1960 100644 --- a/internal/v2/repository/iam/member.go +++ b/internal/v2/repository/iam/member.go @@ -2,6 +2,7 @@ package iam import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/member" @@ -19,7 +20,7 @@ type MemberAddedEvent struct { func NewMemberAddedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberAddedEvent { @@ -28,9 +29,9 @@ func NewMemberAddedEvent( MemberAddedEvent: *member.NewMemberAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberAddedEventType, ), - aggregateID, userID, roles..., ), @@ -52,6 +53,7 @@ type MemberChangedEvent struct { func NewMemberChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberChangedEvent { @@ -59,6 +61,7 @@ func NewMemberChangedEvent( MemberChangedEvent: *member.NewMemberChangedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberChangedEventType, ), userID, @@ -82,7 +85,7 @@ type MemberRemovedEvent struct { func NewMemberRemovedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, ) *MemberRemovedEvent { @@ -90,9 +93,9 @@ func NewMemberRemovedEvent( MemberRemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberRemovedEventType, ), - aggregateID, userID, ), } diff --git a/internal/v2/repository/iam/migrate_unique_constraints.go b/internal/v2/repository/iam/migrate_unique_constraints.go index f7ee3cd51d..9728e9d88a 100644 --- a/internal/v2/repository/iam/migrate_unique_constraints.go +++ b/internal/v2/repository/iam/migrate_unique_constraints.go @@ -37,10 +37,14 @@ func (e *MigrateUniqueConstraintEvent) UniqueConstraints() []*eventstore.EventUn return constraints } -func NewMigrateUniqueConstraintEvent(ctx context.Context, uniqueConstraintMigrations []*domain.UniqueConstraintMigration) *MigrateUniqueConstraintEvent { +func NewMigrateUniqueConstraintEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + uniqueConstraintMigrations []*domain.UniqueConstraintMigration) *MigrateUniqueConstraintEvent { return &MigrateUniqueConstraintEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UniqueConstraintsMigratedEventType, ), uniqueConstraintMigrations: uniqueConstraintMigrations, diff --git a/internal/v2/repository/iam/policy_label.go b/internal/v2/repository/iam/policy_label.go index aa1ce125cb..be5ecf6511 100644 --- a/internal/v2/repository/iam/policy_label.go +++ b/internal/v2/repository/iam/policy_label.go @@ -2,6 +2,7 @@ package iam import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/policy" @@ -18,12 +19,16 @@ type LabelPolicyAddedEvent struct { func NewLabelPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, primaryColor, secondaryColor string, ) *LabelPolicyAddedEvent { return &LabelPolicyAddedEvent{ LabelPolicyAddedEvent: *policy.NewLabelPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LabelPolicyAddedEventType), primaryColor, secondaryColor), } @@ -44,10 +49,14 @@ type LabelPolicyChangedEvent struct { func NewLabelPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.LabelPolicyChanges, ) (*LabelPolicyChangedEvent, error) { changedEvent, err := policy.NewLabelPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LabelPolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_login.go b/internal/v2/repository/iam/policy_login.go index da1826bee3..5cf242b269 100644 --- a/internal/v2/repository/iam/policy_login.go +++ b/internal/v2/repository/iam/policy_login.go @@ -2,6 +2,7 @@ package iam import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -19,6 +20,7 @@ type LoginPolicyAddedEvent struct { func NewLoginPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, allowUsernamePassword, allowRegister, allowExternalIDP, @@ -27,7 +29,10 @@ func NewLoginPolicyAddedEvent( ) *LoginPolicyAddedEvent { return &LoginPolicyAddedEvent{ LoginPolicyAddedEvent: *policy.NewLoginPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyAddedEventType), allowUsernamePassword, allowRegister, allowExternalIDP, @@ -51,10 +56,14 @@ type LoginPolicyChangedEvent struct { func NewLoginPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.LoginPolicyChanges, ) (*LoginPolicyChangedEvent, error) { changedEvent, err := policy.NewLoginPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_login_factors.go b/internal/v2/repository/iam/policy_login_factors.go index ca7151d3d7..b584f0444d 100644 --- a/internal/v2/repository/iam/policy_login_factors.go +++ b/internal/v2/repository/iam/policy_login_factors.go @@ -2,6 +2,7 @@ package iam import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -22,11 +23,15 @@ type LoginPolicySecondFactorAddedEvent struct { func NewLoginPolicySecondFactorAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorAddedEvent { return &LoginPolicySecondFactorAddedEvent{ SecondFactorAddedEvent: *policy.NewSecondFactorAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicySecondFactorAddedEventType), mfaType), } } @@ -48,12 +53,16 @@ type LoginPolicySecondFactorRemovedEvent struct { func NewLoginPolicySecondFactorRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorRemovedEvent { return &LoginPolicySecondFactorRemovedEvent{ SecondFactorRemovedEvent: *policy.NewSecondFactorRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicySecondFactorRemovedEventType), mfaType), } } @@ -75,11 +84,15 @@ type LoginPolicyMultiFactorAddedEvent struct { func NewLoginPolicyMultiFactorAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorAddedEvent { return &LoginPolicyMultiFactorAddedEvent{ MultiFactorAddedEvent: *policy.NewMultiFactorAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyMultiFactorAddedEventType), mfaType), } } @@ -101,12 +114,16 @@ type LoginPolicyMultiFactorRemovedEvent struct { func NewLoginPolicyMultiFactorRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorRemovedEvent { return &LoginPolicyMultiFactorRemovedEvent{ MultiFactorRemovedEvent: *policy.NewMultiFactorRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyMultiFactorRemovedEventType), mfaType), } } diff --git a/internal/v2/repository/iam/policy_login_identity_provider.go b/internal/v2/repository/iam/policy_login_identity_provider.go index 44c115fd42..991a37f380 100644 --- a/internal/v2/repository/iam/policy_login_identity_provider.go +++ b/internal/v2/repository/iam/policy_login_identity_provider.go @@ -2,6 +2,7 @@ package iam import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -20,13 +21,17 @@ type IdentityProviderAddedEvent struct { func NewIdentityProviderAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, idpProviderType domain.IdentityProviderType, ) *IdentityProviderAddedEvent { return &IdentityProviderAddedEvent{ IdentityProviderAddedEvent: *policy.NewIdentityProviderAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyIDPProviderAddedEventType), idpConfigID, idpProviderType), } @@ -49,11 +54,15 @@ type IdentityProviderRemovedEvent struct { func NewIdentityProviderRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, ) *IdentityProviderRemovedEvent { return &IdentityProviderRemovedEvent{ IdentityProviderRemovedEvent: *policy.NewIdentityProviderRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyIDPProviderRemovedEventType), idpConfigID), } } @@ -75,11 +84,12 @@ type IdentityProviderCascadeRemovedEvent struct { func NewIdentityProviderCascadeRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, ) *IdentityProviderCascadeRemovedEvent { return &IdentityProviderCascadeRemovedEvent{ IdentityProviderCascadeRemovedEvent: *policy.NewIdentityProviderCascadeRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderCascadeRemovedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, LoginPolicyIDPProviderCascadeRemovedEventType), idpConfigID), } } diff --git a/internal/v2/repository/iam/policy_mail_template.go b/internal/v2/repository/iam/policy_mail_template.go index 65448b8795..22c3b8dfd4 100644 --- a/internal/v2/repository/iam/policy_mail_template.go +++ b/internal/v2/repository/iam/policy_mail_template.go @@ -18,11 +18,12 @@ type MailTemplateAddedEvent struct { func NewMailTemplateAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, template []byte, ) *MailTemplateAddedEvent { return &MailTemplateAddedEvent{ MailTemplateAddedEvent: *policy.NewMailTemplateAddedEvent( - eventstore.NewBaseEventForPush(ctx, MailTemplateAddedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTemplateAddedEventType), template), } } @@ -42,10 +43,11 @@ type MailTemplateChangedEvent struct { func NewMailTemplateChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.MailTemplateChanges, ) (*MailTemplateChangedEvent, error) { changedEvent, err := policy.NewMailTemplateChangedEvent( - eventstore.NewBaseEventForPush(ctx, MailTemplateChangedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTemplateChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_mail_text.go b/internal/v2/repository/iam/policy_mail_text.go index c0ec0f7f6e..5a8167c74f 100644 --- a/internal/v2/repository/iam/policy_mail_text.go +++ b/internal/v2/repository/iam/policy_mail_text.go @@ -4,7 +4,6 @@ import ( "context" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/repository/policy" ) @@ -19,6 +18,7 @@ type MailTextAddedEvent struct { func NewMailTextAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mailTextType, language, title, @@ -30,7 +30,7 @@ func NewMailTextAddedEvent( ) *MailTextAddedEvent { return &MailTextAddedEvent{ MailTextAddedEvent: *policy.NewMailTextAddedEvent( - eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextAddedEventType, domain.IAMID), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTextAddedEventType), mailTextType, language, title, @@ -57,12 +57,13 @@ type MailTextChangedEvent struct { func NewMailTextChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mailTextType, language string, changes []policy.MailTextChanges, ) (*MailTextChangedEvent, error) { changedEvent, err := policy.NewMailTextChangedEvent( - eventstore.NewBaseEventForPush(ctx, MailTextChangedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTextChangedEventType), mailTextType, language, changes, diff --git a/internal/v2/repository/iam/policy_org_iam.go b/internal/v2/repository/iam/policy_org_iam.go index 4b0dad186e..b7acf00cec 100644 --- a/internal/v2/repository/iam/policy_org_iam.go +++ b/internal/v2/repository/iam/policy_org_iam.go @@ -19,11 +19,15 @@ type OrgIAMPolicyAddedEvent struct { func NewOrgIAMPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userLoginMustBeDomain bool, ) *OrgIAMPolicyAddedEvent { return &OrgIAMPolicyAddedEvent{ OrgIAMPolicyAddedEvent: *policy.NewOrgIAMPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + OrgIAMPolicyAddedEventType), userLoginMustBeDomain, ), } @@ -44,10 +48,14 @@ type OrgIAMPolicyChangedEvent struct { func NewOrgIAMPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.OrgIAMPolicyChanges, ) (*OrgIAMPolicyChangedEvent, error) { changedEvent, err := policy.NewOrgIAMPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + OrgIAMPolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_password_age.go b/internal/v2/repository/iam/policy_password_age.go index 801c69abba..99a457b547 100644 --- a/internal/v2/repository/iam/policy_password_age.go +++ b/internal/v2/repository/iam/policy_password_age.go @@ -19,12 +19,16 @@ type PasswordAgePolicyAddedEvent struct { func NewPasswordAgePolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, expireWarnDays, maxAgeDays uint64, ) *PasswordAgePolicyAddedEvent { return &PasswordAgePolicyAddedEvent{ PasswordAgePolicyAddedEvent: *policy.NewPasswordAgePolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordAgePolicyAddedEventType), expireWarnDays, maxAgeDays), } @@ -45,10 +49,14 @@ type PasswordAgePolicyChangedEvent struct { func NewPasswordAgePolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordAgePolicyChanges, ) (*PasswordAgePolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordAgePolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordAgePolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_password_complexity.go b/internal/v2/repository/iam/policy_password_complexity.go index d90f28f2ca..e9ae4610a4 100644 --- a/internal/v2/repository/iam/policy_password_complexity.go +++ b/internal/v2/repository/iam/policy_password_complexity.go @@ -19,6 +19,7 @@ type PasswordComplexityPolicyAddedEvent struct { func NewPasswordComplexityPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, minLength uint64, hasLowercase, hasUppercase, @@ -27,7 +28,10 @@ func NewPasswordComplexityPolicyAddedEvent( ) *PasswordComplexityPolicyAddedEvent { return &PasswordComplexityPolicyAddedEvent{ PasswordComplexityPolicyAddedEvent: *policy.NewPasswordComplexityPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordComplexityPolicyAddedEventType), minLength, hasLowercase, hasUppercase, @@ -51,10 +55,14 @@ type PasswordComplexityPolicyChangedEvent struct { func NewPasswordComplexityPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordComplexityPolicyChanges, ) (*PasswordComplexityPolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordComplexityPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordComplexityPolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/iam/policy_password_lockout.go b/internal/v2/repository/iam/policy_password_lockout.go index 5dec4234d3..41ae417cc4 100644 --- a/internal/v2/repository/iam/policy_password_lockout.go +++ b/internal/v2/repository/iam/policy_password_lockout.go @@ -19,12 +19,16 @@ type PasswordLockoutPolicyAddedEvent struct { func NewPasswordLockoutPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, maxAttempts uint64, showLockoutFailure bool, ) *PasswordLockoutPolicyAddedEvent { return &PasswordLockoutPolicyAddedEvent{ PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordLockoutPolicyAddedEventType), maxAttempts, showLockoutFailure), } @@ -45,10 +49,14 @@ type PasswordLockoutPolicyChangedEvent struct { func NewPasswordLockoutPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordLockoutPolicyChanges, ) (*PasswordLockoutPolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordLockoutPolicyChangedEventType), changes, ) if err != nil { diff --git a/internal/v2/repository/idpconfig/idp_config.go b/internal/v2/repository/idpconfig/idp_config.go index 1a7d2acd3e..2efa981c0b 100644 --- a/internal/v2/repository/idpconfig/idp_config.go +++ b/internal/v2/repository/idpconfig/idp_config.go @@ -56,7 +56,7 @@ func (e *IDPConfigAddedEvent) Data() interface{} { } func (e *IDPConfigAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner())} + return []*eventstore.EventUniqueConstraint{NewAddIDPConfigNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)} } func IDPConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { @@ -90,8 +90,8 @@ func (e *IDPConfigChangedEvent) UniqueConstraints() []*eventstore.EventUniqueCon return nil } return []*eventstore.EventUniqueConstraint{ - NewRemoveIDPConfigNameUniqueConstraint(e.oldName, e.ResourceOwner()), - NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner()), + NewRemoveIDPConfigNameUniqueConstraint(e.oldName, e.Aggregate().ResourceOwner), + NewAddIDPConfigNameUniqueConstraint(*e.Name, e.Aggregate().ResourceOwner), } } @@ -243,7 +243,7 @@ func (e *IDPConfigRemovedEvent) Data() interface{} { } func (e *IDPConfigRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner())} + return []*eventstore.EventUniqueConstraint{NewRemoveIDPConfigNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)} } func IDPConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { diff --git a/internal/v2/repository/keypair/key_pair.go b/internal/v2/repository/keypair/key_pair.go index 5d81a7aaad..4b18fd39f3 100644 --- a/internal/v2/repository/keypair/key_pair.go +++ b/internal/v2/repository/keypair/key_pair.go @@ -40,6 +40,7 @@ func (e *AddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func NewAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, usage domain.KeyUsage, algorithm string, privateCrypto, @@ -49,6 +50,7 @@ func NewAddedEvent( return &AddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, AddedEventType, ), Usage: usage, diff --git a/internal/v2/repository/member/events.go b/internal/v2/repository/member/events.go index 177c021335..9a49c63e13 100644 --- a/internal/v2/repository/member/events.go +++ b/internal/v2/repository/member/events.go @@ -32,9 +32,8 @@ func NewRemoveMemberUniqueConstraint(aggregateID, userID string) *eventstore.Eve type MemberAddedEvent struct { eventstore.BaseEvent `json:"-"` - Roles []string `json:"roles"` - UserID string `json:"userId"` - aggregateID string + Roles []string `json:"roles"` + UserID string `json:"userId"` } func (e *MemberAddedEvent) Data() interface{} { @@ -42,21 +41,19 @@ func (e *MemberAddedEvent) Data() interface{} { } func (e *MemberAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddMemberUniqueConstraint(e.aggregateID, e.UserID)} + return []*eventstore.EventUniqueConstraint{NewAddMemberUniqueConstraint(e.Aggregate().ID, e.UserID)} } func NewMemberAddedEvent( base *eventstore.BaseEvent, - aggregateID, userID string, roles ...string, ) *MemberAddedEvent { return &MemberAddedEvent{ - BaseEvent: *base, - aggregateID: aggregateID, - Roles: roles, - UserID: userID, + BaseEvent: *base, + Roles: roles, + UserID: userID, } } @@ -116,8 +113,7 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) type MemberRemovedEvent struct { eventstore.BaseEvent `json:"-"` - UserID string `json:"userId"` - aggregateID string + UserID string `json:"userId"` } func (e *MemberRemovedEvent) Data() interface{} { @@ -125,19 +121,17 @@ func (e *MemberRemovedEvent) Data() interface{} { } func (e *MemberRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveMemberUniqueConstraint(e.aggregateID, e.UserID)} + return []*eventstore.EventUniqueConstraint{NewRemoveMemberUniqueConstraint(e.Aggregate().ID, e.UserID)} } func NewRemovedEvent( base *eventstore.BaseEvent, - aggregateID, userID string, ) *MemberRemovedEvent { return &MemberRemovedEvent{ - BaseEvent: *base, - aggregateID: aggregateID, - UserID: userID, + BaseEvent: *base, + UserID: userID, } } diff --git a/internal/v2/repository/org/domain.go b/internal/v2/repository/org/domain.go index 3640ddf485..237a968204 100644 --- a/internal/v2/repository/org/domain.go +++ b/internal/v2/repository/org/domain.go @@ -49,10 +49,11 @@ func (e *DomainAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrai return nil } -func NewDomainAddedEvent(ctx context.Context, domain string) *DomainAddedEvent { +func NewDomainAddedEvent(ctx context.Context, aggregate *eventstore.Aggregate, domain string) *DomainAddedEvent { return &DomainAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainAddedEventType, ), Domain: domain, @@ -89,12 +90,14 @@ func (e *DomainVerificationAddedEvent) UniqueConstraints() []*eventstore.EventUn func NewDomainVerificationAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, domain string, validationType domain.OrgDomainValidationType, validationCode *crypto.CryptoValue) *DomainVerificationAddedEvent { return &DomainVerificationAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainVerificationAddedEventType, ), Domain: domain, @@ -129,10 +132,11 @@ func (e *DomainVerificationFailedEvent) UniqueConstraints() []*eventstore.EventU return nil } -func NewDomainVerificationFailedEvent(ctx context.Context, domain string) *DomainVerificationFailedEvent { +func NewDomainVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate, domain string) *DomainVerificationFailedEvent { return &DomainVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainVerificationFailedEventType, ), Domain: domain, @@ -165,10 +169,11 @@ func (e *DomainVerifiedEvent) UniqueConstraints() []*eventstore.EventUniqueConst return []*eventstore.EventUniqueConstraint{NewAddOrgDomainUniqueConstraint(e.Domain)} } -func NewDomainVerifiedEvent(ctx context.Context, domain string) *DomainVerifiedEvent { +func NewDomainVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate, domain string) *DomainVerifiedEvent { return &DomainVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainVerifiedEventType, ), Domain: domain, @@ -201,10 +206,11 @@ func (e *DomainPrimarySetEvent) UniqueConstraints() []*eventstore.EventUniqueCon return nil } -func NewDomainPrimarySetEvent(ctx context.Context, domain string) *DomainPrimarySetEvent { +func NewDomainPrimarySetEvent(ctx context.Context, aggregate *eventstore.Aggregate, domain string) *DomainPrimarySetEvent { return &DomainPrimarySetEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainPrimarySetEventType, ), Domain: domain, @@ -241,10 +247,11 @@ func (e *DomainRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstr return []*eventstore.EventUniqueConstraint{NewRemoveOrgDomainUniqueConstraint(e.Domain)} } -func NewDomainRemovedEvent(ctx context.Context, domain string) *DomainRemovedEvent { +func NewDomainRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, domain string) *DomainRemovedEvent { return &DomainRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDomainRemovedEventType, ), Domain: domain, diff --git a/internal/v2/repository/org/idp_config.go b/internal/v2/repository/org/idp_config.go index efd137d0bb..a64e5b2ffe 100644 --- a/internal/v2/repository/org/idp_config.go +++ b/internal/v2/repository/org/idp_config.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -22,7 +23,7 @@ type IDPConfigAddedEvent struct { func NewIDPConfigAddedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, name string, configType domain.IDPConfigType, @@ -31,10 +32,10 @@ func NewIDPConfigAddedEvent( return &IDPConfigAddedEvent{ IDPConfigAddedEvent: *idpconfig.NewIDPConfigAddedEvent( - eventstore.NewBaseEventForPushWithResourceOwner( + eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigAddedEventType, - resourceOwner, ), configID, name, @@ -59,13 +60,15 @@ type IDPConfigChangedEvent struct { func NewIDPConfigChangedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, oldName string, changes []idpconfig.IDPConfigChanges, ) (*IDPConfigChangedEvent, error) { changeEvent, err := idpconfig.NewIDPConfigChangedEvent( - eventstore.NewBaseEventForPushWithResourceOwner(ctx, IDPConfigChangedEventType, resourceOwner), + eventstore.NewBaseEventForPush(ctx, + aggregate, + IDPConfigChangedEventType), configID, oldName, changes, @@ -91,17 +94,17 @@ type IDPConfigRemovedEvent struct { func NewIDPConfigRemovedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, configID, name string, ) *IDPConfigRemovedEvent { return &IDPConfigRemovedEvent{ IDPConfigRemovedEvent: *idpconfig.NewIDPConfigRemovedEvent( - eventstore.NewBaseEventForPushWithResourceOwner( + eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigRemovedEventType, - resourceOwner, ), configID, name, @@ -124,6 +127,7 @@ type IDPConfigDeactivatedEvent struct { func NewIDPConfigDeactivatedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, configID string, ) *IDPConfigDeactivatedEvent { @@ -131,6 +135,7 @@ func NewIDPConfigDeactivatedEvent( IDPConfigDeactivatedEvent: *idpconfig.NewIDPConfigDeactivatedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigDeactivatedEventType, ), configID, @@ -153,6 +158,7 @@ type IDPConfigReactivatedEvent struct { func NewIDPConfigReactivatedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, configID string, ) *IDPConfigReactivatedEvent { @@ -160,6 +166,7 @@ func NewIDPConfigReactivatedEvent( IDPConfigReactivatedEvent: *idpconfig.NewIDPConfigReactivatedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPConfigReactivatedEventType, ), configID, diff --git a/internal/v2/repository/org/idp_oidc_config.go b/internal/v2/repository/org/idp_oidc_config.go index 103eade446..518e901977 100644 --- a/internal/v2/repository/org/idp_oidc_config.go +++ b/internal/v2/repository/org/idp_oidc_config.go @@ -21,6 +21,7 @@ type IDPOIDCConfigAddedEvent struct { func NewIDPOIDCConfigAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, clientID, idpConfigID, issuer string, @@ -34,6 +35,7 @@ func NewIDPOIDCConfigAddedEvent( OIDCConfigAddedEvent: *idpconfig.NewOIDCConfigAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, IDPOIDCConfigAddedEventType, ), clientID, @@ -62,11 +64,15 @@ type IDPOIDCConfigChangedEvent struct { func NewIDPOIDCConfigChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, changes []idpconfig.OIDCConfigChanges, ) (*IDPOIDCConfigChangedEvent, error) { changeEvent, err := idpconfig.NewOIDCConfigChangedEvent( - eventstore.NewBaseEventForPush(ctx, IDPOIDCConfigChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + IDPOIDCConfigChangedEventType), idpConfigID, changes, ) diff --git a/internal/v2/repository/org/member.go b/internal/v2/repository/org/member.go index dccffa83df..c79a17990d 100644 --- a/internal/v2/repository/org/member.go +++ b/internal/v2/repository/org/member.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/member" @@ -19,7 +20,7 @@ type MemberAddedEvent struct { func NewMemberAddedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberAddedEvent { @@ -27,9 +28,9 @@ func NewMemberAddedEvent( MemberAddedEvent: *member.NewMemberAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberAddedEventType, ), - aggregateID, userID, roles..., ), @@ -51,6 +52,7 @@ type MemberChangedEvent struct { func NewMemberChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberChangedEvent { @@ -59,6 +61,7 @@ func NewMemberChangedEvent( MemberChangedEvent: *member.NewMemberChangedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberChangedEventType, ), userID, @@ -82,7 +85,7 @@ type MemberRemovedEvent struct { func NewMemberRemovedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, ) *MemberRemovedEvent { @@ -90,9 +93,9 @@ func NewMemberRemovedEvent( MemberRemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberRemovedEventType, ), - aggregateID, userID, ), } diff --git a/internal/v2/repository/org/org.go b/internal/v2/repository/org/org.go index 6b7b8597d5..b705678853 100644 --- a/internal/v2/repository/org/org.go +++ b/internal/v2/repository/org/org.go @@ -45,10 +45,11 @@ func (e *OrgAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint return []*eventstore.EventUniqueConstraint{NewAddOrgNameUniqueConstraint(e.Name)} } -func NewOrgAddedEvent(ctx context.Context, name string) *OrgAddedEvent { +func NewOrgAddedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string) *OrgAddedEvent { return &OrgAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgAddedEventType, ), Name: name, @@ -80,15 +81,16 @@ func (e *OrgChangedEvent) Data() interface{} { func (e *OrgChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { return []*eventstore.EventUniqueConstraint{ - NewRemoveOrgDomainUniqueConstraint(e.oldName), + NewRemoveOrgNameUniqueConstraint(e.oldName), NewAddOrgNameUniqueConstraint(e.Name), } } -func NewOrgChangedEvent(ctx context.Context, oldName, newName string) *OrgChangedEvent { +func NewOrgChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, oldName, newName string) *OrgChangedEvent { return &OrgChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgChangedEventType, ), Name: newName, @@ -120,10 +122,11 @@ func (e *OrgDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConst return nil } -func NewOrgDeactivatedEvent(ctx context.Context) *OrgDeactivatedEvent { +func NewOrgDeactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *OrgDeactivatedEvent { return &OrgDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgDeactivatedEventType, ), } @@ -153,10 +156,11 @@ func (e *OrgReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConst return nil } -func NewOrgReactivatedEvent(ctx context.Context) *OrgReactivatedEvent { +func NewOrgReactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *OrgReactivatedEvent { return &OrgReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgReactivatedEventType, ), } @@ -187,10 +191,11 @@ func (e *OrgRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrain return []*eventstore.EventUniqueConstraint{NewRemoveOrgNameUniqueConstraint(e.name)} } -func NewOrgRemovedEvent(ctx context.Context, name string) *OrgRemovedEvent { +func NewOrgRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string) *OrgRemovedEvent { return &OrgRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OrgRemovedEventType, ), name: name, diff --git a/internal/v2/repository/org/policy_label.go b/internal/v2/repository/org/policy_label.go index 5079638bd4..429f699a04 100644 --- a/internal/v2/repository/org/policy_label.go +++ b/internal/v2/repository/org/policy_label.go @@ -20,12 +20,16 @@ type LabelPolicyAddedEvent struct { func NewLabelPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, primaryColor, secondaryColor string, ) *LabelPolicyAddedEvent { return &LabelPolicyAddedEvent{ LabelPolicyAddedEvent: *policy.NewLabelPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LabelPolicyAddedEventType), primaryColor, secondaryColor), } @@ -46,10 +50,14 @@ type LabelPolicyChangedEvent struct { func NewLabelPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.LabelPolicyChanges, ) (*LabelPolicyChangedEvent, error) { changedEvent, err := policy.NewLabelPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LabelPolicyChangedEventType), changes, ) if err != nil { @@ -73,10 +81,14 @@ type LabelPolicyRemovedEvent struct { func NewLabelPolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *LabelPolicyRemovedEvent { return &LabelPolicyRemovedEvent{ LabelPolicyRemovedEvent: *policy.NewLabelPolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LabelPolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_login.go b/internal/v2/repository/org/policy_login.go index a5f39e0f5d..a4ed58f36e 100644 --- a/internal/v2/repository/org/policy_login.go +++ b/internal/v2/repository/org/policy_login.go @@ -21,6 +21,7 @@ type LoginPolicyAddedEvent struct { func NewLoginPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, allowUsernamePassword, allowRegister, allowExternalIDP, @@ -29,7 +30,10 @@ func NewLoginPolicyAddedEvent( ) *LoginPolicyAddedEvent { return &LoginPolicyAddedEvent{ LoginPolicyAddedEvent: *policy.NewLoginPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyAddedEventType), allowUsernamePassword, allowRegister, allowExternalIDP, @@ -53,10 +57,14 @@ type LoginPolicyChangedEvent struct { func NewLoginPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.LoginPolicyChanges, ) (*LoginPolicyChangedEvent, error) { changedEvent, err := policy.NewLoginPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyChangedEventType), changes, ) if err != nil { @@ -80,10 +88,14 @@ type LoginPolicyRemovedEvent struct { func NewLoginPolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *LoginPolicyRemovedEvent { return &LoginPolicyRemovedEvent{ LoginPolicyRemovedEvent: *policy.NewLoginPolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_login_factors.go b/internal/v2/repository/org/policy_login_factors.go index 7bcf3297ee..1ff97613c8 100644 --- a/internal/v2/repository/org/policy_login_factors.go +++ b/internal/v2/repository/org/policy_login_factors.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -22,11 +23,15 @@ type LoginPolicySecondFactorAddedEvent struct { func NewLoginPolicySecondFactorAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorAddedEvent { return &LoginPolicySecondFactorAddedEvent{ SecondFactorAddedEvent: *policy.NewSecondFactorAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicySecondFactorAddedEventType), mfaType), } } @@ -48,12 +53,16 @@ type LoginPolicySecondFactorRemovedEvent struct { func NewLoginPolicySecondFactorRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorRemovedEvent { return &LoginPolicySecondFactorRemovedEvent{ SecondFactorRemovedEvent: *policy.NewSecondFactorRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicySecondFactorRemovedEventType), mfaType), } } @@ -75,11 +84,15 @@ type LoginPolicyMultiFactorAddedEvent struct { func NewLoginPolicyMultiFactorAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorAddedEvent { return &LoginPolicyMultiFactorAddedEvent{ MultiFactorAddedEvent: *policy.NewMultiFactorAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyMultiFactorAddedEventType), mfaType), } } @@ -101,12 +114,16 @@ type LoginPolicyMultiFactorRemovedEvent struct { func NewLoginPolicyMultiFactorRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorRemovedEvent { return &LoginPolicyMultiFactorRemovedEvent{ MultiFactorRemovedEvent: *policy.NewMultiFactorRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyMultiFactorRemovedEventType), mfaType), } } diff --git a/internal/v2/repository/org/policy_login_identity_provider.go b/internal/v2/repository/org/policy_login_identity_provider.go index 7112566693..624680ed5f 100644 --- a/internal/v2/repository/org/policy_login_identity_provider.go +++ b/internal/v2/repository/org/policy_login_identity_provider.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" @@ -20,13 +21,17 @@ type IdentityProviderAddedEvent struct { func NewIdentityProviderAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, idpProviderType domain.IdentityProviderType, ) *IdentityProviderAddedEvent { return &IdentityProviderAddedEvent{ IdentityProviderAddedEvent: *policy.NewIdentityProviderAddedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyIDPProviderAddedEventType), idpConfigID, idpProviderType), } @@ -49,11 +54,15 @@ type IdentityProviderRemovedEvent struct { func NewIdentityProviderRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, ) *IdentityProviderRemovedEvent { return &IdentityProviderRemovedEvent{ IdentityProviderRemovedEvent: *policy.NewIdentityProviderRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + LoginPolicyIDPProviderRemovedEventType), idpConfigID), } } @@ -75,11 +84,12 @@ type IdentityProviderCascadeRemovedEvent struct { func NewIdentityProviderCascadeRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, idpConfigID string, ) *IdentityProviderCascadeRemovedEvent { return &IdentityProviderCascadeRemovedEvent{ IdentityProviderCascadeRemovedEvent: *policy.NewIdentityProviderCascadeRemovedEvent( - eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderRemovedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, LoginPolicyIDPProviderRemovedEventType), idpConfigID), } } diff --git a/internal/v2/repository/org/policy_mail_template.go b/internal/v2/repository/org/policy_mail_template.go index 06cb5f8d41..bfcb3d3e69 100644 --- a/internal/v2/repository/org/policy_mail_template.go +++ b/internal/v2/repository/org/policy_mail_template.go @@ -20,11 +20,12 @@ type MailTemplateAddedEvent struct { func NewMailTemplateAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, template []byte, ) *MailTemplateAddedEvent { return &MailTemplateAddedEvent{ MailTemplateAddedEvent: *policy.NewMailTemplateAddedEvent( - eventstore.NewBaseEventForPush(ctx, MailTemplateAddedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTemplateAddedEventType), template), } } @@ -44,10 +45,11 @@ type MailTemplateChangedEvent struct { func NewMailTemplateChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.MailTemplateChanges, ) (*MailTemplateChangedEvent, error) { changedEvent, err := policy.NewMailTemplateChangedEvent( - eventstore.NewBaseEventForPush(ctx, MailTemplateChangedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTemplateChangedEventType), changes, ) if err != nil { @@ -71,10 +73,11 @@ type MailTemplateRemovedEvent struct { func NewMailTemplateRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *MailTemplateRemovedEvent { return &MailTemplateRemovedEvent{ MailTemplateRemovedEvent: *policy.NewMailTemplateRemovedEvent( - eventstore.NewBaseEventForPush(ctx, MailTemplateRemovedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTemplateRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_mail_text.go b/internal/v2/repository/org/policy_mail_text.go index f917ef9cbb..b6d11ca199 100644 --- a/internal/v2/repository/org/policy_mail_text.go +++ b/internal/v2/repository/org/policy_mail_text.go @@ -20,7 +20,7 @@ type MailTextAddedEvent struct { func NewMailTextAddedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, mailTextType, language, title, @@ -32,7 +32,7 @@ func NewMailTextAddedEvent( ) *MailTextAddedEvent { return &MailTextAddedEvent{ MailTextAddedEvent: *policy.NewMailTextAddedEvent( - eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextAddedEventType, resourceOwner), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTextAddedEventType), mailTextType, language, title, @@ -59,12 +59,13 @@ type MailTextChangedEvent struct { func NewMailTextChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, mailTextType, language string, changes []policy.MailTextChanges, ) (*MailTextChangedEvent, error) { changedEvent, err := policy.NewMailTextChangedEvent( - eventstore.NewBaseEventForPush(ctx, MailTextChangedEventType), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTextChangedEventType), mailTextType, language, changes, @@ -90,13 +91,13 @@ type MailTextRemovedEvent struct { func NewMailTextRemovedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, mailTextType, language string, ) *MailTextRemovedEvent { return &MailTextRemovedEvent{ MailTextRemovedEvent: *policy.NewMailTextRemovedEvent( - eventstore.NewBaseEventForPushWithResourceOwner(ctx, MailTextRemovedEventType, resourceOwner), + eventstore.NewBaseEventForPush(ctx, aggregate, MailTextRemovedEventType), mailTextType, language, ), diff --git a/internal/v2/repository/org/policy_org_iam.go b/internal/v2/repository/org/policy_org_iam.go index 3cd870121e..2c3b043af9 100644 --- a/internal/v2/repository/org/policy_org_iam.go +++ b/internal/v2/repository/org/policy_org_iam.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/policy" @@ -22,11 +23,15 @@ type OrgIAMPolicyAddedEvent struct { func NewOrgIAMPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userLoginMustBeDomain bool, ) *OrgIAMPolicyAddedEvent { return &OrgIAMPolicyAddedEvent{ OrgIAMPolicyAddedEvent: *policy.NewOrgIAMPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + OrgIAMPolicyAddedEventType), userLoginMustBeDomain, ), } @@ -47,10 +52,14 @@ type OrgIAMPolicyChangedEvent struct { func NewOrgIAMPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.OrgIAMPolicyChanges, ) (*OrgIAMPolicyChangedEvent, error) { changedEvent, err := policy.NewOrgIAMPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + OrgIAMPolicyChangedEventType), changes, ) if err != nil { @@ -74,10 +83,14 @@ type OrgIAMPolicyRemovedEvent struct { func NewOrgIAMPolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *OrgIAMPolicyRemovedEvent { return &OrgIAMPolicyRemovedEvent{ OrgIAMPolicyRemovedEvent: *policy.NewOrgIAMPolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + OrgIAMPolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_password_age.go b/internal/v2/repository/org/policy_password_age.go index 4cffb4a19d..549d414d1d 100644 --- a/internal/v2/repository/org/policy_password_age.go +++ b/internal/v2/repository/org/policy_password_age.go @@ -20,12 +20,16 @@ type PasswordAgePolicyAddedEvent struct { func NewPasswordAgePolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, expireWarnDays, maxAgeDays uint64, ) *PasswordAgePolicyAddedEvent { return &PasswordAgePolicyAddedEvent{ PasswordAgePolicyAddedEvent: *policy.NewPasswordAgePolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordAgePolicyAddedEventType), expireWarnDays, maxAgeDays), } @@ -46,10 +50,14 @@ type PasswordAgePolicyChangedEvent struct { func NewPasswordAgePolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordAgePolicyChanges, ) (*PasswordAgePolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordAgePolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordAgePolicyChangedEventType), changes, ) if err != nil { @@ -73,10 +81,14 @@ type PasswordAgePolicyRemovedEvent struct { func NewPasswordAgePolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *PasswordAgePolicyRemovedEvent { return &PasswordAgePolicyRemovedEvent{ PasswordAgePolicyRemovedEvent: *policy.NewPasswordAgePolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordAgePolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_password_complexity.go b/internal/v2/repository/org/policy_password_complexity.go index ad5f18e9d7..38e984cb31 100644 --- a/internal/v2/repository/org/policy_password_complexity.go +++ b/internal/v2/repository/org/policy_password_complexity.go @@ -2,6 +2,7 @@ package org import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/policy" @@ -19,6 +20,7 @@ type PasswordComplexityPolicyAddedEvent struct { func NewPasswordComplexityPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, minLength uint64, hasLowercase, hasUppercase, @@ -27,7 +29,10 @@ func NewPasswordComplexityPolicyAddedEvent( ) *PasswordComplexityPolicyAddedEvent { return &PasswordComplexityPolicyAddedEvent{ PasswordComplexityPolicyAddedEvent: *policy.NewPasswordComplexityPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordComplexityPolicyAddedEventType), minLength, hasLowercase, hasUppercase, @@ -51,10 +56,14 @@ type PasswordComplexityPolicyChangedEvent struct { func NewPasswordComplexityPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordComplexityPolicyChanges, ) (*PasswordComplexityPolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordComplexityPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordComplexityPolicyChangedEventType), changes, ) if err != nil { @@ -78,10 +87,14 @@ type PasswordComplexityPolicyRemovedEvent struct { func NewPasswordComplexityPolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *PasswordComplexityPolicyRemovedEvent { return &PasswordComplexityPolicyRemovedEvent{ PasswordComplexityPolicyRemovedEvent: *policy.NewPasswordComplexityPolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordComplexityPolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/org/policy_password_lockout.go b/internal/v2/repository/org/policy_password_lockout.go index b0b94dec87..5a6fc2d0f6 100644 --- a/internal/v2/repository/org/policy_password_lockout.go +++ b/internal/v2/repository/org/policy_password_lockout.go @@ -20,12 +20,16 @@ type PasswordLockoutPolicyAddedEvent struct { func NewPasswordLockoutPolicyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, maxAttempts uint64, showLockoutFailure bool, ) *PasswordLockoutPolicyAddedEvent { return &PasswordLockoutPolicyAddedEvent{ PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyAddedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordLockoutPolicyAddedEventType), maxAttempts, showLockoutFailure), } @@ -46,10 +50,14 @@ type PasswordLockoutPolicyChangedEvent struct { func NewPasswordLockoutPolicyChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, changes []policy.PasswordLockoutPolicyChanges, ) (*PasswordLockoutPolicyChangedEvent, error) { changedEvent, err := policy.NewPasswordLockoutPolicyChangedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyChangedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordLockoutPolicyChangedEventType), changes, ) if err != nil { @@ -73,10 +81,14 @@ type PasswordLockoutPolicyRemovedEvent struct { func NewPasswordLockoutPolicyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *PasswordLockoutPolicyRemovedEvent { return &PasswordLockoutPolicyRemovedEvent{ PasswordLockoutPolicyRemovedEvent: *policy.NewPasswordLockoutPolicyRemovedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyRemovedEventType), + eventstore.NewBaseEventForPush( + ctx, + aggregate, + PasswordLockoutPolicyRemovedEventType), ), } } diff --git a/internal/v2/repository/policy/mail_text.go b/internal/v2/repository/policy/mail_text.go index 564921c634..bb42deae68 100644 --- a/internal/v2/repository/policy/mail_text.go +++ b/internal/v2/repository/policy/mail_text.go @@ -47,7 +47,7 @@ func (e *MailTextAddedEvent) Data() interface{} { } func (e *MailTextAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddMailTextUniqueConstraint(e.ResourceOwner(), e.MailTextType, e.Language)} + return []*eventstore.EventUniqueConstraint{NewAddMailTextUniqueConstraint(e.Aggregate().ResourceOwner, e.MailTextType, e.Language)} } func NewMailTextAddedEvent( @@ -191,7 +191,7 @@ func (e *MailTextRemovedEvent) Data() interface{} { } func (e *MailTextRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveMailTextUniqueConstraint(e.ResourceOwner(), e.MailTextType, e.Language)} + return []*eventstore.EventUniqueConstraint{NewRemoveMailTextUniqueConstraint(e.Aggregate().ResourceOwner, e.MailTextType, e.Language)} } func NewMailTextRemovedEvent(base *eventstore.BaseEvent, mailTextType, language string) *MailTextRemovedEvent { diff --git a/internal/v2/repository/project/application.go b/internal/v2/repository/project/application.go index 35ddb7662b..22fe049cc4 100644 --- a/internal/v2/repository/project/application.go +++ b/internal/v2/repository/project/application.go @@ -49,10 +49,17 @@ func (e *ApplicationAddedEvent) UniqueConstraints() []*eventstore.EventUniqueCon return []*eventstore.EventUniqueConstraint{NewAddApplicationUniqueConstraint(e.Name, e.projectID)} } -func NewApplicationAddedEvent(ctx context.Context, appID, name, projectID string) *ApplicationAddedEvent { +func NewApplicationAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + appID, + name, + projectID string, +) *ApplicationAddedEvent { return &ApplicationAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ApplicationAddedType, ), AppID: appID, @@ -94,10 +101,18 @@ func (e *ApplicationChangedEvent) UniqueConstraints() []*eventstore.EventUniqueC } } -func NewApplicationChangedEvent(ctx context.Context, appID, oldName, newName, projectID string) *ApplicationChangedEvent { +func NewApplicationChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + appID, + oldName, + newName, + projectID string, +) *ApplicationChangedEvent { return &ApplicationChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ApplicationChangedType, ), AppID: appID, @@ -134,10 +149,15 @@ func (e *ApplicationDeactivatedEvent) UniqueConstraints() []*eventstore.EventUni return nil } -func NewApplicationDeactivatedEvent(ctx context.Context, appID string) *ApplicationDeactivatedEvent { +func NewApplicationDeactivatedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + appID string, +) *ApplicationDeactivatedEvent { return &ApplicationDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ApplicationDeactivatedType, ), AppID: appID, @@ -171,10 +191,15 @@ func (e *ApplicationReactivatedEvent) UniqueConstraints() []*eventstore.EventUni return nil } -func NewApplicationReactivatedEvent(ctx context.Context, appID string) *ApplicationReactivatedEvent { +func NewApplicationReactivatedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + appID string, +) *ApplicationReactivatedEvent { return &ApplicationReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ApplicationReactivatedType, ), AppID: appID, @@ -210,10 +235,17 @@ func (e *ApplicationRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueC return []*eventstore.EventUniqueConstraint{NewRemoveApplicationUniqueConstraint(e.name, e.projectID)} } -func NewApplicationRemovedEvent(ctx context.Context, appID, name, projectID string) *ApplicationRemovedEvent { +func NewApplicationRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + appID, + name, + projectID string, +) *ApplicationRemovedEvent { return &ApplicationRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ApplicationRemovedType, ), AppID: appID, diff --git a/internal/v2/repository/project/grant.go b/internal/v2/repository/project/grant.go index 4611bb9b8c..95b32266dc 100644 --- a/internal/v2/repository/project/grant.go +++ b/internal/v2/repository/project/grant.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -50,10 +51,18 @@ func (e *GrantAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrain return []*eventstore.EventUniqueConstraint{NewAddProjectGrantUniqueConstraint(e.GrantedOrgID, e.projectID)} } -func NewGrantAddedEvent(ctx context.Context, grantID, grantedOrgID, projectID string, roleKeys []string) *GrantAddedEvent { +func NewGrantAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID, + grantedOrgID, + projectID string, + roleKeys []string, +) *GrantAddedEvent { return &GrantAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantAddedType, ), GrantID: grantID, @@ -91,10 +100,16 @@ func (e *GrantChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstra return nil } -func NewGrantChangedEvent(ctx context.Context, grantID string, roleKeys []string) *GrantChangedEvent { +func NewGrantChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID string, + roleKeys []string, +) *GrantChangedEvent { return &GrantChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantChangedType, ), GrantID: grantID, @@ -130,10 +145,16 @@ func (e *GrantCascadeChangedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } -func NewGrantCascadeChangedEvent(ctx context.Context, grantID string, roleKeys []string) *GrantCascadeChangedEvent { +func NewGrantCascadeChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID string, + roleKeys []string, +) *GrantCascadeChangedEvent { return &GrantCascadeChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantCascadeChangedType, ), GrantID: grantID, @@ -168,10 +189,15 @@ func (e *GrantDeactivateEvent) UniqueConstraints() []*eventstore.EventUniqueCons return nil } -func NewGrantDeactivateEvent(ctx context.Context, grantID string) *GrantDeactivateEvent { +func NewGrantDeactivateEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID string, +) *GrantDeactivateEvent { return &GrantDeactivateEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantDeactivatedType, ), GrantID: grantID, @@ -205,10 +231,15 @@ func (e *GrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueCon return nil } -func NewGrantReactivatedEvent(ctx context.Context, grantID string) *GrantReactivatedEvent { +func NewGrantReactivatedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID string, +) *GrantReactivatedEvent { return &GrantReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantReactivatedType, ), GrantID: grantID, @@ -244,10 +275,17 @@ func (e *GrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstra return []*eventstore.EventUniqueConstraint{NewRemoveProjectGrantUniqueConstraint(e.grantedOrgID, e.projectID)} } -func NewGrantRemovedEvent(ctx context.Context, grantID, grantedOrgID, projectID string) *GrantRemovedEvent { +func NewGrantRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + grantID, + grantedOrgID, + projectID string, +) *GrantRemovedEvent { return &GrantRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantRemovedType, ), GrantID: grantID, diff --git a/internal/v2/repository/project/grant_member.go b/internal/v2/repository/project/grant_member.go index a9e56304e4..6584858500 100644 --- a/internal/v2/repository/project/grant_member.go +++ b/internal/v2/repository/project/grant_member.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -50,6 +51,7 @@ func (e *GrantMemberAddedEvent) UniqueConstraints() []*eventstore.EventUniqueCon func NewProjectGrantMemberAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, projectID, userID, grantID string, @@ -58,6 +60,7 @@ func NewProjectGrantMemberAddedEvent( return &GrantMemberAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantMemberAddedType, ), projectID: projectID, @@ -98,6 +101,7 @@ func (e *GrantMemberChangedEvent) UniqueConstraints() []*eventstore.EventUniqueC func NewProjectGrantMemberChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userID, grantID string, roles ...string, @@ -105,6 +109,7 @@ func NewProjectGrantMemberChangedEvent( return &GrantMemberChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantMemberAddedType, ), UserID: userID, @@ -144,6 +149,7 @@ func (e *GrantMemberRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueC func NewProjectGrantMemberRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, projectID, userID, grantID string, @@ -151,6 +157,7 @@ func NewProjectGrantMemberRemovedEvent( return &GrantMemberRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, GrantMemberRemovedType, ), UserID: userID, diff --git a/internal/v2/repository/project/member.go b/internal/v2/repository/project/member.go index c1b4411d49..98a3875d1f 100644 --- a/internal/v2/repository/project/member.go +++ b/internal/v2/repository/project/member.go @@ -2,6 +2,7 @@ package project import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/member" @@ -19,7 +20,7 @@ type MemberAddedEvent struct { func NewProjectMemberAddedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberAddedEvent { @@ -27,9 +28,9 @@ func NewProjectMemberAddedEvent( MemberAddedEvent: *member.NewMemberAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberAddedType, ), - aggregateID, userID, roles..., ), @@ -51,6 +52,7 @@ type MemberChangedEvent struct { func NewProjectMemberChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userID string, roles ...string, ) *MemberChangedEvent { @@ -59,6 +61,7 @@ func NewProjectMemberChangedEvent( MemberChangedEvent: *member.NewMemberChangedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberChangedType, ), userID, @@ -82,7 +85,7 @@ type MemberRemovedEvent struct { func NewProjectMemberRemovedEvent( ctx context.Context, - aggregateID, + aggregate *eventstore.Aggregate, userID string, ) *MemberRemovedEvent { @@ -90,9 +93,9 @@ func NewProjectMemberRemovedEvent( MemberRemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, MemberRemovedType, ), - aggregateID, userID, ), } diff --git a/internal/v2/repository/project/oidc_config.go b/internal/v2/repository/project/oidc_config.go index 8591b00249..7bfdb77eef 100644 --- a/internal/v2/repository/project/oidc_config.go +++ b/internal/v2/repository/project/oidc_config.go @@ -51,6 +51,7 @@ func (e *OIDCConfigAddedEvent) UniqueConstraints() []*eventstore.EventUniqueCons func NewOIDCConfigAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, version domain.OIDCVersion, appID string, clientID string, @@ -71,6 +72,7 @@ func NewOIDCConfigAddedEvent( return &OIDCConfigAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OIDCConfigAddedType, ), Version: version, @@ -136,6 +138,7 @@ func (e *OIDCConfigChangedEvent) UniqueConstraints() []*eventstore.EventUniqueCo func NewOIDCConfigChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, appID string, changes []OIDCConfigChanges, ) (*OIDCConfigChangedEvent, error) { @@ -146,6 +149,7 @@ func NewOIDCConfigChangedEvent( changeEvent := &OIDCConfigChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OIDCConfigChangedType, ), AppID: appID, @@ -272,12 +276,14 @@ func (e *OIDCConfigSecretChangedEvent) UniqueConstraints() []*eventstore.EventUn func NewOIDCConfigSecretChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, appID string, clientSecret *crypto.CryptoValue, ) *OIDCConfigSecretChangedEvent { return &OIDCConfigSecretChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OIDCConfigSecretChangedType, ), AppID: appID, @@ -314,11 +320,13 @@ func (e *OIDCConfigSecretCheckSucceededEvent) UniqueConstraints() []*eventstore. func NewOIDCConfigSecretCheckSucceededEvent( ctx context.Context, + aggregate *eventstore.Aggregate, appID string, ) *OIDCConfigSecretCheckSucceededEvent { return &OIDCConfigSecretCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OIDCClientSecretCheckSucceededType, ), AppID: appID, @@ -354,11 +362,13 @@ func (e *OIDCConfigSecretCheckFailedEvent) UniqueConstraints() []*eventstore.Eve func NewOIDCConfigSecretCheckFailedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, appID string, ) *OIDCConfigSecretCheckFailedEvent { return &OIDCConfigSecretCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, OIDCClientSecretCheckFailedType, ), AppID: appID, diff --git a/internal/v2/repository/project/project.go b/internal/v2/repository/project/project.go index 838e4b0723..8c211e46fe 100644 --- a/internal/v2/repository/project/project.go +++ b/internal/v2/repository/project/project.go @@ -45,15 +45,19 @@ func (e *ProjectAddedEvent) Data() interface{} { } func (e *ProjectAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddProjectNameUniqueConstraint(e.Name, e.ResourceOwner())} + return []*eventstore.EventUniqueConstraint{NewAddProjectNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)} } -func NewProjectAddedEvent(ctx context.Context, name, resourceOwner string) *ProjectAddedEvent { +func NewProjectAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + name string, +) *ProjectAddedEvent { return &ProjectAddedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectAddedType, - resourceOwner, ), Name: name, } @@ -88,8 +92,8 @@ func (e *ProjectChangeEvent) Data() interface{} { func (e *ProjectChangeEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { if e.oldName != "" { return []*eventstore.EventUniqueConstraint{ - NewRemoveProjectNameUniqueConstraint(e.oldName, e.ResourceOwner()), - NewAddProjectNameUniqueConstraint(*e.Name, e.ResourceOwner()), + NewRemoveProjectNameUniqueConstraint(e.oldName, e.Aggregate().ResourceOwner), + NewAddProjectNameUniqueConstraint(*e.Name, e.Aggregate().ResourceOwner), } } return nil @@ -97,17 +101,20 @@ func (e *ProjectChangeEvent) UniqueConstraints() []*eventstore.EventUniqueConstr func NewProjectChangeEvent( ctx context.Context, - resourceOwner, oldName string, - changes []ProjectChanges) (*ProjectChangeEvent, error) { + aggregate *eventstore.Aggregate, + oldName string, + changes []ProjectChanges, +) (*ProjectChangeEvent, error) { if len(changes) == 0 { return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-mV9xc", "Errors.NoChangesFound") } changeEvent := &ProjectChangeEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectChangedType, - resourceOwner, ), + oldName: oldName, } for _, change := range changes { change(changeEvent) @@ -160,10 +167,11 @@ func (e *ProjectDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewProjectDeactivatedEvent(ctx context.Context) *ProjectDeactivatedEvent { +func NewProjectDeactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *ProjectDeactivatedEvent { return &ProjectDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectDeactivatedType, ), } @@ -187,10 +195,11 @@ func (e *ProjectReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewProjectReactivatedEvent(ctx context.Context) *ProjectReactivatedEvent { +func NewProjectReactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *ProjectReactivatedEvent { return &ProjectReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectReactivatedType, ), } @@ -213,15 +222,19 @@ func (e *ProjectRemovedEvent) Data() interface{} { } func (e *ProjectRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveProjectNameUniqueConstraint(e.Name, e.ResourceOwner())} + return []*eventstore.EventUniqueConstraint{NewRemoveProjectNameUniqueConstraint(e.Name, e.Aggregate().ResourceOwner)} } -func NewProjectRemovedEvent(ctx context.Context, name, resourceOwner string) *ProjectRemovedEvent { +func NewProjectRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + name string, +) *ProjectRemovedEvent { return &ProjectRemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, ProjectRemovedType, - resourceOwner, ), Name: name, } diff --git a/internal/v2/repository/project/role.go b/internal/v2/repository/project/role.go index e68e86b8bd..4018828a69 100644 --- a/internal/v2/repository/project/role.go +++ b/internal/v2/repository/project/role.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -47,10 +48,18 @@ func (e *RoleAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint return []*eventstore.EventUniqueConstraint{NewAddProjectRoleUniqueConstraint(e.Key, e.projectID)} } -func NewRoleAddedEvent(ctx context.Context, key, displayName, group, projectID string) *RoleAddedEvent { +func NewRoleAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + key, + displayName, + group, + projectID string, +) *RoleAddedEvent { return &RoleAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, RoleAddedType, ), Key: key, @@ -91,13 +100,16 @@ func (e *RoleChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrai func NewRoleChangedEvent( ctx context.Context, - changes []RoleChanges) (*RoleChangedEvent, error) { + aggregate *eventstore.Aggregate, + changes []RoleChanges, +) (*RoleChangedEvent, error) { if len(changes) == 0 { return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-eR9vx", "Errors.NoChangesFound") } changeEvent := &RoleChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, RoleChangedType, ), } @@ -154,10 +166,15 @@ func (e *RoleRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrai return []*eventstore.EventUniqueConstraint{NewRemoveProjectRoleUniqueConstraint(e.Key, e.projectID)} } -func NewRoleRemovedEvent(ctx context.Context, key, projectID string) *RoleRemovedEvent { +func NewRoleRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + key, + projectID string) *RoleRemovedEvent { return &RoleRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, RoleRemovedType, ), Key: key, diff --git a/internal/v2/repository/user/human.go b/internal/v2/repository/user/human.go index d7b98ef8b7..6bb902f020 100644 --- a/internal/v2/repository/user/human.go +++ b/internal/v2/repository/user/human.go @@ -3,13 +3,14 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" "golang.org/x/text/language" - "time" ) const ( @@ -55,7 +56,7 @@ func (e *HumanAddedEvent) Data() interface{} { } func (e *HumanAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain)} + return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain)} } func (e *HumanAddedEvent) AddAddressData( @@ -88,7 +89,8 @@ func (e *HumanAddedEvent) AddPasswordData( func NewHumanAddedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, + userName, firstName, lastName, @@ -100,10 +102,10 @@ func NewHumanAddedEvent( userLoginMustBeDomain bool, ) *HumanAddedEvent { return &HumanAddedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanAddedType, - resourceOwner, ), UserName: userName, FirstName: firstName, @@ -161,7 +163,7 @@ func (e *HumanRegisteredEvent) Data() interface{} { } func (e *HumanRegisteredEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain)} + return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain)} } func (e *HumanRegisteredEvent) AddAddressData( @@ -194,7 +196,8 @@ func (e *HumanRegisteredEvent) AddPasswordData( func NewHumanRegisteredEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, + userName, firstName, lastName, @@ -206,10 +209,10 @@ func NewHumanRegisteredEvent( userLoginMustBeDomain bool, ) *HumanRegisteredEvent { return &HumanRegisteredEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanRegisteredType, - resourceOwner, ), UserName: userName, FirstName: firstName, @@ -251,12 +254,14 @@ func (e *HumanInitialCodeAddedEvent) UniqueConstraints() []*eventstore.EventUniq func NewHumanInitialCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, ) *HumanInitialCodeAddedEvent { return &HumanInitialCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanInitialCodeAddedType, ), Code: code, @@ -288,10 +293,11 @@ func (e *HumanInitialCodeSentEvent) UniqueConstraints() []*eventstore.EventUniqu return nil } -func NewHumanInitialCodeSentEvent(ctx context.Context) *HumanInitialCodeSentEvent { +func NewHumanInitialCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitialCodeSentEvent { return &HumanInitialCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanInitialCodeSentType, ), } @@ -315,10 +321,11 @@ func (e *HumanInitializedCheckSucceededEvent) UniqueConstraints() []*eventstore. return nil } -func NewHumanInitializedCheckSucceededEvent(ctx context.Context) *HumanInitializedCheckSucceededEvent { +func NewHumanInitializedCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitializedCheckSucceededEvent { return &HumanInitializedCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanInitializedCheckSucceededType, ), } @@ -342,10 +349,11 @@ func (e *HumanInitializedCheckFailedEvent) UniqueConstraints() []*eventstore.Eve return nil } -func NewHumanInitializedCheckFailedEvent(ctx context.Context) *HumanInitializedCheckFailedEvent { +func NewHumanInitializedCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitializedCheckFailedEvent { return &HumanInitializedCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanInitializedCheckFailedType, ), } @@ -371,10 +379,15 @@ func (e *HumanSignedOutEvent) UniqueConstraints() []*eventstore.EventUniqueConst return nil } -func NewHumanSignedOutEvent(ctx context.Context, userAgentID string) *HumanSignedOutEvent { +func NewHumanSignedOutEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userAgentID string, +) *HumanSignedOutEvent { return &HumanSignedOutEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanSignedOutType, ), UserAgentID: userAgentID, diff --git a/internal/v2/repository/user/human_address.go b/internal/v2/repository/user/human_address.go index 77d9311381..b4e6dbddcc 100644 --- a/internal/v2/repository/user/human_address.go +++ b/internal/v2/repository/user/human_address.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -31,10 +32,11 @@ func (e *HumanAddressChangedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } -func NewHumanAddressChangedEvent(ctx context.Context) *HumanAddressChangedEvent { +func NewHumanAddressChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanAddressChangedEvent { return &HumanAddressChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanAddressChangedType, ), } diff --git a/internal/v2/repository/user/human_email.go b/internal/v2/repository/user/human_email.go index e777960520..110c1d6e76 100644 --- a/internal/v2/repository/user/human_email.go +++ b/internal/v2/repository/user/human_email.go @@ -3,11 +3,12 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "time" ) const ( @@ -33,10 +34,11 @@ func (e *HumanEmailChangedEvent) UniqueConstraints() []*eventstore.EventUniqueCo return nil } -func NewHumanEmailChangedEvent(ctx context.Context) *HumanEmailChangedEvent { +func NewHumanEmailChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailChangedEvent { return &HumanEmailChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanEmailChangedType, ), } @@ -68,10 +70,11 @@ func (e *HumanEmailVerifiedEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewHumanEmailVerifiedEvent(ctx context.Context) *HumanEmailVerifiedEvent { +func NewHumanEmailVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailVerifiedEvent { return &HumanEmailVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanEmailVerifiedType, ), } @@ -97,10 +100,11 @@ func (e *HumanEmailVerificationFailedEvent) UniqueConstraints() []*eventstore.Ev return nil } -func NewHumanEmailVerificationFailedEvent(ctx context.Context) *HumanEmailVerificationFailedEvent { +func NewHumanEmailVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailVerificationFailedEvent { return &HumanEmailVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanEmailVerificationFailedType, ), } @@ -129,11 +133,13 @@ func (e *HumanEmailCodeAddedEvent) UniqueConstraints() []*eventstore.EventUnique func NewHumanEmailCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration) *HumanEmailCodeAddedEvent { return &HumanEmailCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanEmailCodeAddedType, ), Code: code, @@ -165,10 +171,11 @@ func (e *HumanEmailCodeSentEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewHumanEmailCodeSentEvent(ctx context.Context) *HumanEmailCodeSentEvent { +func NewHumanEmailCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailCodeSentEvent { return &HumanEmailCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanEmailCodeSentType, ), } diff --git a/internal/v2/repository/user/human_external_idp.go b/internal/v2/repository/user/human_external_idp.go index c38b1f17bb..7cbba694e3 100644 --- a/internal/v2/repository/user/human_external_idp.go +++ b/internal/v2/repository/user/human_external_idp.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -49,10 +50,17 @@ func (e *HumanExternalIDPAddedEvent) UniqueConstraints() []*eventstore.EventUniq return []*eventstore.EventUniqueConstraint{NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)} } -func NewHumanExternalIDPAddedEvent(ctx context.Context, idpConfigID, displayName, externalUserID string) *HumanExternalIDPAddedEvent { +func NewHumanExternalIDPAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + idpConfigID, + displayName, + externalUserID string, +) *HumanExternalIDPAddedEvent { return &HumanExternalIDPAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanExternalIDPAddedType, ), IDPConfigID: idpConfigID, @@ -89,10 +97,16 @@ func (e *HumanExternalIDPRemovedEvent) UniqueConstraints() []*eventstore.EventUn return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)} } -func NewHumanExternalIDPRemovedEvent(ctx context.Context, idpConfigID, externalUserID string) *HumanExternalIDPRemovedEvent { +func NewHumanExternalIDPRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + idpConfigID, + externalUserID string, +) *HumanExternalIDPRemovedEvent { return &HumanExternalIDPRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanExternalIDPRemovedType, ), IDPConfigID: idpConfigID, @@ -128,10 +142,16 @@ func (e *HumanExternalIDPCascadeRemovedEvent) UniqueConstraints() []*eventstore. return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)} } -func NewHumanExternalIDPCascadeRemovedEvent(ctx context.Context, idpConfigID, externalUserID string) *HumanExternalIDPCascadeRemovedEvent { +func NewHumanExternalIDPCascadeRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + idpConfigID, + externalUserID string, +) *HumanExternalIDPCascadeRemovedEvent { return &HumanExternalIDPCascadeRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanExternalIDPCascadeRemovedType, ), IDPConfigID: idpConfigID, @@ -165,10 +185,14 @@ func (e *HumanExternalIDPCheckSucceededEvent) UniqueConstraints() []*eventstore. return nil } -func NewHumanExternalIDPCheckSucceededEvent(ctx context.Context, info *AuthRequestInfo) *HumanExternalIDPCheckSucceededEvent { +func NewHumanExternalIDPCheckSucceededEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + info *AuthRequestInfo) *HumanExternalIDPCheckSucceededEvent { return &HumanExternalIDPCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanExternalLoginCheckSucceededType, ), AuthRequestInfo: info, diff --git a/internal/v2/repository/user/human_mfa_events.go b/internal/v2/repository/user/human_mfa_events.go index 60ba93ec17..6e782ed389 100644 --- a/internal/v2/repository/user/human_mfa_events.go +++ b/internal/v2/repository/user/human_mfa_events.go @@ -2,6 +2,7 @@ package user import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" ) @@ -23,10 +24,11 @@ func (e *HumanMFAInitSkippedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } -func NewHumanMFAInitSkippedEvent(ctx context.Context) *HumanMFAInitSkippedEvent { +func NewHumanMFAInitSkippedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanMFAInitSkippedEvent { return &HumanMFAInitSkippedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAInitSkippedType, ), } diff --git a/internal/v2/repository/user/human_mfa_otp.go b/internal/v2/repository/user/human_mfa_otp.go index 14d73bdce1..2d1ab31ec2 100644 --- a/internal/v2/repository/user/human_mfa_otp.go +++ b/internal/v2/repository/user/human_mfa_otp.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" @@ -32,11 +33,15 @@ func (e *HumanOTPAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstr return nil } -func NewHumanOTPAddedEvent(ctx context.Context, - secret *crypto.CryptoValue) *HumanOTPAddedEvent { +func NewHumanOTPAddedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + secret *crypto.CryptoValue, +) *HumanOTPAddedEvent { return &HumanOTPAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAOTPAddedType, ), Secret: secret, @@ -67,10 +72,15 @@ func (e *HumanOTPVerifiedEvent) UniqueConstraints() []*eventstore.EventUniqueCon return nil } -func NewHumanOTPVerifiedEvent(ctx context.Context, userAgentID string) *HumanOTPVerifiedEvent { +func NewHumanOTPVerifiedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userAgentID string, +) *HumanOTPVerifiedEvent { return &HumanOTPVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAOTPVerifiedType, ), UserAgentID: userAgentID, @@ -95,10 +105,14 @@ func (e *HumanOTPRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueCons return nil } -func NewHumanOTPRemovedEvent(ctx context.Context) *HumanOTPRemovedEvent { +func NewHumanOTPRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, +) *HumanOTPRemovedEvent { return &HumanOTPRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAOTPRemovedType, ), } @@ -123,10 +137,15 @@ func (e *HumanOTPCheckSucceededEvent) UniqueConstraints() []*eventstore.EventUni return nil } -func NewHumanOTPCheckSucceededEvent(ctx context.Context, info *AuthRequestInfo) *HumanOTPCheckSucceededEvent { +func NewHumanOTPCheckSucceededEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + info *AuthRequestInfo, +) *HumanOTPCheckSucceededEvent { return &HumanOTPCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAOTPCheckSucceededType, ), AuthRequestInfo: info, @@ -157,10 +176,15 @@ func (e *HumanOTPCheckFailedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } -func NewHumanOTPCheckFailedEvent(ctx context.Context, info *AuthRequestInfo) *HumanOTPCheckFailedEvent { +func NewHumanOTPCheckFailedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + info *AuthRequestInfo, +) *HumanOTPCheckFailedEvent { return &HumanOTPCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanMFAOTPCheckFailedType, ), AuthRequestInfo: info, diff --git a/internal/v2/repository/user/human_mfa_passwordless.go b/internal/v2/repository/user/human_mfa_passwordless.go index 950cffb89f..ec5a7ce7d2 100644 --- a/internal/v2/repository/user/human_mfa_passwordless.go +++ b/internal/v2/repository/user/human_mfa_passwordless.go @@ -2,6 +2,7 @@ package user import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" ) @@ -23,6 +24,7 @@ type HumanPasswordlessAddedEvent struct { func NewHumanPasswordlessAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID, challenge string, ) *HumanPasswordlessAddedEvent { @@ -30,6 +32,7 @@ func NewHumanPasswordlessAddedEvent( HumanWebAuthNAddedEvent: *NewHumanWebAuthNAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenAddedType, ), webAuthNTokenID, @@ -53,6 +56,7 @@ type HumanPasswordlessVerifiedEvent struct { func NewHumanPasswordlessVerifiedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID, webAuthNTokenName, attestationType string, @@ -65,6 +69,7 @@ func NewHumanPasswordlessVerifiedEvent( HumanWebAuthNVerifiedEvent: *NewHumanWebAuthNVerifiedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenVerifiedType, ), webAuthNTokenID, @@ -93,6 +98,7 @@ type HumanPasswordlessSignCountChangedEvent struct { func NewHumanPasswordlessSignCountChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID string, signCount uint32, ) *HumanPasswordlessSignCountChangedEvent { @@ -100,6 +106,7 @@ func NewHumanPasswordlessSignCountChangedEvent( HumanWebAuthNSignCountChangedEvent: *NewHumanWebAuthNSignCountChangedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenSignCountChangedType, ), webAuthNTokenID, @@ -121,14 +128,22 @@ type HumanPasswordlessRemovedEvent struct { HumanWebAuthNRemovedEvent } +func PrepareHumanPasswordlessRemovedEvent(ctx context.Context, webAuthNTokenID string) func(*eventstore.Aggregate) eventstore.EventPusher { + return func(a *eventstore.Aggregate) eventstore.EventPusher { + return NewHumanPasswordlessRemovedEvent(ctx, a, webAuthNTokenID) + } +} + func NewHumanPasswordlessRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID string, ) *HumanPasswordlessRemovedEvent { return &HumanPasswordlessRemovedEvent{ HumanWebAuthNRemovedEvent: *NewHumanWebAuthNRemovedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenRemovedType, ), webAuthNTokenID, @@ -151,6 +166,7 @@ type HumanPasswordlessBeginLoginEvent struct { func NewHumanPasswordlessBeginLoginEvent( ctx context.Context, + aggregate *eventstore.Aggregate, challenge string, info *AuthRequestInfo, ) *HumanPasswordlessBeginLoginEvent { @@ -158,6 +174,7 @@ func NewHumanPasswordlessBeginLoginEvent( HumanWebAuthNBeginLoginEvent: *NewHumanWebAuthNBeginLoginEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenVerifiedType, ), challenge, @@ -179,11 +196,12 @@ type HumanPasswordlessCheckSucceededEvent struct { HumanWebAuthNCheckSucceededEvent } -func NewHumanPasswordlessCheckSucceededEvent(ctx context.Context) *HumanPasswordlessCheckSucceededEvent { +func NewHumanPasswordlessCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordlessCheckSucceededEvent { return &HumanPasswordlessCheckSucceededEvent{ HumanWebAuthNCheckSucceededEvent: *NewHumanWebAuthNCheckSucceededEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenCheckSucceededType, ), ), @@ -203,11 +221,12 @@ type HumanPasswordlessCheckFailedEvent struct { HumanWebAuthNCheckFailedEvent } -func NewHumanPasswordlessCheckFailedEvent(ctx context.Context) *HumanPasswordlessCheckFailedEvent { +func NewHumanPasswordlessCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordlessCheckFailedEvent { return &HumanPasswordlessCheckFailedEvent{ HumanWebAuthNCheckFailedEvent: *NewHumanWebAuthNCheckFailedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordlessTokenCheckFailedType, ), ), diff --git a/internal/v2/repository/user/human_mfa_u2f.go b/internal/v2/repository/user/human_mfa_u2f.go index effde7e1c6..ddfa74ce56 100644 --- a/internal/v2/repository/user/human_mfa_u2f.go +++ b/internal/v2/repository/user/human_mfa_u2f.go @@ -2,6 +2,7 @@ package user import ( "context" + "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" ) @@ -23,6 +24,7 @@ type HumanU2FAddedEvent struct { func NewHumanU2FAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID, challenge string, ) *HumanU2FAddedEvent { @@ -30,6 +32,7 @@ func NewHumanU2FAddedEvent( HumanWebAuthNAddedEvent: *NewHumanWebAuthNAddedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenAddedType, ), webAuthNTokenID, @@ -53,6 +56,7 @@ type HumanU2FVerifiedEvent struct { func NewHumanU2FVerifiedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID, webAuthNTokenName, attestationType string, @@ -65,6 +69,7 @@ func NewHumanU2FVerifiedEvent( HumanWebAuthNVerifiedEvent: *NewHumanWebAuthNVerifiedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenVerifiedType, ), webAuthNTokenID, @@ -93,6 +98,7 @@ type HumanU2FSignCountChangedEvent struct { func NewHumanU2FSignCountChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID string, signCount uint32, ) *HumanU2FSignCountChangedEvent { @@ -100,6 +106,7 @@ func NewHumanU2FSignCountChangedEvent( HumanWebAuthNSignCountChangedEvent: *NewHumanWebAuthNSignCountChangedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenSignCountChangedType, ), webAuthNTokenID, @@ -121,14 +128,22 @@ type HumanU2FRemovedEvent struct { HumanWebAuthNRemovedEvent } +func PrepareHumanU2FRemovedEvent(ctx context.Context, webAuthNTokenID string) func(*eventstore.Aggregate) eventstore.EventPusher { + return func(a *eventstore.Aggregate) eventstore.EventPusher { + return NewHumanU2FRemovedEvent(ctx, a, webAuthNTokenID) + } +} + func NewHumanU2FRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, webAuthNTokenID string, ) *HumanU2FRemovedEvent { return &HumanU2FRemovedEvent{ HumanWebAuthNRemovedEvent: *NewHumanWebAuthNRemovedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenRemovedType, ), webAuthNTokenID, @@ -151,6 +166,7 @@ type HumanU2FBeginLoginEvent struct { func NewHumanU2FBeginLoginEvent( ctx context.Context, + aggregate *eventstore.Aggregate, challenge string, info *AuthRequestInfo, ) *HumanU2FBeginLoginEvent { @@ -158,6 +174,7 @@ func NewHumanU2FBeginLoginEvent( HumanWebAuthNBeginLoginEvent: *NewHumanWebAuthNBeginLoginEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenVerifiedType, ), challenge, @@ -179,11 +196,12 @@ type HumanU2FCheckSucceededEvent struct { HumanWebAuthNCheckSucceededEvent } -func NewHumanU2FCheckSucceededEvent(ctx context.Context) *HumanU2FCheckSucceededEvent { +func NewHumanU2FCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanU2FCheckSucceededEvent { return &HumanU2FCheckSucceededEvent{ HumanWebAuthNCheckSucceededEvent: *NewHumanWebAuthNCheckSucceededEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenCheckSucceededType, ), ), @@ -203,11 +221,12 @@ type HumanU2FCheckFailedEvent struct { HumanWebAuthNCheckFailedEvent } -func NewHumanU2FCheckFailedEvent(ctx context.Context) *HumanU2FCheckFailedEvent { +func NewHumanU2FCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanU2FCheckFailedEvent { return &HumanU2FCheckFailedEvent{ HumanWebAuthNCheckFailedEvent: *NewHumanWebAuthNCheckFailedEvent( eventstore.NewBaseEventForPush( ctx, + aggregate, HumanU2FTokenCheckFailedType, ), ), diff --git a/internal/v2/repository/user/human_password.go b/internal/v2/repository/user/human_password.go index f35d948b3b..bf551e0016 100644 --- a/internal/v2/repository/user/human_password.go +++ b/internal/v2/repository/user/human_password.go @@ -3,12 +3,13 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" - "time" ) const ( @@ -38,6 +39,7 @@ func (e *HumanPasswordChangedEvent) UniqueConstraints() []*eventstore.EventUniqu func NewHumanPasswordChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, secret *crypto.CryptoValue, changeRequired bool, userAgentID string, @@ -45,6 +47,7 @@ func NewHumanPasswordChangedEvent( return &HumanPasswordChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordChangedType, ), Secret: secret, @@ -83,6 +86,7 @@ func (e *HumanPasswordCodeAddedEvent) UniqueConstraints() []*eventstore.EventUni func NewHumanPasswordCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, notificationType domain.NotificationType, @@ -90,6 +94,7 @@ func NewHumanPasswordCodeAddedEvent( return &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordCodeAddedType, ), Code: code, @@ -122,10 +127,11 @@ func (e *HumanPasswordCodeSentEvent) UniqueConstraints() []*eventstore.EventUniq return nil } -func NewHumanPasswordCodeSentEvent(ctx context.Context) *HumanPasswordCodeSentEvent { +func NewHumanPasswordCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordCodeSentEvent { return &HumanPasswordCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordCodeSentType, ), } @@ -150,10 +156,15 @@ func (e *HumanPasswordCheckSucceededEvent) UniqueConstraints() []*eventstore.Eve return nil } -func NewHumanPasswordCheckSucceededEvent(ctx context.Context, info *AuthRequestInfo) *HumanPasswordCheckSucceededEvent { +func NewHumanPasswordCheckSucceededEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + info *AuthRequestInfo, +) *HumanPasswordCheckSucceededEvent { return &HumanPasswordCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordCheckSucceededType, ), AuthRequestInfo: info, @@ -185,10 +196,15 @@ func (e *HumanPasswordCheckFailedEvent) UniqueConstraints() []*eventstore.EventU return nil } -func NewHumanPasswordCheckFailedEvent(ctx context.Context, info *AuthRequestInfo) *HumanPasswordCheckFailedEvent { +func NewHumanPasswordCheckFailedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + info *AuthRequestInfo, +) *HumanPasswordCheckFailedEvent { return &HumanPasswordCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPasswordCheckFailedType, ), AuthRequestInfo: info, diff --git a/internal/v2/repository/user/human_phone.go b/internal/v2/repository/user/human_phone.go index 47fac6329f..4651bdc74c 100644 --- a/internal/v2/repository/user/human_phone.go +++ b/internal/v2/repository/user/human_phone.go @@ -3,11 +3,12 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "time" ) const ( @@ -34,10 +35,11 @@ func (e *HumanPhoneChangedEvent) UniqueConstraints() []*eventstore.EventUniqueCo return nil } -func NewHumanPhoneChangedEvent(ctx context.Context) *HumanPhoneChangedEvent { +func NewHumanPhoneChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneChangedEvent { return &HumanPhoneChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneChangedType, ), } @@ -67,10 +69,11 @@ func (e *HumanPhoneRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueCo return nil } -func NewHumanPhoneRemovedEvent(ctx context.Context) *HumanPhoneRemovedEvent { +func NewHumanPhoneRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneRemovedEvent { return &HumanPhoneRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneRemovedType, ), } @@ -96,10 +99,11 @@ func (e *HumanPhoneVerifiedEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewHumanPhoneVerifiedEvent(ctx context.Context) *HumanPhoneVerifiedEvent { +func NewHumanPhoneVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneVerifiedEvent { return &HumanPhoneVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneVerifiedType, ), } @@ -124,10 +128,11 @@ func (e *HumanPhoneVerificationFailedEvent) UniqueConstraints() []*eventstore.Ev return nil } -func NewHumanPhoneVerificationFailedEvent(ctx context.Context) *HumanPhoneVerificationFailedEvent { +func NewHumanPhoneVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneVerificationFailedEvent { return &HumanPhoneVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneVerificationFailedType, ), } @@ -156,12 +161,14 @@ func (e *HumanPhoneCodeAddedEvent) UniqueConstraints() []*eventstore.EventUnique func NewHumanPhoneCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, ) *HumanPhoneCodeAddedEvent { return &HumanPhoneCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneCodeAddedType, ), Code: code, @@ -193,10 +200,11 @@ func (e *HumanPhoneCodeSentEvent) UniqueConstraints() []*eventstore.EventUniqueC return nil } -func NewHumanPhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent { +func NewHumanPhoneCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneCodeSentEvent { return &HumanPhoneCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanPhoneCodeSentType, ), } diff --git a/internal/v2/repository/user/human_profile.go b/internal/v2/repository/user/human_profile.go index 4b3e8154f6..c3de588e82 100644 --- a/internal/v2/repository/user/human_profile.go +++ b/internal/v2/repository/user/human_profile.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -34,11 +35,11 @@ func (e *HumanProfileChangedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } -func NewHumanProfileChangedEvent( - ctx context.Context) *HumanProfileChangedEvent { +func NewHumanProfileChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanProfileChangedEvent { return &HumanProfileChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, HumanProfileChangedType, ), } diff --git a/internal/v2/repository/user/machine.go b/internal/v2/repository/user/machine.go index ddc408be69..d0cc2ecdd9 100644 --- a/internal/v2/repository/user/machine.go +++ b/internal/v2/repository/user/machine.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -29,11 +30,12 @@ func (e *MachineAddedEvent) Data() interface{} { } func (e *MachineAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.UserLoginMustBeDomain)} + return []*eventstore.EventUniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.UserLoginMustBeDomain)} } func NewMachineAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userName, name, description string, @@ -42,6 +44,7 @@ func NewMachineAddedEvent( return &MachineAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, MachineAddedEventType, ), UserName: userName, @@ -82,10 +85,12 @@ func (e *MachineChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConst func NewMachineChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *MachineChangedEvent { return &MachineChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, MachineChangedEventType, ), } diff --git a/internal/v2/repository/user/machine_key.go b/internal/v2/repository/user/machine_key.go index 43d70b0ccb..795000dd8e 100644 --- a/internal/v2/repository/user/machine_key.go +++ b/internal/v2/repository/user/machine_key.go @@ -3,11 +3,12 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/domain" - "time" ) const ( @@ -35,6 +36,7 @@ func (e *MachineKeyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueCons func NewMachineKeyAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, keyID string, keyType domain.MachineKeyType, expirationDate time.Time, @@ -43,6 +45,7 @@ func NewMachineKeyAddedEvent( return &MachineKeyAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, MachineKeyAddedEventType, ), KeyID: keyID, @@ -80,11 +83,13 @@ func (e *MachineKeyRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueCo func NewMachineKeyRemovedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, keyID string, ) *MachineKeyRemovedEvent { return &MachineKeyRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, MachineKeyRemovedEventType, ), KeyID: keyID, diff --git a/internal/v2/repository/user/user.go b/internal/v2/repository/user/user.go index 367964536a..79cc737c97 100644 --- a/internal/v2/repository/user/user.go +++ b/internal/v2/repository/user/user.go @@ -3,10 +3,11 @@ package user import ( "context" "encoding/json" + "time" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "time" ) const ( @@ -56,10 +57,11 @@ func (e *UserLockedEvent) UniqueConstraints() []*eventstore.EventUniqueConstrain return nil } -func NewUserLockedEvent(ctx context.Context) *UserLockedEvent { +func NewUserLockedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserLockedEvent { return &UserLockedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserLockedType, ), } @@ -83,10 +85,11 @@ func (e *UserUnlockedEvent) UniqueConstraints() []*eventstore.EventUniqueConstra return nil } -func NewUserUnlockedEvent(ctx context.Context) *UserUnlockedEvent { +func NewUserUnlockedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserUnlockedEvent { return &UserUnlockedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserUnlockedType, ), } @@ -110,10 +113,11 @@ func (e *UserDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueCons return nil } -func NewUserDeactivatedEvent(ctx context.Context) *UserDeactivatedEvent { +func NewUserDeactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserDeactivatedEvent { return &UserDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserDeactivatedType, ), } @@ -137,10 +141,11 @@ func (e *UserReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueCons return nil } -func NewUserReactivatedEvent(ctx context.Context) *UserReactivatedEvent { +func NewUserReactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserReactivatedEvent { return &UserReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserReactivatedType, ), } @@ -155,8 +160,8 @@ func UserReactivatedEventMapper(event *repository.Event) (eventstore.EventReader type UserRemovedEvent struct { eventstore.BaseEvent `json:"-"` - UserName string - UserLoginMustBeDomain bool + userName string + loginMustBeDomain bool } func (e *UserRemovedEvent) Data() interface{} { @@ -164,18 +169,23 @@ func (e *UserRemovedEvent) Data() interface{} { } func (e *UserRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.UserLoginMustBeDomain)} + return []*eventstore.EventUniqueConstraint{NewRemoveUsernameUniqueConstraint(e.userName, e.Aggregate().ResourceOwner, e.loginMustBeDomain)} } -func NewUserRemovedEvent(ctx context.Context, resourceOwner, userName string, userLoginMustBeDomain bool) *UserRemovedEvent { +func NewUserRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userName string, + userLoginMustBeDomain bool, +) *UserRemovedEvent { return &UserRemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserRemovedType, - resourceOwner, ), - UserName: userName, - UserLoginMustBeDomain: userLoginMustBeDomain, + userName: userName, + loginMustBeDomain: userLoginMustBeDomain, } } @@ -207,6 +217,7 @@ func (e *UserTokenAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConst func NewUserTokenAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, tokenID, applicationID, userAgentID, @@ -218,6 +229,7 @@ func NewUserTokenAddedEvent( return &UserTokenAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserTokenAddedType, ), TokenID: tokenID, @@ -256,13 +268,14 @@ func (e *DomainClaimedEvent) Data() interface{} { func (e *DomainClaimedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { return []*eventstore.EventUniqueConstraint{ - NewRemoveUsernameUniqueConstraint(e.oldUserName, e.ResourceOwner(), e.userLoginMustBeDomain), - NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain), + NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain), + NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain), } } func NewDomainClaimedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, userName, oldUserName string, userLoginMustBeDomain bool, @@ -270,6 +283,7 @@ func NewDomainClaimedEvent( return &DomainClaimedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserDomainClaimedType, ), UserName: userName, @@ -304,10 +318,12 @@ func (e *DomainClaimedSentEvent) UniqueConstraints() []*eventstore.EventUniqueCo func NewDomainClaimedSentEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *DomainClaimedSentEvent { return &DomainClaimedSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserDomainClaimedSentType, ), } @@ -333,13 +349,14 @@ func (e *UsernameChangedEvent) Data() interface{} { func (e *UsernameChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { return []*eventstore.EventUniqueConstraint{ - NewRemoveUsernameUniqueConstraint(e.oldUserName, e.ResourceOwner(), e.userLoginMustBeDomain), - NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain), + NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain), + NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain), } } func NewUsernameChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, oldUserName, newUserName string, userLoginMustBeDomain bool, @@ -347,6 +364,7 @@ func NewUsernameChangedEvent( return &UsernameChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserUserNameChangedType, ), UserName: newUserName, diff --git a/internal/v2/repository/user/v1.go b/internal/v2/repository/user/v1.go index 17b624cfc8..589b79205b 100644 --- a/internal/v2/repository/user/v1.go +++ b/internal/v2/repository/user/v1.go @@ -2,11 +2,12 @@ package user import ( "context" + "time" + "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/domain" "golang.org/x/text/language" - "time" ) const ( @@ -59,6 +60,8 @@ const ( func NewUserV1AddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, + userName, firstName, lastName, @@ -77,6 +80,7 @@ func NewUserV1AddedEvent( return &HumanAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1AddedType, ), UserName: userName, @@ -98,6 +102,8 @@ func NewUserV1AddedEvent( func NewUserV1RegisteredEvent( ctx context.Context, + aggregate *eventstore.Aggregate, + userName, firstName, lastName, @@ -116,6 +122,7 @@ func NewUserV1RegisteredEvent( return &HumanRegisteredEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1RegisteredType, ), UserName: userName, @@ -137,12 +144,14 @@ func NewUserV1RegisteredEvent( func NewUserV1InitialCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, ) *HumanInitialCodeAddedEvent { return &HumanInitialCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1InitialCodeAddedType, ), Code: code, @@ -150,37 +159,41 @@ func NewUserV1InitialCodeAddedEvent( } } -func NewUserV1InitialCodeSentEvent(ctx context.Context) *HumanInitialCodeSentEvent { +func NewUserV1InitialCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitialCodeSentEvent { return &HumanInitialCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1InitialCodeSentType, ), } } -func NewUserV1InitializedCheckSucceededEvent(ctx context.Context) *HumanInitializedCheckSucceededEvent { +func NewUserV1InitializedCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitializedCheckSucceededEvent { return &HumanInitializedCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1InitializedCheckSucceededType, ), } } -func NewUserV1InitializedCheckFailedEvent(ctx context.Context) *HumanInitializedCheckFailedEvent { +func NewUserV1InitializedCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanInitializedCheckFailedEvent { return &HumanInitializedCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1InitializedCheckFailedType, ), } } -func NewUserV1SignedOutEvent(ctx context.Context) *HumanSignedOutEvent { +func NewUserV1SignedOutEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanSignedOutEvent { return &HumanSignedOutEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1SignedOutType, ), } @@ -188,12 +201,14 @@ func NewUserV1SignedOutEvent(ctx context.Context) *HumanSignedOutEvent { func NewUserV1PasswordChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, secret *crypto.CryptoValue, changeRequired bool, ) *HumanPasswordChangedEvent { return &HumanPasswordChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PasswordChangedType, ), Secret: secret, @@ -203,6 +218,7 @@ func NewUserV1PasswordChangedEvent( func NewUserV1PasswordCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, notificationType domain.NotificationType, @@ -210,6 +226,7 @@ func NewUserV1PasswordCodeAddedEvent( return &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PasswordCodeAddedType, ), Code: code, @@ -218,56 +235,66 @@ func NewUserV1PasswordCodeAddedEvent( } } -func NewUserV1PasswordCodeSentEvent(ctx context.Context) *HumanPasswordCodeSentEvent { +func NewUserV1PasswordCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordCodeSentEvent { return &HumanPasswordCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PasswordCodeSentType, ), } } -func NewUserV1PasswordCheckSucceededEvent(ctx context.Context) *HumanPasswordCheckSucceededEvent { +func NewUserV1PasswordCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordCheckSucceededEvent { return &HumanPasswordCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PasswordCheckSucceededType, ), } } -func NewUserV1PasswordCheckFailedEvent(ctx context.Context) *HumanPasswordCheckFailedEvent { +func NewUserV1PasswordCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPasswordCheckFailedEvent { return &HumanPasswordCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PasswordCheckFailedType, ), } } -func NewUserV1EmailChangedEvent(ctx context.Context, emailAddress string) *HumanEmailChangedEvent { +func NewUserV1EmailChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + emailAddress string, +) *HumanEmailChangedEvent { return &HumanEmailChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1EmailChangedType, ), EmailAddress: emailAddress, } } -func NewUserV1EmailVerifiedEvent(ctx context.Context) *HumanEmailVerifiedEvent { +func NewUserV1EmailVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailVerifiedEvent { return &HumanEmailVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1EmailVerifiedType, ), } } -func NewUserV1EmailVerificationFailedEvent(ctx context.Context) *HumanEmailVerificationFailedEvent { +func NewUserV1EmailVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailVerificationFailedEvent { return &HumanEmailVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1EmailVerificationFailedType, ), } @@ -275,12 +302,14 @@ func NewUserV1EmailVerificationFailedEvent(ctx context.Context) *HumanEmailVerif func NewUserV1EmailCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, ) *HumanEmailCodeAddedEvent { return &HumanEmailCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1EmailCodeAddedType, ), Code: code, @@ -288,47 +317,56 @@ func NewUserV1EmailCodeAddedEvent( } } -func NewUserV1EmailCodeSentEvent(ctx context.Context) *HumanEmailCodeSentEvent { +func NewUserV1EmailCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanEmailCodeSentEvent { return &HumanEmailCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1EmailCodeSentType, ), } } -func NewUserV1PhoneChangedEvent(ctx context.Context, phone string) *HumanPhoneChangedEvent { +func NewUserV1PhoneChangedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + phone string, +) *HumanPhoneChangedEvent { return &HumanPhoneChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneChangedType, ), PhoneNumber: phone, } } -func NewUserV1PhoneRemovedEvent(ctx context.Context) *HumanPhoneRemovedEvent { +func NewUserV1PhoneRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneRemovedEvent { return &HumanPhoneRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneRemovedType, ), } } -func NewUserV1PhoneVerifiedEvent(ctx context.Context) *HumanPhoneVerifiedEvent { +func NewUserV1PhoneVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneVerifiedEvent { return &HumanPhoneVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneVerifiedType, ), } } -func NewUserV1PhoneVerificationFailedEvent(ctx context.Context) *HumanPhoneVerificationFailedEvent { +func NewUserV1PhoneVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneVerificationFailedEvent { return &HumanPhoneVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneVerificationFailedType, ), } @@ -336,12 +374,14 @@ func NewUserV1PhoneVerificationFailedEvent(ctx context.Context) *HumanPhoneVerif func NewUserV1PhoneCodeAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, code *crypto.CryptoValue, expiry time.Duration, ) *HumanPhoneCodeAddedEvent { return &HumanPhoneCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneCodeAddedType, ), Code: code, @@ -349,10 +389,11 @@ func NewUserV1PhoneCodeAddedEvent( } } -func NewUserV1PhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent { +func NewUserV1PhoneCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanPhoneCodeSentEvent { return &HumanPhoneCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1PhoneCodeSentType, ), } @@ -360,10 +401,12 @@ func NewUserV1PhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent { func NewUserV1ProfileChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, ) *HumanProfileChangedEvent { return &HumanProfileChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1ProfileChangedType, ), } @@ -371,6 +414,7 @@ func NewUserV1ProfileChangedEvent( func NewUserV1AddressChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, country, locality, postalCode, @@ -380,15 +424,17 @@ func NewUserV1AddressChangedEvent( return &HumanAddressChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1AddressChangedType, ), } } -func NewUserV1MFAInitSkippedEvent(ctx context.Context) *HumanMFAInitSkippedEvent { +func NewUserV1MFAInitSkippedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanMFAInitSkippedEvent { return &HumanMFAInitSkippedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAInitSkippedType, ), } @@ -396,48 +442,54 @@ func NewUserV1MFAInitSkippedEvent(ctx context.Context) *HumanMFAInitSkippedEvent func NewUserV1MFAOTPAddedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, secret *crypto.CryptoValue, ) *HumanOTPAddedEvent { return &HumanOTPAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAOTPAddedType, ), Secret: secret, } } -func NewUserV1MFAOTPVerifiedEvent(ctx context.Context) *HumanOTPVerifiedEvent { +func NewUserV1MFAOTPVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanOTPVerifiedEvent { return &HumanOTPVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAOTPVerifiedType, ), } } -func NewUserV1MFAOTPRemovedEvent(ctx context.Context) *HumanOTPRemovedEvent { +func NewUserV1MFAOTPRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanOTPRemovedEvent { return &HumanOTPRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAOTPRemovedType, ), } } -func NewUserV1MFAOTPCheckSucceededEvent(ctx context.Context) *HumanOTPCheckSucceededEvent { +func NewUserV1MFAOTPCheckSucceededEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanOTPCheckSucceededEvent { return &HumanOTPCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAOTPCheckSucceededType, ), } } -func NewUserV1MFAOTPCheckFailedEvent(ctx context.Context) *HumanOTPCheckFailedEvent { +func NewUserV1MFAOTPCheckFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *HumanOTPCheckFailedEvent { return &HumanOTPCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserV1MFAOTPCheckFailedType, ), } diff --git a/internal/v2/repository/usergrant/user_grant.go b/internal/v2/repository/usergrant/user_grant.go index f216a934ef..1f006fbd0c 100644 --- a/internal/v2/repository/usergrant/user_grant.go +++ b/internal/v2/repository/usergrant/user_grant.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" @@ -48,21 +49,21 @@ func (e *UserGrantAddedEvent) Data() interface{} { } func (e *UserGrantAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID, e.ProjectGrantID)} + return []*eventstore.EventUniqueConstraint{NewAddUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.UserID, e.ProjectID, e.ProjectGrantID)} } func NewUserGrantAddedEvent( ctx context.Context, - resourceOwner, + aggregate *eventstore.Aggregate, userID, projectID, projectGrantID string, roleKeys []string) *UserGrantAddedEvent { return &UserGrantAddedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantAddedType, - resourceOwner, ), UserID: userID, ProjectID: projectID, @@ -99,10 +100,12 @@ func (e *UserGrantChangedEvent) UniqueConstraints() []*eventstore.EventUniqueCon func NewUserGrantChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, roleKeys []string) *UserGrantChangedEvent { return &UserGrantChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantChangedType, ), RoleKeys: roleKeys, @@ -137,10 +140,12 @@ func (e *UserGrantCascadeChangedEvent) UniqueConstraints() []*eventstore.EventUn func NewUserGrantCascadeChangedEvent( ctx context.Context, + aggregate *eventstore.Aggregate, roleKeys []string) *UserGrantCascadeChangedEvent { return &UserGrantCascadeChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantCascadeChangedType, ), RoleKeys: roleKeys, @@ -172,15 +177,21 @@ func (e *UserGrantRemovedEvent) Data() interface{} { } func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID, e.projectGrantID)} + return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.userID, e.projectID, e.projectGrantID)} } -func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projectID, projectGrantID string) *UserGrantRemovedEvent { +func NewUserGrantRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userID, + projectID, + projectGrantID string, +) *UserGrantRemovedEvent { return &UserGrantRemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantRemovedType, - resourceOwner, ), userID: userID, projectID: projectID, @@ -206,15 +217,21 @@ func (e *UserGrantCascadeRemovedEvent) Data() interface{} { } func (e *UserGrantCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { - return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID, e.projectGrantID)} + return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.userID, e.projectID, e.projectGrantID)} } -func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID, projectGrantID string) *UserGrantCascadeRemovedEvent { +func NewUserGrantCascadeRemovedEvent( + ctx context.Context, + aggregate *eventstore.Aggregate, + userID, + projectID, + projectGrantID string, +) *UserGrantCascadeRemovedEvent { return &UserGrantCascadeRemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantCascadeRemovedType, - resourceOwner, ), userID: userID, projectID: projectID, @@ -240,10 +257,11 @@ func (e *UserGrantDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqu return nil } -func NewUserGrantDeactivatedEvent(ctx context.Context) *UserGrantDeactivatedEvent { +func NewUserGrantDeactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserGrantDeactivatedEvent { return &UserGrantDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantDeactivatedType, ), } @@ -267,10 +285,11 @@ func (e *UserGrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqu return nil } -func NewUserGrantReactivatedEvent(ctx context.Context) *UserGrantReactivatedEvent { +func NewUserGrantReactivatedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *UserGrantReactivatedEvent { return &UserGrantReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, + aggregate, UserGrantReactivatedType, ), } diff --git a/migrations/cockroach/V1.34__indexes.sql b/migrations/cockroach/V1.34__indexes.sql new file mode 100644 index 0000000000..6bc2a0099e --- /dev/null +++ b/migrations/cockroach/V1.34__indexes.sql @@ -0,0 +1,2 @@ +CREATE INDEX event_type ON eventstore.events (event_type); +CREATE INDEX resource_owner ON eventstore.events (resource_owner); diff --git a/pkg/grpc/management/changes.go b/pkg/grpc/management/changes.go index 3d577498e7..3120e82aaf 100644 --- a/pkg/grpc/management/changes.go +++ b/pkg/grpc/management/changes.go @@ -1,6 +1,8 @@ package management -import "github.com/caos/zitadel/internal/api/grpc/server/middleware" +import ( + "github.com/caos/zitadel/internal/api/grpc/server/middleware" +) func (c *Changes) Localizers() []middleware.Localizer { if c == nil {