idp config

This commit is contained in:
adlerhurst 2020-11-26 13:14:07 +01:00
parent 246d4294cf
commit 1b3f821ad0
25 changed files with 403 additions and 79 deletions

View File

@ -16,8 +16,6 @@ import (
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
iam_business "github.com/caos/zitadel/internal/v2/business/iam" iam_business "github.com/caos/zitadel/internal/v2/business/iam"
"github.com/caos/zitadel/internal/v2/repository/iam" "github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/idp"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
"github.com/caos/zitadel/internal/v2/repository/member" "github.com/caos/zitadel/internal/v2/repository/member"
) )
@ -46,13 +44,13 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
esV2.RegisterFilterEventMapper(iam.MemberAddedEventType, member.AddedEventMapper). esV2.RegisterFilterEventMapper(iam.MemberAddedEventType, member.AddedEventMapper).
RegisterFilterEventMapper(iam.MemberChangedEventType, member.ChangedEventMapper). RegisterFilterEventMapper(iam.MemberChangedEventType, member.ChangedEventMapper).
RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper). RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper).
RegisterFilterEventMapper(iam.IDPConfigAddedEventType, idp.ConfigAddedEventMapper). RegisterFilterEventMapper(iam.IDPConfigAddedEventType, iam.IDPConfigAddedEventMapper).
RegisterFilterEventMapper(iam.IDPConfigChangedEventType, idp.ConfigChangedEventMapper). RegisterFilterEventMapper(iam.IDPConfigChangedEventType, iam.IDPConfigChangedEventMapper).
RegisterFilterEventMapper(iam.IDPConfigDeactivatedEventType, idp.ConfigDeactivatedEventMapper). RegisterFilterEventMapper(iam.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventMapper).
RegisterFilterEventMapper(iam.IDPConfigReactivatedEventType, idp.ConfigReactivatedEventMapper). RegisterFilterEventMapper(iam.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventMapper).
RegisterFilterEventMapper(iam.IDPConfigRemovedEventType, idp.ConfigRemovedEventMapper). RegisterFilterEventMapper(iam.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventMapper).
RegisterFilterEventMapper(iam.IDPOIDCConfigAddedEventType, oidc.ConfigAddedEventMapper). RegisterFilterEventMapper(iam.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventMapper).
RegisterFilterEventMapper(iam.IDPOIDCConfigChangedEventType, oidc.ConfigChangedEventMapper) RegisterFilterEventMapper(iam.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventMapper)
iam, err := es_iam.StartIAM(es_iam.IAMConfig{ iam, err := es_iam.StartIAM(es_iam.IAMConfig{
Eventstore: es, Eventstore: es,
@ -79,6 +77,10 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
if err != nil { if err != nil {
return nil, err return nil, err
} }
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
if err != nil {
return nil, err
}
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, handler.EventstoreRepos{UserEvents: user, OrgEvents: org, IamEvents: iam}, systemDefaults) spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, handler.EventstoreRepos{UserEvents: user, OrgEvents: org, IamEvents: iam}, systemDefaults)
@ -100,7 +102,7 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
SystemDefaults: systemDefaults, SystemDefaults: systemDefaults,
SearchLimit: conf.SearchLimit, SearchLimit: conf.SearchLimit,
Roles: roles, Roles: roles,
IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), IAMV2: iamV2,
}, },
AdministratorRepo: eventstore.AdministratorRepo{ AdministratorRepo: eventstore.AdministratorRepo{
View: view, View: view,

View File

@ -132,6 +132,11 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
return nil, err return nil, err
} }
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
if err != nil {
return nil, err
}
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults) org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
repos := handler.EventstoreRepos{UserEvents: user, ProjectEvents: project, OrgEvents: org, IamEvents: iam} repos := handler.EventstoreRepos{UserEvents: user, ProjectEvents: project, OrgEvents: org, IamEvents: iam}
@ -200,7 +205,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
}, },
eventstore.IAMRepository{ eventstore.IAMRepository{
IAMID: systemDefaults.IamID, IAMID: systemDefaults.IamID,
IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), IAMV2: iamV2,
}, },
}, nil }, nil
} }

View File

@ -100,6 +100,11 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
if err != nil { if err != nil {
return nil, err return nil, err
} }
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
if err != nil {
return nil, err
}
repos := handler.EventstoreRepos{IamEvents: iam} repos := handler.EventstoreRepos{IamEvents: iam}
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, repos, systemDefaults) spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, repos, systemDefaults)
@ -114,7 +119,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
eventstore.IamRepo{ eventstore.IamRepo{
IAMID: systemDefaults.IamID, IAMID: systemDefaults.IamID,
IAMEvents: iam, IAMEvents: iam,
IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), IAMV2: iamV2,
}, },
eventstore.TokenVerifierRepo{ eventstore.TokenVerifierRepo{
//TODO: Add Token Verification Key //TODO: Add Token Verification Key

View File

@ -125,8 +125,9 @@ func (es *Eventstore) mapEvents(events []*repository.Event) (mappedEvents []Even
interceptors, ok := es.eventInterceptors[EventType(event.Type)] interceptors, ok := es.eventInterceptors[EventType(event.Type)]
if !ok || interceptors.eventMapper == nil { if !ok || interceptors.eventMapper == nil {
mappedEvents[i] = BaseEventFromRepo(event) mappedEvents[i] = BaseEventFromRepo(event)
// continue //TODO: return error if unable to map event
return nil, errors.ThrowPreconditionFailed(nil, "V2-usujB", "event mapper not defined") continue
// return nil, errors.ThrowPreconditionFailed(nil, "V2-usujB", "event mapper not defined")
} }
mappedEvents[i], err = interceptors.eventMapper(event) mappedEvents[i], err = interceptors.eventMapper(event)
if err != nil { if err != nil {

View File

@ -96,6 +96,10 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
if err != nil { if err != nil {
return nil, err return nil, err
} }
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
if err != nil {
return nil, err
}
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults) org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
iam, err := es_iam.StartIAM(es_iam.IAMConfig{ iam, err := es_iam.StartIAM(es_iam.IAMConfig{
@ -115,7 +119,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults}, UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults},
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view}, UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
IAMRepository: eventstore.IAMRepository{ IAMRepository: eventstore.IAMRepository{
IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), IAMV2: iamV2,
}, },
}, nil }, nil
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/caos/zitadel/internal/v2/repository/iam" "github.com/caos/zitadel/internal/v2/repository/iam"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/idp" "github.com/caos/zitadel/internal/v2/repository/idp"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
"github.com/caos/zitadel/internal/v2/repository/member" "github.com/caos/zitadel/internal/v2/repository/member"
) )
@ -155,3 +156,29 @@ func readModelToIDPConfigView(rm *iam.IDPConfigReadModel) *model.IDPConfigView {
StylingType: model.IDPStylingType(rm.StylingType), StylingType: model.IDPStylingType(rm.StylingType),
} }
} }
func readModelToIDPConfig(rm *iam.IDPConfigReadModel) *model.IDPConfig {
return &model.IDPConfig{
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
OIDCConfig: readModelToIDPOIDCConfig(rm.OIDCConfig),
Type: model.IdpConfigType(rm.Type),
IDPConfigID: rm.ConfigID,
Name: rm.Name,
State: model.IDPConfigState(rm.State),
StylingType: model.IDPStylingType(rm.StylingType),
}
}
func readModelToIDPOIDCConfig(rm *oidc.ConfigReadModel) *model.OIDCIDPConfig {
return &model.OIDCIDPConfig{
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
ClientID: rm.ClientID,
ClientSecret: rm.ClientSecret,
ClientSecretString: string(rm.ClientSecret.Crypted),
IDPConfigID: rm.IDPConfigID,
IDPDisplayNameMapping: model.OIDCMappingField(rm.IDPDisplayNameMapping),
Issuer: rm.Issuer,
Scopes: rm.Scopes,
UsernameMapping: model.OIDCMappingField(rm.UserNameMapping),
}
}

View File

@ -3,9 +3,13 @@ package iam
import ( import (
"context" "context"
"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"
iam_model "github.com/caos/zitadel/internal/iam/model" iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/repository/iam" "github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/idp"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
) )
func (r *Repository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) { func (r *Repository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) {
@ -30,10 +34,48 @@ func (r *Repository) IDPConfigByID(ctx context.Context, idpConfigID string) (*ia
} }
func (r *Repository) AddIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { func (r *Repository) AddIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
iam, err := r.iamByID(ctx, config.AggregateID) readModel, err := r.iamByID(ctx, config.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return nil, nil idpConfigID, err := r.idGenerator.Next()
if err != nil {
return nil, err
}
aggregate := iam.AggregateFromReadModel(readModel).
PushIDPConfigAdded(ctx, idpConfigID, config.Name, idp.ConfigType(config.Type), idp.StylingType(config.StylingType))
if config.OIDCConfig != nil {
clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.secretCrypto)
if err != nil {
return nil, err
}
aggregate = aggregate.PushIDPOIDCConfigAdded(
ctx,
config.OIDCConfig.ClientID,
idpConfigID,
config.OIDCConfig.Issuer,
clientSecret,
oidc.MappingField(config.OIDCConfig.IDPDisplayNameMapping),
oidc.MappingField(config.OIDCConfig.UsernameMapping),
config.OIDCConfig.Scopes...)
}
events, err := r.eventstore.PushAggregates(ctx, aggregate)
if err != nil {
return nil, err
}
if err = readModel.AppendAndReduce(events...); err != nil {
return nil, err
}
idpConfig := readModel.IDPByID(idpConfigID)
if idpConfig == nil {
return nil, errors.ThrowInternal(nil, "IAM-stZYB", "Errors.Internal")
}
return readModelToIDPConfig(idpConfig), nil
} }

View File

@ -3,24 +3,37 @@ package iam
import ( import (
"context" "context"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
iam_model "github.com/caos/zitadel/internal/iam/model" iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/id"
"github.com/caos/zitadel/internal/tracing" "github.com/caos/zitadel/internal/tracing"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
) )
type Repository struct { type Repository struct {
eventstore *eventstore.Eventstore eventstore *eventstore.Eventstore
idGenerator id.Generator
secretCrypto crypto.Crypto
} }
type Config struct { type Config struct {
Eventstore *eventstore.Eventstore Eventstore *eventstore.Eventstore
SystemDefaults sd.SystemDefaults
} }
func StartRepository(config *Config) *Repository { func StartRepository(config *Config) (repo *Repository, err error) {
return &Repository{ repo = &Repository{
eventstore: config.Eventstore, eventstore: config.Eventstore,
idGenerator: id.SonyFlakeGenerator,
} }
repo.secretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey)
if err != nil {
return nil, err
}
return repo, nil
} }
func (r *Repository) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) { func (r *Repository) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) {

View File

@ -3,7 +3,10 @@ package iam
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/idp"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
) )
const ( const (
@ -87,3 +90,81 @@ func (a *Aggregate) PushStepDone(ctx context.Context, step Step) *Aggregate {
a.Aggregate = *a.PushEvents(NewSetupStepDoneEvent(ctx, step)) a.Aggregate = *a.PushEvents(NewSetupStepDoneEvent(ctx, step))
return a return a
} }
func (a *Aggregate) PushIDPConfigAdded(
ctx context.Context,
configID,
name string,
configType idp.ConfigType,
stylingType idp.StylingType,
) *Aggregate {
a.Aggregate = *a.PushEvents(NewIDPConfigAddedEvent(ctx, configID, name, configType, stylingType))
return a
}
func (a *Aggregate) PushIDPConfigChanged(
ctx context.Context,
current *IDPConfigWriteModel,
configID,
name string,
configType idp.ConfigType,
stylingType idp.StylingType,
) *Aggregate {
event, err := NewIDPConfigChangedEvent(ctx, current, configID, name, configType, stylingType)
if err != nil {
return a
}
a.Aggregate = *a.PushEvents(event)
return a
}
func (a *Aggregate) PushIDPConfigDeactivated(ctx context.Context, configID string) *Aggregate {
a.Aggregate = *a.PushEvents(NewIDPConfigDeactivatedEvent(ctx, configID))
return a
}
func (a *Aggregate) PushIDPConfigReactivated(ctx context.Context, configID string) *Aggregate {
a.Aggregate = *a.PushEvents(NewIDPConfigReactivatedEvent(ctx, configID))
return a
}
func (a *Aggregate) PushIDPConfigRemoved(ctx context.Context, configID string) *Aggregate {
a.Aggregate = *a.PushEvents(NewIDPConfigRemovedEvent(ctx, configID))
return a
}
func (a *Aggregate) PushIDPOIDCConfigAdded(
ctx context.Context,
clientID,
idpConfigID,
issuer string,
clientSecret *crypto.CryptoValue,
idpDisplayNameMapping,
userNameMapping oidc.MappingField,
scopes ...string,
) *Aggregate {
a.Aggregate = *a.PushEvents(NewIDPOIDCConfigAddedEvent(ctx, clientID, idpConfigID, issuer, clientSecret, idpDisplayNameMapping, userNameMapping, scopes...))
return a
}
func (a *Aggregate) PushIDPOIDCConfigChanged(
ctx context.Context,
current *IDPOIDCConfigWriteModel,
clientID,
idpConfigID,
issuer string,
clientSecret *crypto.CryptoValue,
idpDisplayNameMapping,
userNameMapping oidc.MappingField,
scopes ...string,
) *Aggregate {
event, err := NewIDPOIDCConfigChangedEvent(ctx, current, clientID, idpConfigID, issuer, clientSecret, idpDisplayNameMapping, userNameMapping, scopes...)
if err != nil {
return a
}
a.Aggregate = *a.PushEvents(event)
return a
}

View File

@ -4,8 +4,8 @@ import (
"context" "context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/repository/idp" "github.com/caos/zitadel/internal/v2/repository/idp"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
) )
const ( const (
@ -33,15 +33,10 @@ func (rm *IDPConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.ConfigReadModel.AppendEvents(&e.ConfigReactivatedEvent) rm.ConfigReadModel.AppendEvents(&e.ConfigReactivatedEvent)
case *IDPConfigRemovedEvent: case *IDPConfigRemovedEvent:
rm.ConfigReadModel.AppendEvents(&e.ConfigRemovedEvent) rm.ConfigReadModel.AppendEvents(&e.ConfigRemovedEvent)
case *idp.ConfigAddedEvent, case *IDPOIDCConfigAddedEvent:
*idp.ConfigChangedEvent, rm.ConfigReadModel.AppendEvents(&e.ConfigAddedEvent)
*idp.ConfigDeactivatedEvent, case *IDPOIDCConfigChangedEvent:
*idp.ConfigReactivatedEvent, rm.ConfigReadModel.AppendEvents(&e.ConfigChangedEvent)
*idp.ConfigRemovedEvent,
*oidc.ConfigAddedEvent,
*oidc.ConfigChangedEvent:
rm.ConfigReadModel.AppendEvents(e)
} }
} }
} }
@ -100,6 +95,15 @@ func NewIDPConfigAddedEvent(
} }
} }
func IDPConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := idp.ConfigAddedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPConfigAddedEvent{ConfigAddedEvent: *e}, nil
}
type IDPConfigChangedEvent struct { type IDPConfigChangedEvent struct {
idp.ConfigChangedEvent idp.ConfigChangedEvent
} }
@ -131,6 +135,15 @@ func NewIDPConfigChangedEvent(
}, nil }, nil
} }
func IDPConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := idp.ConfigChangedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPConfigChangedEvent{ConfigChangedEvent: *e}, nil
}
type IDPConfigRemovedEvent struct { type IDPConfigRemovedEvent struct {
idp.ConfigRemovedEvent idp.ConfigRemovedEvent
} }
@ -151,6 +164,15 @@ func NewIDPConfigRemovedEvent(
} }
} }
func IDPConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := idp.ConfigRemovedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPConfigRemovedEvent{ConfigRemovedEvent: *e}, nil
}
type IDPConfigDeactivatedEvent struct { type IDPConfigDeactivatedEvent struct {
idp.ConfigDeactivatedEvent idp.ConfigDeactivatedEvent
} }
@ -171,6 +193,15 @@ func NewIDPConfigDeactivatedEvent(
} }
} }
func IDPConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := idp.ConfigDeactivatedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPConfigDeactivatedEvent{ConfigDeactivatedEvent: *e}, nil
}
type IDPConfigReactivatedEvent struct { type IDPConfigReactivatedEvent struct {
idp.ConfigReactivatedEvent idp.ConfigReactivatedEvent
} }
@ -190,3 +221,12 @@ func NewIDPConfigReactivatedEvent(
), ),
} }
} }
func IDPConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := idp.ConfigReactivatedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPConfigReactivatedEvent{ConfigReactivatedEvent: *e}, nil
}

View File

@ -0,0 +1,31 @@
package iam
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/idp"
)
type IDPConfigsReadModel struct {
idp.ConfigsReadModel
}
func (rm *IDPConfigsReadModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *IDPConfigAddedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigAddedEvent)
case *IDPConfigChangedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigChangedEvent)
case *IDPConfigDeactivatedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigDeactivatedEvent)
case *IDPConfigReactivatedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigReactivatedEvent)
case *IDPConfigRemovedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigRemovedEvent)
case *IDPOIDCConfigAddedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigAddedEvent)
case *IDPOIDCConfigChangedEvent:
rm.ConfigsReadModel.AppendEvents(&e.ConfigChangedEvent)
}
}
}

View File

@ -5,6 +5,7 @@ import (
"github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/repository/idp/oidc" "github.com/caos/zitadel/internal/v2/repository/idp/oidc"
) )
@ -64,6 +65,15 @@ func NewIDPOIDCConfigAddedEvent(
} }
} }
func IDPOIDCConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := oidc.ConfigAddedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPOIDCConfigAddedEvent{ConfigAddedEvent: *e}, nil
}
type IDPOIDCConfigChangedEvent struct { type IDPOIDCConfigChangedEvent struct {
oidc.ConfigChangedEvent oidc.ConfigChangedEvent
} }
@ -102,3 +112,12 @@ func NewIDPOIDCConfigChangedEvent(
ConfigChangedEvent: *event, ConfigChangedEvent: *event,
}, nil }, nil
} }
func IDPOIDCConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := oidc.ConfigChangedEventMapper(event)
if err != nil {
return nil, err
}
return &IDPOIDCConfigChangedEvent{ConfigChangedEvent: *e}, nil
}

View File

@ -19,7 +19,10 @@ func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.ReadModel.AppendEvents(&e.ChangedEvent) rm.ReadModel.AppendEvents(&e.ChangedEvent)
case *MemberRemovedEvent: case *MemberRemovedEvent:
rm.ReadModel.AppendEvents(&e.RemovedEvent) rm.ReadModel.AppendEvents(&e.RemovedEvent)
case *member.AddedEvent, *member.ChangedEvent, *member.RemovedEvent: case *member.AddedEvent,
*member.ChangedEvent,
*member.RemovedEvent:
rm.ReadModel.AppendEvents(e) rm.ReadModel.AppendEvents(e)
} }
} }

View File

@ -21,7 +21,9 @@ func (rm *PasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventRea
rm.ReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) rm.ReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent)
case *PasswordAgePolicyChangedEvent: case *PasswordAgePolicyChangedEvent:
rm.ReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) rm.ReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent)
case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent: case *policy.PasswordAgePolicyAddedEvent,
*policy.PasswordAgePolicyChangedEvent:
rm.ReadModel.AppendEvents(e) rm.ReadModel.AppendEvents(e)
} }
} }

View File

@ -21,7 +21,9 @@ func (rm *PasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.E
rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent)
case *PasswordComplexityPolicyChangedEvent: case *PasswordComplexityPolicyChangedEvent:
rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent)
case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent: case *policy.PasswordComplexityPolicyAddedEvent,
*policy.PasswordComplexityPolicyChangedEvent:
rm.ReadModel.AppendEvents(e) rm.ReadModel.AppendEvents(e)
} }
} }

View File

@ -13,6 +13,7 @@ type ReadModel struct {
SetUpDone Step SetUpDone Step
Members MembersReadModel Members MembersReadModel
IDPs IDPConfigsReadModel
GlobalOrgID string GlobalOrgID string
ProjectID string ProjectID string
@ -33,23 +34,53 @@ func NewReadModel(id string) *ReadModel {
} }
} }
func (rm *ReadModel) IDPByID(idpID string) *IDPConfigReadModel {
_, config := rm.IDPs.ConfigByID(idpID)
if config == nil {
return nil
}
return &IDPConfigReadModel{ConfigReadModel: *config}
}
func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.ReadModel.AppendEvents(events...) rm.ReadModel.AppendEvents(events...)
for _, event := range events { for _, event := range events {
switch event.(type) { switch event.(type) {
case *member.AddedEvent, *member.ChangedEvent, *member.RemovedEvent: case *member.AddedEvent,
*member.ChangedEvent,
*member.RemovedEvent:
rm.Members.AppendEvents(event) rm.Members.AppendEvents(event)
case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent: case *IDPConfigAddedEvent,
*IDPConfigChangedEvent,
*IDPConfigDeactivatedEvent,
*IDPConfigReactivatedEvent,
*IDPConfigRemovedEvent,
*IDPOIDCConfigAddedEvent,
*IDPOIDCConfigChangedEvent:
rm.IDPs.AppendEvents(event)
case *policy.LabelPolicyAddedEvent,
*policy.LabelPolicyChangedEvent:
rm.DefaultLabelPolicy.AppendEvents(event) rm.DefaultLabelPolicy.AppendEvents(event)
case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent: case *policy.LoginPolicyAddedEvent,
*policy.LoginPolicyChangedEvent:
rm.DefaultLoginPolicy.AppendEvents(event) rm.DefaultLoginPolicy.AppendEvents(event)
case *policy.OrgIAMPolicyAddedEvent: case *policy.OrgIAMPolicyAddedEvent:
rm.DefaultOrgIAMPolicy.AppendEvents(event) rm.DefaultOrgIAMPolicy.AppendEvents(event)
case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent: case *policy.PasswordComplexityPolicyAddedEvent,
*policy.PasswordComplexityPolicyChangedEvent:
rm.DefaultPasswordComplexityPolicy.AppendEvents(event) rm.DefaultPasswordComplexityPolicy.AppendEvents(event)
case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent: case *policy.PasswordAgePolicyAddedEvent,
*policy.PasswordAgePolicyChangedEvent:
rm.DefaultPasswordAgePolicy.AppendEvents(event) rm.DefaultPasswordAgePolicy.AppendEvents(event)
case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent: case *policy.PasswordLockoutPolicyAddedEvent,
*policy.PasswordLockoutPolicyChangedEvent:
rm.DefaultPasswordLockoutPolicy.AppendEvents(event) rm.DefaultPasswordLockoutPolicy.AppendEvents(event)
} }
} }
@ -72,6 +103,7 @@ func (rm *ReadModel) Reduce() (err error) {
} }
for _, reduce := range []func() error{ for _, reduce := range []func() error{
rm.Members.Reduce, rm.Members.Reduce,
rm.IDPs.Reduce,
rm.DefaultLoginPolicy.Reduce, rm.DefaultLoginPolicy.Reduce,
rm.DefaultLabelPolicy.Reduce, rm.DefaultLabelPolicy.Reduce,
rm.DefaultOrgIAMPolicy.Reduce, rm.DefaultOrgIAMPolicy.Reduce,

View File

@ -19,6 +19,12 @@ type ConfigReadModel struct {
OIDCConfig *oidc.ConfigReadModel OIDCConfig *oidc.ConfigReadModel
} }
func NewConfigReadModel(configID string) *ConfigReadModel {
return &ConfigReadModel{
ConfigID: configID,
}
}
func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) { func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.ReadModel.AppendEvents(events...) rm.ReadModel.AppendEvents(events...)
for _, event := range events { for _, event := range events {
@ -57,6 +63,7 @@ func (rm *ConfigReadModel) Reduce() error {
rm.Type = ConfigTypeOIDC rm.Type = ConfigTypeOIDC
} }
} }
if err := rm.OIDCConfig.Reduce(); err != nil { if err := rm.OIDCConfig.Reduce(); err != nil {
return err return err
} }

View File

@ -11,46 +11,54 @@ type ConfigsReadModel struct {
Configs []*ConfigReadModel Configs []*ConfigReadModel
} }
func (rm *ConfigsReadModel) ConfigByID(id string) (idx int, config *ConfigReadModel) {
for idx, config = range rm.Configs {
if config.ConfigID == id {
return idx, config
}
}
return -1, nil
}
func (rm *ConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { func (rm *ConfigsReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.ReadModel.AppendEvents(events...)
for _, event := range events { for _, event := range events {
switch event.(type) { switch e := event.(type) {
case *ConfigAddedEvent:
config := NewConfigReadModel(e.ConfigID)
rm.Configs = append(rm.Configs, config)
config.AppendEvents(event)
case *ConfigChangedEvent:
_, config := rm.ConfigByID(e.ConfigID)
config.AppendEvents(e)
case *ConfigDeactivatedEvent:
_, config := rm.ConfigByID(e.ConfigID)
config.AppendEvents(e)
case *ConfigReactivatedEvent:
_, config := rm.ConfigByID(e.ConfigID)
config.AppendEvents(e)
case *oidc.ConfigAddedEvent: case *oidc.ConfigAddedEvent:
rm.OIDCConfig = &oidc.ConfigReadModel{} _, config := rm.ConfigByID(e.IDPConfigID)
rm.OIDCConfig.AppendEvents(event) config.AppendEvents(e)
case *oidc.ConfigChangedEvent: case *oidc.ConfigChangedEvent:
rm.OIDCConfig.AppendEvents(event) _, config := rm.ConfigByID(e.IDPConfigID)
config.AppendEvents(e)
case *ConfigRemovedEvent:
idx, _ := rm.ConfigByID(e.ConfigID)
if idx < 0 {
continue
}
copy(rm.Configs[idx:], rm.Configs[idx+1:])
rm.Configs[len(rm.Configs)-1] = nil
rm.Configs = rm.Configs[:len(rm.Configs)-1]
} }
} }
} }
func (rm *ConfigsReadModel) Reduce() error { func (rm *ConfigsReadModel) Reduce() error {
for _, event := range rm.Events { for _, config := range rm.Configs {
switch e := event.(type) { if err := config.Reduce(); err != nil {
case *ConfigAddedEvent:
rm.ConfigID = e.ConfigID
rm.Name = e.Name
rm.StylingType = e.StylingType
rm.State = ConfigStateActive
case *ConfigChangedEvent:
if e.Name != "" {
rm.Name = e.Name
}
if e.StylingType.Valid() {
rm.StylingType = e.StylingType
}
case *ConfigDeactivatedEvent:
rm.State = ConfigStateInactive
case *ConfigReactivatedEvent:
rm.State = ConfigStateActive
case *ConfigRemovedEvent:
rm.State = ConfigStateRemoved
case *oidc.ConfigAddedEvent:
rm.Type = ConfigTypeOIDC
}
}
if err := rm.OIDCConfig.Reduce(); err != nil {
return err return err
} }
return rm.ReadModel.Reduce() }
return nil
} }

View File

@ -42,7 +42,7 @@ func (e *ConfigAddedEvent) Data() interface{} {
return e return e
} }
func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigAddedEventMapper(event *repository.Event) (*ConfigAddedEvent, error) {
e := &ConfigAddedEvent{ e := &ConfigAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -53,7 +53,7 @@ func (e *ConfigChangedEvent) Data() interface{} {
return e return e
} }
func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigChangedEventMapper(event *repository.Event) (*ConfigChangedEvent, error) {
e := &ConfigChangedEvent{ e := &ConfigChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -33,7 +33,7 @@ func (e *ConfigDeactivatedEvent) Data() interface{} {
return e return e
} }
func ConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigDeactivatedEventMapper(event *repository.Event) (*ConfigDeactivatedEvent, error) {
e := &ConfigDeactivatedEvent{ e := &ConfigDeactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -33,7 +33,7 @@ func (e *ConfigReactivatedEvent) Data() interface{} {
return e return e
} }
func ConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigReactivatedEventMapper(event *repository.Event) (*ConfigReactivatedEvent, error) {
e := &ConfigReactivatedEvent{ e := &ConfigReactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -33,7 +33,7 @@ func (e *ConfigRemovedEvent) Data() interface{} {
return e return e
} }
func ConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigRemovedEventMapper(event *repository.Event) (*ConfigRemovedEvent, error) {
e := &ConfigRemovedEvent{ e := &ConfigRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -53,7 +53,7 @@ func NewConfigAddedEvent(
} }
} }
func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigAddedEventMapper(event *repository.Event) (*ConfigAddedEvent, error) {
e := &ConfigAddedEvent{ e := &ConfigAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }

View File

@ -91,7 +91,7 @@ func NewConfigChangedEvent(
return event, nil return event, nil
} }
func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func ConfigChangedEventMapper(event *repository.Event) (*ConfigChangedEvent, error) {
e := &ConfigChangedEvent{ e := &ConfigChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }