mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-02 12:22:15 +00:00
feat: idps (#1188)
* add setup steps * refactoring * omitempty * cleanup * begin org * create org * setup org * setup org * merge * fixes * fixes * fixes * add project * add oidc application * fix app creation * add resourceOwner to writemodels * resource owner * cleanup * global org, iam project and iam member in setup * logs * logs * logs * cleanup * Update internal/v2/command/project.go Co-authored-by: Fabi <[email protected]> * check project state * add org domain commands * add org status changes and member commands * fixes * policies * login policy * fix iam project event * mapper * label policy * change to command * fix * fix * handle change event differently and lot of fixes * idps * fixes * fixes * fixes * changedEvent handling * fix change events * remove creation date Co-authored-by: Fabi <[email protected]>
This commit is contained in:
@@ -86,7 +86,7 @@ func writeModelToPasswordLockoutPolicy(wm *PasswordLockoutPolicyWriteModel) *dom
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPConfig(wm *IAMIDPConfigWriteModel) *domain.IDPConfig {
|
||||
func writeModelToIDPConfig(wm *IDPConfigWriteModel) *domain.IDPConfig {
|
||||
return &domain.IDPConfig{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig),
|
||||
|
||||
@@ -55,7 +55,7 @@ func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *domain.ID
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(addedConfig), nil
|
||||
return writeModelToIDPConfig(&addedConfig.IDPConfigWriteModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain.IDPConfig) (*domain.IDPConfig, error) {
|
||||
@@ -78,44 +78,35 @@ func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
return writeModelToIDPConfig(&existingIDP.IDPConfigWriteModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
|
||||
func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, idpID string) error {
|
||||
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, idpID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateActive {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive")
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIDPConfigDeactivatedEvent(ctx, idpID))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
return r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
|
||||
func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) error {
|
||||
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, idpID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateInactive {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mo0d", "Errors.IAM.IDPConfig.NotInactive")
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mo0d", "Errors.IAM.IDPConfig.NotInactive")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIDPConfigReactivatedEvent(ctx, idpID))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
return r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, idpID string) error {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
)
|
||||
|
||||
type IAMIDPConfigWriteModel struct {
|
||||
@@ -88,16 +89,19 @@ func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
|
||||
stylingType domain.IDPConfigStylingType,
|
||||
) (*iam.IDPConfigChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewIDPConfigChangedEvent(ctx)
|
||||
changedEvent.ConfigID = configID
|
||||
changes := make([]idpconfig.IDPConfigChanges, 0)
|
||||
if wm.Name != name {
|
||||
hasChanged = true
|
||||
changedEvent.Name = name
|
||||
changes = append(changes, idpconfig.ChangeName(name))
|
||||
}
|
||||
if stylingType.Valid() && wm.StylingType != stylingType {
|
||||
hasChanged = true
|
||||
changedEvent.StylingType = stylingType
|
||||
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
changeEvent, err := iam.NewIDPConfigChangedEvent(ctx, configID, changes)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return changeEvent, true
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *do
|
||||
|
||||
changedEvent, hasChanged, err := existingConfig.NewChangedEvent(
|
||||
ctx,
|
||||
config.IDPConfigID,
|
||||
config.ClientID,
|
||||
config.Issuer,
|
||||
config.ClientSecretString,
|
||||
|
||||
@@ -8,14 +8,15 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
)
|
||||
|
||||
type IDPOIDCConfigWriteModel struct {
|
||||
type IAMIDPOIDCConfigWriteModel struct {
|
||||
OIDCConfigWriteModel
|
||||
}
|
||||
|
||||
func NewIAMIDPOIDCConfigWriteModel(idpConfigID string) *IDPOIDCConfigWriteModel {
|
||||
return &IDPOIDCConfigWriteModel{
|
||||
func NewIAMIDPOIDCConfigWriteModel(idpConfigID string) *IAMIDPOIDCConfigWriteModel {
|
||||
return &IAMIDPOIDCConfigWriteModel{
|
||||
OIDCConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: domain.IAMID,
|
||||
@@ -26,7 +27,7 @@ func NewIAMIDPOIDCConfigWriteModel(idpConfigID string) *IDPOIDCConfigWriteModel
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
func (wm *IAMIDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.IDPOIDCConfigAddedEvent:
|
||||
@@ -60,21 +61,22 @@ func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Reduce() error {
|
||||
func (wm *IAMIDPOIDCConfigWriteModel) Reduce() error {
|
||||
if err := wm.OIDCConfigWriteModel.Reduce(); err != nil {
|
||||
return err
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
func (wm *IAMIDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
ResourceOwner(wm.ResourceOwner)
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
func (wm *IAMIDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
idpConfigID,
|
||||
clientID,
|
||||
issuer,
|
||||
clientSecretString string,
|
||||
@@ -83,8 +85,8 @@ func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
userNameMapping domain.OIDCMappingField,
|
||||
scopes ...string,
|
||||
) (*iam.IDPOIDCConfigChangedEvent, bool, error) {
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewIDPOIDCConfigChangedEvent(ctx)
|
||||
|
||||
changes := make([]idpconfig.OIDCConfigChanges, 0)
|
||||
var clientSecret *crypto.CryptoValue
|
||||
var err error
|
||||
if clientSecretString != "" {
|
||||
@@ -92,27 +94,29 @@ func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
changedEvent.ClientSecret = clientSecret
|
||||
changes = append(changes, idpconfig.ChangeClientSecret(clientSecret))
|
||||
}
|
||||
if wm.ClientID != clientID {
|
||||
hasChanged = true
|
||||
changedEvent.ClientID = clientID
|
||||
changes = append(changes, idpconfig.ChangeClientID(clientID))
|
||||
}
|
||||
if wm.Issuer != issuer {
|
||||
hasChanged = true
|
||||
changedEvent.Issuer = issuer
|
||||
changes = append(changes, idpconfig.ChangeIssuer(issuer))
|
||||
}
|
||||
if idpDisplayNameMapping.Valid() && wm.IDPDisplayNameMapping != idpDisplayNameMapping {
|
||||
hasChanged = true
|
||||
changedEvent.IDPDisplayNameMapping = idpDisplayNameMapping
|
||||
changes = append(changes, idpconfig.ChangeIDPDisplayNameMapping(idpDisplayNameMapping))
|
||||
}
|
||||
if userNameMapping.Valid() && wm.UserNameMapping != userNameMapping {
|
||||
hasChanged = true
|
||||
changedEvent.UserNameMapping = userNameMapping
|
||||
changes = append(changes, idpconfig.ChangeUserNameMapping(userNameMapping))
|
||||
}
|
||||
if reflect.DeepEqual(wm.Scopes, scopes) {
|
||||
hasChanged = true
|
||||
changedEvent.Scopes = scopes
|
||||
changes = append(changes, idpconfig.ChangeScopes(scopes))
|
||||
}
|
||||
return changedEvent, hasChanged, nil
|
||||
if len(changes) == 0 {
|
||||
return nil, false, nil
|
||||
}
|
||||
changeEvent, err := iam.NewIDPOIDCConfigChangedEvent(ctx, idpConfigID, changes)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return changeEvent, true, nil
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ func (rm *IDPConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAdde
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) {
|
||||
if e.Name != "" {
|
||||
rm.Name = e.Name
|
||||
if e.Name != nil {
|
||||
rm.Name = *e.Name
|
||||
}
|
||||
if e.StylingType.Valid() {
|
||||
rm.StylingType = e.StylingType
|
||||
if e.StylingType != nil && e.StylingType.Valid() {
|
||||
rm.StylingType = *e.StylingType
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,19 +52,19 @@ func (wm *OIDCConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.OIDCConfigAd
|
||||
}
|
||||
|
||||
func (wm *OIDCConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.OIDCConfigChangedEvent) {
|
||||
if e.ClientID != "" {
|
||||
wm.ClientID = e.ClientID
|
||||
if e.ClientID != nil {
|
||||
wm.ClientID = *e.ClientID
|
||||
}
|
||||
if e.Issuer != "" {
|
||||
wm.Issuer = e.Issuer
|
||||
if e.Issuer != nil {
|
||||
wm.Issuer = *e.Issuer
|
||||
}
|
||||
if len(e.Scopes) > 0 {
|
||||
wm.Scopes = e.Scopes
|
||||
}
|
||||
if e.IDPDisplayNameMapping.Valid() {
|
||||
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
if e.IDPDisplayNameMapping != nil && e.IDPDisplayNameMapping.Valid() {
|
||||
wm.IDPDisplayNameMapping = *e.IDPDisplayNameMapping
|
||||
}
|
||||
if e.UserNameMapping.Valid() {
|
||||
wm.UserNameMapping = e.UserNameMapping
|
||||
if e.UserNameMapping != nil && e.UserNameMapping.Valid() {
|
||||
wm.UserNameMapping = *e.UserNameMapping
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
org_repo "github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddIDPConfig(ctx context.Context, config *domain.IDPConfig) (*domain.IDPConfig, error) {
|
||||
if config.OIDCConfig == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "Org-eUpQU", "Errors.idp.config.notset")
|
||||
}
|
||||
|
||||
idpConfigID, err := r.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//TODO: check name unique on aggregate
|
||||
addedConfig := NewOrgIDPConfigWriteModel(idpConfigID, config.AggregateID)
|
||||
|
||||
clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.idpConfigSecretCrypto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orgAgg := OrgAggregateFromWriteModel(&addedConfig.WriteModel)
|
||||
orgAgg.PushEvents(
|
||||
org_repo.NewIDPConfigAddedEvent(
|
||||
ctx,
|
||||
idpConfigID,
|
||||
config.Name,
|
||||
config.Type,
|
||||
config.StylingType,
|
||||
),
|
||||
)
|
||||
orgAgg.PushEvents(
|
||||
org_repo.NewIDPOIDCConfigAddedEvent(
|
||||
ctx, config.OIDCConfig.ClientID,
|
||||
idpConfigID,
|
||||
config.OIDCConfig.Issuer,
|
||||
clientSecret,
|
||||
config.OIDCConfig.IDPDisplayNameMapping,
|
||||
config.OIDCConfig.UsernameMapping,
|
||||
config.OIDCConfig.Scopes...,
|
||||
),
|
||||
)
|
||||
err = r.eventstore.PushAggregate(ctx, addedConfig, orgAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(&addedConfig.IDPConfigWriteModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeIDPConfig(ctx context.Context, config *domain.IDPConfig) (*domain.IDPConfig, error) {
|
||||
existingIDP, err := r.orgIDPConfigWriteModelByID(ctx, config.IDPConfigID, config.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotExisting")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, config.IDPConfigID, config.Name, config.StylingType)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
|
||||
}
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
orgAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, orgAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(&existingIDP.IDPConfigWriteModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) DeactivateIDPConfig(ctx context.Context, idpID, orgID string) error {
|
||||
existingIDP, err := r.orgIDPConfigWriteModelByID(ctx, idpID, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateActive {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotActive")
|
||||
}
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
orgAgg.PushEvents(org_repo.NewIDPConfigDeactivatedEvent(ctx, idpID))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, existingIDP, orgAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) ReactivateIDPConfig(ctx context.Context, idpID, orgID string) error {
|
||||
existingIDP, err := r.orgIDPConfigWriteModelByID(ctx, idpID, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateInactive {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "Org-5Mo0d", "Errors.Org.IDPConfig.NotInactive")
|
||||
}
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
orgAgg.PushEvents(org_repo.NewIDPConfigReactivatedEvent(ctx, idpID))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, existingIDP, orgAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveIDPConfig(ctx context.Context, idpID, orgID string) error {
|
||||
_, err := r.pushIDPWriteModel(ctx, idpID, orgID, func(a *org.Aggregate, _ *OrgIDPConfigWriteModel) *org.Aggregate {
|
||||
a.Aggregate = *a.PushEvents(org_repo.NewIDPConfigRemovedEvent(ctx, idpID))
|
||||
return a
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *CommandSide) pushIDPWriteModel(ctx context.Context, idpID, orgID string, eventSetter func(*org.Aggregate, *OrgIDPConfigWriteModel) *org.Aggregate) (*OrgIDPConfigWriteModel, error) {
|
||||
writeModel := NewOrgIDPConfigWriteModel(idpID, orgID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregate := eventSetter(OrgAggregateFromWriteModel(&writeModel.WriteModel), writeModel)
|
||||
err = r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) orgIDPConfigWriteModelByID(ctx context.Context, idpID, orgID string) (policy *OrgIDPConfigWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewOrgIDPConfigWriteModel(idpID, orgID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
type OrgIDPConfigWriteModel struct {
|
||||
IDPConfigWriteModel
|
||||
}
|
||||
|
||||
func NewOrgIDPConfigWriteModel(configID, orgID string) *OrgIDPConfigWriteModel {
|
||||
return &OrgIDPConfigWriteModel{
|
||||
IDPConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: orgID,
|
||||
ResourceOwner: orgID,
|
||||
},
|
||||
ConfigID: configID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *OrgIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
ResourceOwner(wm.ResourceOwner)
|
||||
}
|
||||
|
||||
func (wm *OrgIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigAddedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigAddedEvent)
|
||||
case *org.IDPConfigChangedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigChangedEvent)
|
||||
case *org.IDPConfigDeactivatedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent)
|
||||
case *org.IDPConfigReactivatedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent)
|
||||
case *org.IDPConfigRemovedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent)
|
||||
case *org.IDPOIDCConfigAddedEvent:
|
||||
if wm.ConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent)
|
||||
case *org.IDPOIDCConfigChangedEvent:
|
||||
if wm.ConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *OrgIDPConfigWriteModel) Reduce() error {
|
||||
return wm.IDPConfigWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *OrgIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventReader) error {
|
||||
wm.AppendEvents(events...)
|
||||
return wm.Reduce()
|
||||
}
|
||||
|
||||
func (wm *OrgIDPConfigWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
configID,
|
||||
name string,
|
||||
stylingType domain.IDPConfigStylingType,
|
||||
) (*org.IDPConfigChangedEvent, bool) {
|
||||
|
||||
changes := make([]idpconfig.IDPConfigChanges, 0)
|
||||
if wm.Name != name {
|
||||
changes = append(changes, idpconfig.ChangeName(name))
|
||||
}
|
||||
if stylingType.Valid() && wm.StylingType != stylingType {
|
||||
changes = append(changes, idpconfig.ChangeStyleType(stylingType))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
changeEvent, err := org.NewIDPConfigChangedEvent(ctx, configID, changes)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return changeEvent, true
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
func (r *CommandSide) ChangeIDPOIDCConfig(ctx context.Context, config *domain.OIDCIDPConfig) (*domain.OIDCIDPConfig, error) {
|
||||
existingConfig := NewOrgIDPOIDCConfigWriteModel(config.IDPConfigID, config.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, existingConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existingConfig.State == domain.IDPConfigStateRemoved || existingConfig.State == domain.IDPConfigStateUnspecified {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "Org-67J9d", "Errors.Org.IDPConfig.AlreadyExists")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged, err := existingConfig.NewChangedEvent(
|
||||
ctx,
|
||||
config.IDPConfigID,
|
||||
config.ClientID,
|
||||
config.Issuer,
|
||||
config.ClientSecretString,
|
||||
r.idpConfigSecretCrypto,
|
||||
config.IDPDisplayNameMapping,
|
||||
config.UsernameMapping,
|
||||
config.Scopes...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
orgAgg := OrgAggregateFromWriteModel(&existingConfig.WriteModel)
|
||||
orgAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingConfig, orgAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPOIDCConfig(&existingConfig.OIDCConfigWriteModel), nil
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
type IDPOIDCConfigWriteModel struct {
|
||||
OIDCConfigWriteModel
|
||||
}
|
||||
|
||||
func NewOrgIDPOIDCConfigWriteModel(idpConfigID, orgID string) *IDPOIDCConfigWriteModel {
|
||||
return &IDPOIDCConfigWriteModel{
|
||||
OIDCConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: orgID,
|
||||
ResourceOwner: orgID,
|
||||
},
|
||||
IDPConfigID: idpConfigID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *org.IDPOIDCConfigAddedEvent:
|
||||
if wm.IDPConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent)
|
||||
case *org.IDPOIDCConfigChangedEvent:
|
||||
if wm.IDPConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent)
|
||||
case *org.IDPConfigReactivatedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent)
|
||||
case *org.IDPConfigDeactivatedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent)
|
||||
case *org.IDPConfigRemovedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent)
|
||||
default:
|
||||
wm.OIDCConfigWriteModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Reduce() error {
|
||||
if err := wm.OIDCConfigWriteModel.Reduce(); err != nil {
|
||||
return err
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
ResourceOwner(wm.ResourceOwner)
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
idpConfigID,
|
||||
clientID,
|
||||
issuer,
|
||||
clientSecretString string,
|
||||
secretCrypto crypto.Crypto,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping domain.OIDCMappingField,
|
||||
scopes ...string,
|
||||
) (*org.IDPOIDCConfigChangedEvent, bool, error) {
|
||||
|
||||
changes := make([]idpconfig.OIDCConfigChanges, 0)
|
||||
var clientSecret *crypto.CryptoValue
|
||||
var err error
|
||||
if clientSecretString != "" {
|
||||
clientSecret, err = crypto.Crypt([]byte(clientSecretString), secretCrypto)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
changes = append(changes, idpconfig.ChangeClientSecret(clientSecret))
|
||||
}
|
||||
if wm.ClientID != clientID {
|
||||
changes = append(changes, idpconfig.ChangeClientID(clientID))
|
||||
}
|
||||
if wm.Issuer != issuer {
|
||||
changes = append(changes, idpconfig.ChangeIssuer(issuer))
|
||||
}
|
||||
if idpDisplayNameMapping.Valid() && wm.IDPDisplayNameMapping != idpDisplayNameMapping {
|
||||
changes = append(changes, idpconfig.ChangeIDPDisplayNameMapping(idpDisplayNameMapping))
|
||||
}
|
||||
if userNameMapping.Valid() && wm.UserNameMapping != userNameMapping {
|
||||
changes = append(changes, idpconfig.ChangeUserNameMapping(userNameMapping))
|
||||
}
|
||||
if reflect.DeepEqual(wm.Scopes, scopes) {
|
||||
changes = append(changes, idpconfig.ChangeScopes(scopes))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, false, nil
|
||||
}
|
||||
changeEvent, err := org.NewIDPOIDCConfigChangedEvent(ctx, idpConfigID, changes)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return changeEvent, true, nil
|
||||
}
|
||||
Reference in New Issue
Block a user