This commit is contained in:
adlerhurst 2020-11-11 17:51:44 +01:00
parent 4e0577e74f
commit 720fea4bcc
19 changed files with 556 additions and 301 deletions

View File

@ -1,34 +1,65 @@
package eventstore package eventstore
func NewAggregate(id string) *Aggregate { func NewAggregate(
id string,
typ AggregateType,
resourceOwner string,
version Version,
previousSequence uint64,
) *Aggregate {
return &Aggregate{ return &Aggregate{
ID: id, id: id,
Events: []EventPusher{}, typ: typ,
resourceOwner: resourceOwner,
version: version,
previousSequence: previousSequence,
events: []EventPusher{},
} }
} }
//Aggregate is the basic implementation of aggregater
type Aggregate struct { type Aggregate struct {
PreviousSequence uint64 `json:"-"` id string `json:"-"`
ID string `json:"-"` typ AggregateType `json:"-"`
Events []EventPusher `json:"-"` events []EventPusher `json:"-"`
resourceOwner string `json:"-"`
version Version `json:"-"`
previousSequence uint64 `json:"-"`
} }
//AppendEvents adds all the events to the aggregate. //PushEvents adds all the events to the aggregate.
// The function doesn't compute the new state of the aggregate // The added events will be pushed to eventstore
func (a *Aggregate) AppendEvents(events ...EventPusher) *Aggregate { func (a *Aggregate) PushEvents(events ...EventPusher) *Aggregate {
a.Events = append(a.Events, events...) a.events = append(a.events, events...)
return a return a
} }
//Reduce must be the last step in the reduce function of the extension //ID implements aggregater
func (a *Aggregate) Reduce() error { func (a *Aggregate) ID() string {
if len(a.Events) == 0 { return a.id
return nil }
}
//Type implements aggregater
a.PreviousSequence = a.Events[len(a.Events)-1].Sequence() func (a *Aggregate) Type() AggregateType {
// all events processed and not needed anymore return a.typ
a.Events = nil }
a.Events = []Event{}
return nil //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
}
//PreviousSequence implements aggregater
func (a *Aggregate) PreviousSequence() uint64 {
return a.previousSequence
} }

View File

@ -58,7 +58,6 @@ func newTestEvent(description string, data func() interface{}, checkPrevious boo
shouldCheckPrevious: checkPrevious, shouldCheckPrevious: checkPrevious,
BaseEvent: *NewBaseEventForPush( BaseEvent: *NewBaseEventForPush(
authz.NewMockContext("resourceOwner", "editorUser"), authz.NewMockContext("resourceOwner", "editorUser"),
"editorService",
"test.event", "test.event",
), ),
} }

View File

@ -23,43 +23,20 @@ type UserAggregate struct {
FirstName string FirstName string
} }
func (a *UserAggregate) ID() string {
return a.Aggregate.ID
}
func (a *UserAggregate) Type() eventstore.AggregateType {
return "test.user"
}
func (a *UserAggregate) Events() []eventstore.EventPusher {
events := make([]eventstore.EventPusher, len(a.Aggregate.Events))
for i, event := range a.Aggregate.Events {
events[i] = event
}
return events
}
func (a *UserAggregate) ResourceOwner() string {
return "caos"
}
func (a *UserAggregate) Version() eventstore.Version {
return "v1"
}
func (a *UserAggregate) PreviousSequence() uint64 {
return a.Aggregate.PreviousSequence
}
func NewUserAggregate(id string) *UserAggregate { func NewUserAggregate(id string) *UserAggregate {
return &UserAggregate{ return &UserAggregate{
Aggregate: *eventstore.NewAggregate(id), Aggregate: *eventstore.NewAggregate(
id,
"test.user",
"caos",
"v1",
0,
),
} }
} }
func (rm *UserAggregate) AppendEvents(events ...eventstore.EventReader) *UserAggregate {
rm.Aggregate.AppendEvents(events...)
return rm
}
func (rm *UserAggregate) Reduce() error { func (rm *UserAggregate) Reduce() error {
for _, event := range rm.Aggregate.Events { for _, event := range rm.Aggregate.Events() {
switch e := event.(type) { switch e := event.(type) {
case *UserAddedEvent: case *UserAddedEvent:
rm.FirstName = e.FirstName rm.FirstName = e.FirstName
@ -67,7 +44,7 @@ func (rm *UserAggregate) Reduce() error {
rm.FirstName = e.FirstName rm.FirstName = e.FirstName
} }
} }
return rm.Aggregate.Reduce() return nil
} }
// ------------------------------------------------------------ // ------------------------------------------------------------
@ -228,12 +205,13 @@ func (e *UserDeletedEvent) Data() interface{} {
type UsersReadModel struct { type UsersReadModel struct {
eventstore.ReadModel eventstore.ReadModel
Users []*UserReadModel Users []*UserReadModel
} }
func NewUsersReadModel() *UsersReadModel { func NewUsersReadModel() *UsersReadModel {
return &UsersReadModel{ return &UsersReadModel{
ReadModel: *eventstore.NewReadModel(""), ReadModel: *eventstore.NewReadModel(),
Users: []*UserReadModel{}, Users: []*UserReadModel{},
} }
} }
@ -284,7 +262,7 @@ func (rm *UsersReadModel) Reduce() error {
func (rm *UsersReadModel) userByID(id string) (idx int, user *UserReadModel) { func (rm *UsersReadModel) userByID(id string) (idx int, user *UserReadModel) {
for idx, user = range rm.Users { for idx, user = range rm.Users {
if user.ReadModel.ID == id { if user.ID == id {
return idx, user return idx, user
} }
} }
@ -298,6 +276,8 @@ func (rm *UsersReadModel) userByID(id string) (idx int, user *UserReadModel) {
type UserReadModel struct { type UserReadModel struct {
eventstore.ReadModel eventstore.ReadModel
ID string
FirstName string FirstName string
pwCheckCount int pwCheckCount int
lastPasswordCheck time.Time lastPasswordCheck time.Time
@ -305,7 +285,8 @@ type UserReadModel struct {
func NewUserReadModel(id string) *UserReadModel { func NewUserReadModel(id string) *UserReadModel {
return &UserReadModel{ return &UserReadModel{
ReadModel: *eventstore.NewReadModel(id), ReadModel: *eventstore.NewReadModel(),
ID: id,
} }
} }
@ -342,9 +323,9 @@ func TestUserReadModel(t *testing.T) {
RegisterFilterEventMapper(UserDeletedMapper()) RegisterFilterEventMapper(UserDeletedMapper())
events, err := es.PushAggregates(context.Background(), events, err := es.PushAggregates(context.Background(),
NewUserAggregate("1").AppendEvents(NewUserAddedEvent("hodor")), NewUserAggregate("1").PushEvents(NewUserAddedEvent("hodor")),
NewUserAggregate("2").AppendEvents(NewUserAddedEvent("hodor"), NewUserPasswordCheckedEvent(), NewUserPasswordCheckedEvent(), NewUserFirstNameChangedEvent("ueli")), NewUserAggregate("2").PushEvents(NewUserAddedEvent("hodor"), NewUserPasswordCheckedEvent(), NewUserPasswordCheckedEvent(), NewUserFirstNameChangedEvent("ueli")),
NewUserAggregate("2").AppendEvents(NewUserDeletedEvent()), NewUserAggregate("2").PushEvents(NewUserDeletedEvent()),
) )
if err != nil { if err != nil {
t.Errorf("unexpected error on push aggregates: %v", err) t.Errorf("unexpected error on push aggregates: %v", err)

View File

@ -2,21 +2,21 @@ package eventstore
import "time" import "time"
func NewReadModel( /*id string*/ ) *ReadModel { func NewReadModel() *ReadModel {
return &ReadModel{ return &ReadModel{
// ID: id,
Events: []EventReader{}, Events: []EventReader{},
} }
} }
//ReadModel 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 // it might be saved in a database or in memory
type ReadModel struct { type ReadModel struct {
ProcessedSequence uint64 `json:"-"` AggregateID string `json:"-"`
// ID string `json:"-"` ProcessedSequence uint64 `json:"-"`
CreationDate time.Time `json:"-"` CreationDate time.Time `json:"-"`
ChangeDate time.Time `json:"-"` ChangeDate time.Time `json:"-"`
Events []EventReader `json:"-"` Events []EventReader `json:"-"`
} }
//AppendEvents adds all the events to the read model. //AppendEvents adds all the events to the read model.
@ -26,12 +26,17 @@ func (rm *ReadModel) AppendEvents(events ...EventReader) *ReadModel {
return rm return rm
} }
//Reduce must be the last step in the reduce function of the extension //Reduce is the basic implementaion of reducer
// If this function is extended the extending function should be the last step
func (rm *ReadModel) Reduce() error { func (rm *ReadModel) Reduce() error {
if len(rm.Events) == 0 { if len(rm.Events) == 0 {
return nil return nil
} }
if rm.AggregateID == "" {
rm.AggregateID = rm.Events[0].AggregateID()
}
if rm.CreationDate.IsZero() { if rm.CreationDate.IsZero() {
rm.CreationDate = rm.Events[0].CreationDate() rm.CreationDate = rm.Events[0].CreationDate()
} }

View File

@ -0,0 +1,114 @@
package iam
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/member"
"github.com/caos/zitadel/internal/v2/repository/members"
)
const (
iamEventTypePrefix = eventstore.EventType("iam.")
)
var (
MemberAddedEventType = iamEventTypePrefix + member.AddedEventType
MemberChangedEventType = iamEventTypePrefix + member.ChangedEventType
MemberRemovedEventType = iamEventTypePrefix + member.RemovedEventType
)
type MembersReadModel struct {
members.ReadModel
}
func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
for _, event := range events {
switch e := event.(type) {
case *MemberAddedEvent:
rm.ReadModel.AppendEvents(&e.AddedEvent)
case *MemberChangedEvent:
rm.ReadModel.AppendEvents(&e.ChangedEvent)
case *MemberRemovedEvent:
rm.ReadModel.AppendEvents(&e.RemovedEvent)
}
}
return nil
}
type MemberReadModel member.ReadModel
func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
for _, event := range events {
switch e := event.(type) {
case *MemberAddedEvent:
rm.ReadModel.AppendEvents(&e.AddedEvent)
case *MemberChangedEvent:
rm.ReadModel.AppendEvents(&e.ChangedEvent)
}
}
return nil
}
type MemberAddedEvent struct {
member.AddedEvent
}
type MemberChangedEvent struct {
member.ChangedEvent
}
type MemberRemovedEvent struct {
member.RemovedEvent
}
func NewMemberAddedEvent(
ctx context.Context,
userID string,
roles ...string,
) *MemberAddedEvent {
return &MemberAddedEvent{
AddedEvent: *member.NewMemberAddedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberAddedEventType,
),
userID,
roles...,
),
}
}
func NewMemberChangedEvent(
ctx context.Context,
userID string,
roles ...string,
) *MemberChangedEvent {
return &MemberChangedEvent{
ChangedEvent: *member.NewMemberChangedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberChangedEventType,
),
userID,
roles...,
),
}
}
func NewMemberRemovedEvent(
ctx context.Context,
userID string,
) *MemberRemovedEvent {
return &MemberRemovedEvent{
RemovedEvent: *member.NewMemberRemovedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberRemovedEventType,
),
userID,
),
}
}

View File

@ -3,6 +3,7 @@ package iam
import ( import (
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/member" "github.com/caos/zitadel/internal/v2/repository/member"
"github.com/caos/zitadel/internal/v2/repository/policy"
) )
type ReadModel struct { type ReadModel struct {
@ -11,20 +12,38 @@ type ReadModel struct {
SetUpStarted Step SetUpStarted Step
SetUpDone Step SetUpDone Step
Members member.MembersReadModel Members MembersReadModel
GlobalOrgID string GlobalOrgID string
ProjectID string ProjectID string
DefaultLoginPolicy policy.LoginPolicyReadModel
DefaultLabelPolicy policy.LabelPolicyReadModel
DefaultOrgIAMPolicy policy.OrgIAMPolicyReadModel
DefaultPasswordComplexityPolicy policy.PasswordComplexityPolicyReadModel
DefaultPasswordAgePolicy policy.PasswordAgePolicyReadModel
DefaultPasswordLockoutPolicy policy.PasswordLockoutPolicyReadModel
} }
func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
rm.ReadModel.AppendEvents(events...) rm.ReadModel.AppendEvents(events...)
for _, event := range events { for _, event := range events {
switch event.(type) { switch event.(type) {
case *member.MemberAddedEvent, *member.MemberChangedEvent, *member.MemberRemovedEvent: case *member.AddedEvent, *member.ChangedEvent, *member.RemovedEvent:
err = rm.Members.AppendEvents(events...) rm.Members.AppendEvents(event)
case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent:
rm.DefaultLabelPolicy.AppendEvents(event)
case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent:
rm.DefaultLoginPolicy.AppendEvents(event)
case *policy.OrgIAMPolicyAddedEvent:
rm.DefaultOrgIAMPolicy.AppendEvents(event)
case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent:
rm.DefaultPasswordComplexityPolicy.AppendEvents(event)
case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent:
rm.DefaultPasswordAgePolicy.AppendEvents(event)
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent:
rm.DefaultPasswordLockoutPolicy.AppendEvents(event)
} }
} }
return err return err
} }
@ -44,9 +63,21 @@ func (rm *ReadModel) Reduce() (err error) {
} }
} }
} }
err = rm.Members.Reduce() for _, reduce := range []func() error{
if err != nil { rm.Members.Reduce,
return err rm.Members.Reduce,
rm.DefaultLoginPolicy.Reduce,
rm.DefaultLabelPolicy.Reduce,
rm.DefaultOrgIAMPolicy.Reduce,
rm.DefaultPasswordComplexityPolicy.Reduce,
rm.DefaultPasswordAgePolicy.Reduce,
rm.DefaultPasswordLockoutPolicy.Reduce,
rm.ReadModel.Reduce,
} {
if err = reduce(); err != nil {
return err
}
} }
return rm.ReadModel.Reduce()
return nil
} }

View File

@ -1,39 +1,37 @@
package member package member
import ( import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
) )
type MemberAddedEvent struct { const (
AddedEventType = "member.added"
)
type AddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
UserID string `json:"userId"` UserID string `json:"userId"`
} }
func (e *MemberAddedEvent) CheckPrevious() bool { func (e *AddedEvent) CheckPrevious() bool {
return true return true
} }
func (e *MemberAddedEvent) Data() interface{} { func (e *AddedEvent) Data() interface{} {
return e return e
} }
func NewMemberAddedEvent( func NewMemberAddedEvent(
ctx context.Context, base *eventstore.BaseEvent,
eventType eventstore.EventType,
userID string, userID string,
roles ...string, roles ...string,
) *MemberAddedEvent { ) *AddedEvent {
return &MemberAddedEvent{ return &AddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *base,
ctx, Roles: roles,
eventType, UserID: userID,
),
Roles: roles,
UserID: userID,
} }
} }

View File

@ -1,39 +1,37 @@
package member package member
import ( import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
) )
type MemberChangedEvent struct { const (
ChangedEventType = "member.changed"
)
type ChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
UserID string `json:"userId"` UserID string `json:"userId"`
} }
func (e *MemberChangedEvent) CheckPrevious() bool { func (e *ChangedEvent) CheckPrevious() bool {
return true return true
} }
func (e *MemberChangedEvent) Data() interface{} { func (e *ChangedEvent) Data() interface{} {
return e return e
} }
func NewMemberChangedEvent( func NewMemberChangedEvent(
ctx context.Context, base *eventstore.BaseEvent,
eventType eventstore.EventType,
userID string, userID string,
roles ...string, roles ...string,
) *MemberChangedEvent { ) *ChangedEvent {
return &MemberChangedEvent{ return &ChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *base,
ctx, Roles: roles,
eventType, UserID: userID,
),
Roles: roles,
UserID: userID,
} }
} }

View File

@ -1,36 +1,34 @@
package member package member
import ( import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
) )
type MemberRemovedEvent struct { const (
RemovedEventType = "member.removed"
)
type RemovedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
UserID string `json:"userId"` UserID string `json:"userId"`
} }
func (e *MemberRemovedEvent) CheckPrevious() bool { func (e *RemovedEvent) CheckPrevious() bool {
return true return true
} }
func (e *MemberRemovedEvent) Data() interface{} { func (e *RemovedEvent) Data() interface{} {
return e return e
} }
func NewMemberRemovedEvent( func NewMemberRemovedEvent(
ctx context.Context, base *eventstore.BaseEvent,
eventType eventstore.EventType,
userID string, userID string,
) *MemberRemovedEvent { ) *RemovedEvent {
return &MemberRemovedEvent{ return &RemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *base,
ctx, UserID: userID,
eventType,
),
UserID: userID,
} }
} }

View File

@ -0,0 +1,30 @@
package member
import "github.com/caos/zitadel/internal/eventstore/v2"
type ReadModel struct {
eventstore.ReadModel
UserID string
Roles []string
}
func NewMemberReadModel(userID string) *ReadModel {
return &ReadModel{
ReadModel: *eventstore.NewReadModel(),
}
}
func (rm *ReadModel) Reduce() error {
for _, event := range rm.Events {
switch e := event.(type) {
case *AddedEvent:
rm.UserID = e.UserID
rm.Roles = e.Roles
case *ChangedEvent:
rm.UserID = e.UserID
rm.Roles = e.Roles
}
}
return rm.ReadModel.Reduce()
}

View File

@ -1,84 +0,0 @@
package member
import "github.com/caos/zitadel/internal/eventstore/v2"
type MemberReadModel struct {
eventstore.ReadModel
UserID string
Roles []string
}
func NewMemberReadModel(userID string) *MemberReadModel {
return &MemberReadModel{
ReadModel: *eventstore.NewReadModel(),
}
}
func (rm *MemberReadModel) Reduce() error {
for _, event := range rm.Events {
switch e := event.(type) {
case *MemberAddedEvent:
rm.UserID = e.UserID
rm.Roles = e.Roles
case *MemberChangedEvent:
rm.UserID = e.UserID
rm.Roles = e.Roles
}
}
return rm.ReadModel.Reduce()
}
type MembersReadModel struct {
eventstore.ReadModel
Members []*MemberReadModel
}
func NewMembersReadModel() *MembersReadModel {
return &MembersReadModel{
ReadModel: *eventstore.NewReadModel(),
Members: []*MemberReadModel{},
}
}
func (rm *MembersReadModel) MemberByUserID(id string) (idx int, member *MemberReadModel) {
for idx, member = range rm.Members {
if member.UserID == id {
return idx, member
}
}
return -1, nil
}
func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
for _, event := range events {
switch e := event.(type) {
case *MemberAddedEvent:
member := NewMemberReadModel(e.UserID)
rm.Members = append(rm.Members, member)
member.AppendEvents(e)
case *MemberChangedEvent:
_, member := rm.MemberByUserID(e.UserID)
member.AppendEvents(e)
case *MemberRemovedEvent:
idx, _ := rm.MemberByUserID(e.UserID)
if idx < 0 {
return nil
}
copy(rm.Members[idx:], rm.Members[idx+1:])
rm.Members[len(rm.Members)-1] = nil
rm.Members = rm.Members[:len(rm.Members)-1]
}
}
return err
}
func (rm *MembersReadModel) Reduce() (err error) {
for _, member := range rm.Members {
err = member.Reduce()
if err != nil {
return err
}
}
return rm.ReadModel.Reduce()
}

View File

@ -0,0 +1,61 @@
package members
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/member"
)
type ReadModel struct {
eventstore.ReadModel
Members []*member.ReadModel
}
func NewMembersReadModel() *ReadModel {
return &ReadModel{
ReadModel: *eventstore.NewReadModel(),
Members: []*member.ReadModel{},
}
}
func (rm *ReadModel) MemberByUserID(id string) (idx int, member *member.ReadModel) {
for idx, member = range rm.Members {
if member.UserID == id {
return idx, member
}
}
return -1, nil
}
func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
for _, event := range events {
switch e := event.(type) {
case *member.MemberAddedEvent:
member := member.NewMemberReadModel(e.UserID)
rm.Members = append(rm.Members, member)
member.AppendEvents(e)
case *member.MemberChangedEvent:
_, member := rm.MemberByUserID(e.UserID)
member.AppendEvents(e)
case *member.MemberRemovedEvent:
idx, _ := rm.MemberByUserID(e.UserID)
if idx < 0 {
return nil
}
copy(rm.Members[idx:], rm.Members[idx+1:])
rm.Members[len(rm.Members)-1] = nil
rm.Members = rm.Members[:len(rm.Members)-1]
}
}
return err
}
func (rm *ReadModel) Reduce() (err error) {
for _, member := range rm.Members {
err = member.Reduce()
if err != nil {
return err
}
}
return rm.ReadModel.Reduce()
}

View File

@ -19,6 +19,13 @@ type LabelPolicyAggregate struct {
SecondaryColor string SecondaryColor string
} }
type LabelPolicyReadModel struct {
eventstore.ReadModel
PrimaryColor string
SecondaryColor string
}
type LabelPolicyAddedEvent struct { type LabelPolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
@ -53,8 +60,8 @@ func NewLabelPolicyAddedEvent(
type LabelPolicyChangedEvent struct { type LabelPolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
current *LabelPolicyAggregate PrimaryColor string `json:"primaryColor,omitempty"`
changed *LabelPolicyAggregate SecondaryColor string `json:"secondaryColor,omitempty"`
} }
func (e *LabelPolicyChangedEvent) CheckPrevious() bool { func (e *LabelPolicyChangedEvent) CheckPrevious() bool {
@ -62,15 +69,7 @@ func (e *LabelPolicyChangedEvent) CheckPrevious() bool {
} }
func (e *LabelPolicyChangedEvent) Data() interface{} { func (e *LabelPolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{} return e
if e.current.PrimaryColor != e.changed.PrimaryColor {
changes["primaryColor"] = e.changed.PrimaryColor
}
if e.current.SecondaryColor != e.changed.SecondaryColor {
changes["secondaryColor"] = e.changed.SecondaryColor
}
return changes
} }
func NewLabelPolicyChangedEvent( func NewLabelPolicyChangedEvent(
@ -79,14 +78,20 @@ func NewLabelPolicyChangedEvent(
changed *LabelPolicyAggregate, changed *LabelPolicyAggregate,
) *LabelPolicyChangedEvent { ) *LabelPolicyChangedEvent {
return &LabelPolicyChangedEvent{ e := &LabelPolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LabelPolicyChangedEventType, LabelPolicyChangedEventType,
), ),
current: current,
changed: changed,
} }
if current.PrimaryColor != changed.PrimaryColor {
e.PrimaryColor = changed.PrimaryColor
}
if current.SecondaryColor != changed.SecondaryColor {
e.SecondaryColor = changed.SecondaryColor
}
return e
} }
type LabelPolicyRemovedEvent struct { type LabelPolicyRemovedEvent struct {
@ -101,14 +106,11 @@ func (e *LabelPolicyRemovedEvent) Data() interface{} {
return nil return nil
} }
func NewLabelPolicyRemovedEvent( func NewLabelPolicyRemovedEvent(ctx context.Context) *LabelPolicyRemovedEvent {
ctx context.Context,
) *LabelPolicyRemovedEvent {
return &LabelPolicyRemovedEvent{ return &LabelPolicyRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LabelPolicyChangedEventType, LabelPolicyRemovedEventType,
), ),
} }
} }

View File

@ -20,6 +20,14 @@ type LoginPolicyAggregate struct {
AllowExternalIDP bool AllowExternalIDP bool
} }
type LoginPolicyReadModel struct {
eventstore.ReadModel
AllowUserNamePassword bool
AllowRegister bool
AllowExternalIDP bool
}
type LoginPolicyAddedEvent struct { type LoginPolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
@ -58,8 +66,9 @@ func NewLoginPolicyAddedEvent(
type LoginPolicyChangedEvent struct { type LoginPolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
current *LoginPolicyAggregate AllowUserNamePassword bool `json:"allowUsernamePassword,omitempty"`
changed *LoginPolicyAggregate AllowRegister bool `json:"allowRegister"`
AllowExternalIDP bool `json:"allowExternalIdp"`
} }
func (e *LoginPolicyChangedEvent) CheckPrevious() bool { func (e *LoginPolicyChangedEvent) CheckPrevious() bool {
@ -67,18 +76,7 @@ func (e *LoginPolicyChangedEvent) CheckPrevious() bool {
} }
func (e *LoginPolicyChangedEvent) Data() interface{} { func (e *LoginPolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{} return e
if e.current.AllowExternalIDP != e.changed.AllowExternalIDP {
changes["allowUsernamePassword"] = e.changed.AllowExternalIDP
}
if e.current.AllowRegister != e.changed.AllowRegister {
changes["allowRegister"] = e.changed.AllowExternalIDP
}
if e.current.AllowExternalIDP != e.changed.AllowExternalIDP {
changes["allowExternalIdp"] = e.changed.AllowExternalIDP
}
return changes
} }
func NewLoginPolicyChangedEvent( func NewLoginPolicyChangedEvent(
@ -87,12 +85,24 @@ func NewLoginPolicyChangedEvent(
changed *LoginPolicyAggregate, changed *LoginPolicyAggregate,
) *LoginPolicyChangedEvent { ) *LoginPolicyChangedEvent {
return &LoginPolicyChangedEvent{ e := &LoginPolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LoginPolicyChangedEventType, LoginPolicyChangedEventType,
), ),
} }
if current.AllowUserNamePassword != changed.AllowUserNamePassword {
e.AllowUserNamePassword = changed.AllowUserNamePassword
}
if current.AllowRegister != changed.AllowRegister {
e.AllowRegister = changed.AllowRegister
}
if current.AllowExternalIDP != changed.AllowExternalIDP {
e.AllowExternalIDP = changed.AllowExternalIDP
}
return e
} }
type LoginPolicyRemovedEvent struct { type LoginPolicyRemovedEvent struct {

View File

@ -10,6 +10,18 @@ const (
OrgIAMPolicyAddedEventType = "policy.org.iam.added" OrgIAMPolicyAddedEventType = "policy.org.iam.added"
) )
type OrgIAMPolicyAggregate struct {
eventstore.Aggregate
UserLoginMustBeDomain bool
}
type OrgIAMPolicyReadModel struct {
eventstore.ReadModel
UserLoginMustBeDomain bool
}
type OrgIAMPolicyAddedEvent struct { type OrgIAMPolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`

View File

@ -19,6 +19,13 @@ type PasswordAgePolicyAggregate struct {
MaxAgeDays int MaxAgeDays int
} }
type PasswordAgePolicyReadModel struct {
eventstore.ReadModel
ExpireWarnDays int
MaxAgeDays int
}
type PasswordAgePolicyAddedEvent struct { type PasswordAgePolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
@ -53,8 +60,8 @@ func NewPasswordAgePolicyAddedEvent(
type PasswordAgePolicyChangedEvent struct { type PasswordAgePolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
current *PasswordAgePolicyAggregate ExpireWarnDays int `json:"expireWarnDays,omitempty"`
changed *PasswordAgePolicyAggregate MaxAgeDays int `json:"maxAgeDays,omitempty"`
} }
func (e *PasswordAgePolicyChangedEvent) CheckPrevious() bool { func (e *PasswordAgePolicyChangedEvent) CheckPrevious() bool {
@ -62,16 +69,7 @@ func (e *PasswordAgePolicyChangedEvent) CheckPrevious() bool {
} }
func (e *PasswordAgePolicyChangedEvent) Data() interface{} { func (e *PasswordAgePolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{} return e
if e.current.ExpireWarnDays != e.changed.ExpireWarnDays {
changes["expireWarnDays"] = e.changed.ExpireWarnDays
}
if e.current.MaxAgeDays != e.changed.MaxAgeDays {
changes["maxAgeDays"] = e.changed.ExpireWarnDays
}
return changes
} }
func NewPasswordAgePolicyChangedEvent( func NewPasswordAgePolicyChangedEvent(
@ -80,14 +78,21 @@ func NewPasswordAgePolicyChangedEvent(
changed *PasswordAgePolicyAggregate, changed *PasswordAgePolicyAggregate,
) *PasswordAgePolicyChangedEvent { ) *PasswordAgePolicyChangedEvent {
return &PasswordAgePolicyChangedEvent{ e := &PasswordAgePolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
PasswordAgePolicyChangedEventType, PasswordAgePolicyChangedEventType,
), ),
current: current,
changed: changed,
} }
if current.ExpireWarnDays != changed.ExpireWarnDays {
e.ExpireWarnDays = changed.ExpireWarnDays
}
if current.MaxAgeDays != changed.MaxAgeDays {
e.MaxAgeDays = changed.ExpireWarnDays
}
return e
} }
type PasswordAgePolicyRemovedEvent struct { type PasswordAgePolicyRemovedEvent struct {
@ -111,7 +116,7 @@ func NewPasswordAgePolicyRemovedEvent(
return &PasswordAgePolicyChangedEvent{ return &PasswordAgePolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
PasswordAgePolicyChangedEventType, PasswordAgePolicyRemovedEventType,
), ),
} }
} }

View File

@ -13,6 +13,18 @@ const (
) )
type PasswordComplexityPolicyAggregate struct { type PasswordComplexityPolicyAggregate struct {
eventstore.Aggregate
MinLength int
HasLowercase bool
HasUpperCase bool
HasNumber bool
HasSymbol bool
}
type PasswordComplexityPolicyReadModel struct {
eventstore.ReadModel
MinLength int MinLength int
HasLowercase bool HasLowercase bool
HasUpperCase bool HasUpperCase bool
@ -63,8 +75,11 @@ func NewPasswordComplexityPolicyAddedEvent(
type PasswordComplexityPolicyChangedEvent struct { type PasswordComplexityPolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
current *PasswordComplexityPolicyAggregate MinLength int `json:"minLength"`
changed *PasswordComplexityPolicyAggregate HasLowercase bool `json:"hasLowercase"`
HasUpperCase bool `json:"hasUppercase"`
HasNumber bool `json:"hasNumber"`
HasSymbol bool `json:"hasSymbol"`
} }
func (e *PasswordComplexityPolicyChangedEvent) CheckPrevious() bool { func (e *PasswordComplexityPolicyChangedEvent) CheckPrevious() bool {
@ -72,25 +87,7 @@ func (e *PasswordComplexityPolicyChangedEvent) CheckPrevious() bool {
} }
func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} { func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{} return e
if e.current.MinLength != e.changed.MinLength {
changes["minLength"] = e.changed.MinLength
}
if e.current.HasLowercase != e.changed.HasLowercase {
changes["hasLowercase"] = e.changed.HasLowercase
}
if e.current.HasUpperCase != e.changed.HasUpperCase {
changes["hasUppercase"] = e.changed.HasUpperCase
}
if e.current.HasNumber != e.changed.HasNumber {
changes["hasNumber"] = e.changed.HasNumber
}
if e.current.HasSymbol != e.changed.HasSymbol {
changes["hasSymbol"] = e.changed.HasSymbol
}
return changes
} }
func NewPasswordComplexityPolicyChangedEvent( func NewPasswordComplexityPolicyChangedEvent(
@ -99,14 +96,30 @@ func NewPasswordComplexityPolicyChangedEvent(
changed *PasswordComplexityPolicyAggregate, changed *PasswordComplexityPolicyAggregate,
) *PasswordComplexityPolicyChangedEvent { ) *PasswordComplexityPolicyChangedEvent {
return &PasswordComplexityPolicyChangedEvent{ e := &PasswordComplexityPolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyChangedEventType,
), ),
current: current,
changed: changed,
} }
if current.MinLength != changed.MinLength {
e.MinLength = changed.MinLength
}
if current.HasLowercase != changed.HasLowercase {
e.HasLowercase = changed.HasLowercase
}
if current.HasUpperCase != changed.HasUpperCase {
e.HasUpperCase = changed.HasUpperCase
}
if current.HasNumber != changed.HasNumber {
e.HasNumber = changed.HasNumber
}
if current.HasSymbol != changed.HasSymbol {
e.HasSymbol = changed.HasSymbol
}
return e
} }
type PasswordComplexityPolicyRemovedEvent struct { type PasswordComplexityPolicyRemovedEvent struct {
@ -128,7 +141,7 @@ func NewPasswordComplexityPolicyRemovedEvent(
return &PasswordComplexityPolicyRemovedEvent{ return &PasswordComplexityPolicyRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyRemovedEventType,
), ),
} }
} }

View File

@ -7,16 +7,25 @@ import (
) )
const ( const (
PasswordLockoutPolicyAddedEventType = "policy.password.lockout.added" PasswordLockoutPolicyAddedEventType = "policy.password.lockout.added"
PasswordLockoutPolicyChangedEventType = "policy.password.lockout.changed"
PasswordLockoutPolicyRemovedEventType = "policy.password.lockout.removed"
) )
type PasswordLockoutAggregate struct { type PasswordLockoutPolicyAggregate struct {
eventstore.Aggregate eventstore.Aggregate
MaxAttempts int MaxAttempts int
ShowLockOutFailures bool ShowLockOutFailures bool
} }
type PasswordLockoutPolicyReadModel struct {
eventstore.ReadModel
MaxAttempts int
ShowLockOutFailures bool
}
type PasswordLockoutPolicyAddedEvent struct { type PasswordLockoutPolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
@ -41,7 +50,7 @@ func NewPasswordLockoutPolicyAddedEvent(
return &PasswordLockoutPolicyAddedEvent{ return &PasswordLockoutPolicyAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LabelPolicyAddedEventType, PasswordLockoutPolicyAddedEventType,
), ),
MaxAttempts: maxAttempts, MaxAttempts: maxAttempts,
ShowLockOutFailures: showLockOutFailures, ShowLockOutFailures: showLockOutFailures,
@ -51,8 +60,8 @@ func NewPasswordLockoutPolicyAddedEvent(
type PasswordLockoutPolicyChangedEvent struct { type PasswordLockoutPolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
current *PasswordLockoutAggregate MaxAttempts int `json:"maxAttempts,omitempty"`
changed *PasswordLockoutAggregate ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"`
} }
func (e *PasswordLockoutPolicyChangedEvent) CheckPrevious() bool { func (e *PasswordLockoutPolicyChangedEvent) CheckPrevious() bool {
@ -60,32 +69,30 @@ func (e *PasswordLockoutPolicyChangedEvent) CheckPrevious() bool {
} }
func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} { func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{} return e
if e.current.MaxAttempts != e.changed.MaxAttempts {
changes["maxAttempts"] = e.changed.MaxAttempts
}
if e.current.ShowLockOutFailures != e.changed.ShowLockOutFailures {
changes["showLockOutFailures"] = e.changed.ShowLockOutFailures
}
return changes
} }
func NewPasswordLockoutPolicyChangedEvent( func NewPasswordLockoutPolicyChangedEvent(
ctx context.Context, ctx context.Context,
current, current,
changed *PasswordLockoutAggregate, changed *PasswordLockoutPolicyAggregate,
) *PasswordLockoutPolicyChangedEvent { ) *PasswordLockoutPolicyChangedEvent {
return &PasswordLockoutPolicyChangedEvent{ e := &PasswordLockoutPolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LabelPolicyAddedEventType, PasswordLockoutPolicyChangedEventType,
), ),
current: current,
changed: changed,
} }
if current.MaxAttempts != changed.MaxAttempts {
e.MaxAttempts = changed.MaxAttempts
}
if current.ShowLockOutFailures != changed.ShowLockOutFailures {
e.ShowLockOutFailures = changed.ShowLockOutFailures
}
return e
} }
type PasswordLockoutPolicyRemovedEvent struct { type PasswordLockoutPolicyRemovedEvent struct {
@ -107,7 +114,7 @@ func NewPasswordLockoutPolicyRemovedEvent(
return &PasswordLockoutPolicyRemovedEvent{ return &PasswordLockoutPolicyRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
LabelPolicyAddedEventType, PasswordLockoutPolicyRemovedEventType,
), ),
} }
} }

44
internal/v2/view/iam.go Normal file
View File

@ -0,0 +1,44 @@
package view
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
type IAM struct {
eventstore.ReadModel
SetUpStarted iam.Step
SetUpDone iam.Step
GlobalOrgID string
ProjectID string
// TODO: how to implement queries?
}
func (rm *IAM) AppendEvents(events ...eventstore.EventReader) (err error) {
rm.ReadModel.AppendEvents(events...)
return err
}
//Reduce implements eventstore.ReadModel
//
func (rm *IAM) Reduce() (err error) {
for _, event := range rm.Events {
switch e := event.(type) {
case *iam.ProjectSetEvent:
rm.ProjectID = e.ProjectID
case *iam.GlobalOrgSetEvent:
rm.GlobalOrgID = e.OrgID
case *iam.SetupStepEvent:
if e.Done {
rm.SetUpDone = e.Step
} else {
rm.SetUpStarted = e.Step
}
}
}
return rm.ReadModel.Reduce()
//execute all queries
}