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

View File

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

View File

@ -2,21 +2,21 @@ package eventstore
import "time"
func NewReadModel( /*id string*/ ) *ReadModel {
func NewReadModel() *ReadModel {
return &ReadModel{
// ID: id,
Events: []EventReader{},
}
}
//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 {
ProcessedSequence uint64 `json:"-"`
// ID string `json:"-"`
CreationDate time.Time `json:"-"`
ChangeDate time.Time `json:"-"`
Events []EventReader `json:"-"`
AggregateID string `json:"-"`
ProcessedSequence uint64 `json:"-"`
CreationDate time.Time `json:"-"`
ChangeDate time.Time `json:"-"`
Events []EventReader `json:"-"`
}
//AppendEvents adds all the events to the read model.
@ -26,12 +26,17 @@ func (rm *ReadModel) AppendEvents(events ...EventReader) *ReadModel {
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 {
if len(rm.Events) == 0 {
return nil
}
if rm.AggregateID == "" {
rm.AggregateID = rm.Events[0].AggregateID()
}
if rm.CreationDate.IsZero() {
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 (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/member"
"github.com/caos/zitadel/internal/v2/repository/policy"
)
type ReadModel struct {
@ -11,20 +12,38 @@ type ReadModel struct {
SetUpStarted Step
SetUpDone Step
Members member.MembersReadModel
Members MembersReadModel
GlobalOrgID 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) {
rm.ReadModel.AppendEvents(events...)
for _, event := range events {
switch event.(type) {
case *member.MemberAddedEvent, *member.MemberChangedEvent, *member.MemberRemovedEvent:
err = rm.Members.AppendEvents(events...)
case *member.AddedEvent, *member.ChangedEvent, *member.RemovedEvent:
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
}
@ -44,9 +63,21 @@ func (rm *ReadModel) Reduce() (err error) {
}
}
}
err = rm.Members.Reduce()
if err != nil {
return err
for _, reduce := range []func() error{
rm.Members.Reduce,
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
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
)
type MemberAddedEvent struct {
const (
AddedEventType = "member.added"
)
type AddedEvent struct {
eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"`
UserID string `json:"userId"`
}
func (e *MemberAddedEvent) CheckPrevious() bool {
func (e *AddedEvent) CheckPrevious() bool {
return true
}
func (e *MemberAddedEvent) Data() interface{} {
func (e *AddedEvent) Data() interface{} {
return e
}
func NewMemberAddedEvent(
ctx context.Context,
eventType eventstore.EventType,
base *eventstore.BaseEvent,
userID string,
roles ...string,
) *MemberAddedEvent {
) *AddedEvent {
return &MemberAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
eventType,
),
Roles: roles,
UserID: userID,
return &AddedEvent{
BaseEvent: *base,
Roles: roles,
UserID: userID,
}
}

View File

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

View File

@ -1,36 +1,34 @@
package member
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
)
type MemberRemovedEvent struct {
const (
RemovedEventType = "member.removed"
)
type RemovedEvent struct {
eventstore.BaseEvent `json:"-"`
UserID string `json:"userId"`
}
func (e *MemberRemovedEvent) CheckPrevious() bool {
func (e *RemovedEvent) CheckPrevious() bool {
return true
}
func (e *MemberRemovedEvent) Data() interface{} {
func (e *RemovedEvent) Data() interface{} {
return e
}
func NewMemberRemovedEvent(
ctx context.Context,
eventType eventstore.EventType,
base *eventstore.BaseEvent,
userID string,
) *MemberRemovedEvent {
) *RemovedEvent {
return &MemberRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
eventType,
),
UserID: userID,
return &RemovedEvent{
BaseEvent: *base,
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
}
type LabelPolicyReadModel struct {
eventstore.ReadModel
PrimaryColor string
SecondaryColor string
}
type LabelPolicyAddedEvent struct {
eventstore.BaseEvent `json:"-"`
@ -53,8 +60,8 @@ func NewLabelPolicyAddedEvent(
type LabelPolicyChangedEvent struct {
eventstore.BaseEvent `json:"-"`
current *LabelPolicyAggregate
changed *LabelPolicyAggregate
PrimaryColor string `json:"primaryColor,omitempty"`
SecondaryColor string `json:"secondaryColor,omitempty"`
}
func (e *LabelPolicyChangedEvent) CheckPrevious() bool {
@ -62,15 +69,7 @@ func (e *LabelPolicyChangedEvent) CheckPrevious() bool {
}
func (e *LabelPolicyChangedEvent) Data() interface{} {
changes := map[string]interface{}{}
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
return e
}
func NewLabelPolicyChangedEvent(
@ -79,14 +78,20 @@ func NewLabelPolicyChangedEvent(
changed *LabelPolicyAggregate,
) *LabelPolicyChangedEvent {
return &LabelPolicyChangedEvent{
e := &LabelPolicyChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
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 {
@ -101,14 +106,11 @@ func (e *LabelPolicyRemovedEvent) Data() interface{} {
return nil
}
func NewLabelPolicyRemovedEvent(
ctx context.Context,
) *LabelPolicyRemovedEvent {
func NewLabelPolicyRemovedEvent(ctx context.Context) *LabelPolicyRemovedEvent {
return &LabelPolicyRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
LabelPolicyChangedEventType,
LabelPolicyRemovedEventType,
),
}
}

View File

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

View File

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

View File

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

View File

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

View File

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