mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
idp
This commit is contained in:
parent
f6cdcee77a
commit
4bb9650f27
@ -33,8 +33,8 @@ type IAMRepository struct {
|
||||
IAMV2 *iam_business.Repository
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) IAMMemberByID(ctx context.Context, orgID, userID string) (*iam_model.IAMMemberView, error) {
|
||||
member, err := repo.View.IAMMemberByIDs(orgID, userID)
|
||||
func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID string) (*iam_model.IAMMemberView, error) {
|
||||
member, err := repo.View.IAMMemberByIDs(iamID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -44,7 +44,7 @@ func (repo *IAMRepository) IAMMemberByID(ctx context.Context, orgID, userID stri
|
||||
func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
member.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddIAMMember(ctx, member)
|
||||
return repo.IAMV2.AddMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.AddIAMMember(ctx, member)
|
||||
}
|
||||
@ -52,7 +52,7 @@ func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.I
|
||||
func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
member.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeIAMMember(ctx, member)
|
||||
return repo.IAMV2.ChangeMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeIAMMember(ctx, member)
|
||||
}
|
||||
@ -60,7 +60,7 @@ func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_mode
|
||||
func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error {
|
||||
member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID)
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.RemoveIAMMember(ctx, member)
|
||||
return repo.IAMV2.RemoveMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.RemoveIAMMember(ctx, member)
|
||||
}
|
||||
@ -97,12 +97,17 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string {
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.IDPConfigByID(ctx, idpConfigID)
|
||||
}
|
||||
|
||||
idp, err := repo.View.IDPConfigByID(idpConfigID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IDPConfigViewToModel(idp), nil
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
idp.AggregateID = repo.SystemDefaults.IamID
|
||||
return repo.IAMEventstore.AddIDPConfig(ctx, idp)
|
||||
|
@ -16,6 +16,8 @@ import (
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
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/idp"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
"github.com/caos/zitadel/internal/v2/repository/member"
|
||||
)
|
||||
|
||||
@ -43,7 +45,14 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
esV2 := es.V2()
|
||||
esV2.RegisterFilterEventMapper(iam.MemberAddedEventType, member.AddedEventMapper).
|
||||
RegisterFilterEventMapper(iam.MemberChangedEventType, member.ChangedEventMapper).
|
||||
RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper)
|
||||
RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPConfigAddedEventType, idp.ConfigAddedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPConfigChangedEventType, idp.ConfigChangedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPConfigDeactivatedEventType, idp.ConfigDeactivatedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPConfigReactivatedEventType, idp.ConfigReactivatedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPConfigRemovedEventType, idp.ConfigRemovedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPOIDCConfigAddedEventType, oidc.ConfigAddedEventMapper).
|
||||
RegisterFilterEventMapper(iam.IDPOIDCConfigChangedEventType, oidc.ConfigChangedEventMapper)
|
||||
|
||||
iam, err := es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"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/member"
|
||||
)
|
||||
|
||||
@ -133,3 +134,24 @@ func writeModelToMember(writeModel *iam.MemberWriteModel) *model.IAMMember {
|
||||
UserID: writeModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPConfigView(rm *iam.IDPConfigReadModel) *model.IDPConfigView {
|
||||
return &model.IDPConfigView{
|
||||
AggregateID: rm.AggregateID,
|
||||
ChangeDate: rm.ChangeDate,
|
||||
CreationDate: rm.CreationDate,
|
||||
IDPConfigID: rm.ConfigID,
|
||||
IDPProviderType: model.IDPProviderType(rm.ProviderType),
|
||||
IsOIDC: rm.Type == idp.ConfigTypeOIDC,
|
||||
Name: rm.Name,
|
||||
OIDCClientID: rm.OIDCConfig.ClientID,
|
||||
OIDCClientSecret: rm.OIDCConfig.ClientSecret,
|
||||
OIDCIDPDisplayNameMapping: model.OIDCMappingField(rm.OIDCConfig.IDPDisplayNameMapping),
|
||||
OIDCIssuer: rm.OIDCConfig.Issuer,
|
||||
OIDCScopes: rm.OIDCConfig.Scopes,
|
||||
OIDCUsernameMapping: model.OIDCMappingField(rm.OIDCConfig.UserNameMapping),
|
||||
Sequence: rm.ProcessedSequence,
|
||||
State: model.IDPConfigState(rm.State),
|
||||
StylingType: model.IDPStylingType(rm.StylingType),
|
||||
}
|
||||
}
|
||||
|
30
internal/v2/business/iam/idp_oidc_config.go
Normal file
30
internal/v2/business/iam/idp_oidc_config.go
Normal file
@ -0,0 +1,30 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *Repository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) {
|
||||
query := eventstore.NewSearchQueryFactory(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
EventData(map[string]interface{}{
|
||||
"idpConfigId": idpConfigID,
|
||||
})
|
||||
|
||||
idpConfig := new(iam.IDPConfigReadModel)
|
||||
|
||||
events, err := r.eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idpConfig.AppendEvents(events...)
|
||||
if err = idpConfig.Reduce(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readModelToIDPConfigView(idpConfig), nil
|
||||
}
|
@ -11,7 +11,9 @@ import (
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *Repository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//TODO: check if roles valid
|
||||
|
||||
if !member.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid")
|
||||
}
|
||||
@ -40,14 +42,15 @@ func (r *Repository) AddIAMMember(ctx context.Context, member *iam_model.IAMMemb
|
||||
|
||||
_, addedMember := iam.Members.MemberByUserID(member.UserID)
|
||||
if member == nil {
|
||||
return nil, errors.ThrowInternal(nil, "IAM-nuoDN", "member not saved")
|
||||
return nil, errors.ThrowInternal(nil, "IAM-nuoDN", "Errors.Internal")
|
||||
}
|
||||
return readModelToMember(addedMember), nil
|
||||
}
|
||||
|
||||
//ChangeIAMMember updates an existing member
|
||||
//TODO: refactor to ChangeMember
|
||||
func (r *Repository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//ChangeMember updates an existing member
|
||||
func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//TODO: check if roles valid
|
||||
|
||||
if !member.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid")
|
||||
}
|
||||
@ -66,16 +69,14 @@ func (r *Repository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMM
|
||||
}
|
||||
|
||||
existingMember.AppendEvents(events...)
|
||||
|
||||
updatedMember, err := r.MemberByID(ctx, member.AggregateID, member.UserID)
|
||||
if err != nil {
|
||||
if err = existingMember.Reduce(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readModelToMember(&updatedMember.ReadModel), nil
|
||||
return writeModelToMember(existingMember), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error {
|
||||
func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMember) error {
|
||||
iam, err := r.iamByID(ctx, member.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -115,3 +116,20 @@ func (r *Repository) MemberByID(ctx context.Context, iamID, userID string) (memb
|
||||
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func (r *Repository) memberWriteModelByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := iam_repo.NewMemberReadModel(iamID, userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if writeModel.IsRemoved {
|
||||
return nil, errors.ThrowNotFound(nil, "IAM-D8JxR", "Errors.NotFound")
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package iam
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/tracing"
|
||||
@ -45,20 +44,3 @@ func (r *Repository) iamByID(ctx context.Context, id string) (_ *iam_repo.ReadMo
|
||||
|
||||
return readModel, nil
|
||||
}
|
||||
|
||||
func (r *Repository) memberWriteModelByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := iam_repo.NewMemberReadModel(iamID, userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if writeModel.IsRemoved {
|
||||
return nil, errors.ThrowNotFound(nil, "IAM-D8JxR", "Errors.NotFound")
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
||||
|
@ -1,49 +1,50 @@
|
||||
package iam
|
||||
|
||||
// import (
|
||||
// "context"
|
||||
import (
|
||||
"context"
|
||||
|
||||
// caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
// "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
// iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
// )
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
// func (r *Repository) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
// iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepStartedEvent(ctx, iam_repo.Step(step)))
|
||||
// if err != nil {
|
||||
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
// }
|
||||
// return iam, nil
|
||||
// }
|
||||
func (r *Repository) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepStartedEvent(ctx, iam_repo.Step(step)))
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
}
|
||||
return iam, nil
|
||||
}
|
||||
|
||||
// func (r *Repository) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
// iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepDoneEvent(ctx, iam_repo.Step(step)))
|
||||
// if err != nil {
|
||||
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
// }
|
||||
// return iam, nil
|
||||
// }
|
||||
func (r *Repository) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepDoneEvent(ctx, iam_repo.Step(step)))
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
}
|
||||
return iam, nil
|
||||
}
|
||||
|
||||
// func (r *Repository) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) {
|
||||
// iam, err := r.iamByID(ctx, iamID)
|
||||
// if err != nil && !caos_errs.IsNotFound(err) {
|
||||
// return nil, err
|
||||
// }
|
||||
func (r *Repository) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) {
|
||||
iam, err := r.iamByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) {
|
||||
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
|
||||
// }
|
||||
if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
|
||||
}
|
||||
|
||||
// aggregate := iam_repo.AggregateFromReadModel(iam).
|
||||
// PushEvents(event)
|
||||
aggregate := iam_repo.AggregateFromReadModel(iam).
|
||||
PushEvents(event)
|
||||
|
||||
// events, err := r.eventstore.PushAggregates(ctx, aggregate)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
events, err := r.eventstore.PushAggregates(ctx, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if err = iam.AppendAndReduce(events...); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return readModelToIAM(iam), nil
|
||||
// }
|
||||
if err = iam.AppendAndReduce(events...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return readModelToIAM(iam), nil
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ const (
|
||||
|
||||
type Aggregate struct {
|
||||
eventstore.Aggregate
|
||||
|
||||
// SetUpStarted Step
|
||||
// SetUpDone Step
|
||||
}
|
||||
|
||||
func NewAggregate(
|
||||
@ -54,8 +51,6 @@ func AggregateFromReadModel(rm *ReadModel) *Aggregate {
|
||||
AggregateVersion,
|
||||
rm.ProcessedSequence,
|
||||
),
|
||||
// SetUpDone: rm.SetUpDone,
|
||||
// SetUpStarted: rm.SetUpStarted,
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,3 +77,13 @@ func (a *Aggregate) PushMemberRemoved(ctx context.Context, userID string) *Aggre
|
||||
a.Aggregate = *a.PushEvents(NewMemberRemovedEvent(ctx, userID))
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Aggregate) PushStepStarted(ctx context.Context, step Step) *Aggregate {
|
||||
a.Aggregate = *a.PushEvents(NewSetupStepStartedEvent(ctx, step))
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Aggregate) PushStepDone(ctx context.Context, step Step) *Aggregate {
|
||||
a.Aggregate = *a.PushEvents(NewSetupStepDoneEvent(ctx, step))
|
||||
return a
|
||||
}
|
||||
|
192
internal/v2/repository/iam/idp_config.go
Normal file
192
internal/v2/repository/iam/idp_config.go
Normal file
@ -0,0 +1,192 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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 (
|
||||
IDPConfigAddedEventType eventstore.EventType = "iam.idp.config.added"
|
||||
IDPConfigChangedEventType eventstore.EventType = "iam.idp.config.changed"
|
||||
IDPConfigRemovedEventType eventstore.EventType = "iam.idp.config.removed"
|
||||
IDPConfigDeactivatedEventType eventstore.EventType = "iam.idp.config.deactivated"
|
||||
IDPConfigReactivatedEventType eventstore.EventType = "iam.idp.config.reactivated"
|
||||
)
|
||||
|
||||
type IDPConfigReadModel struct {
|
||||
idp.ConfigReadModel
|
||||
}
|
||||
|
||||
func (rm *IDPConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *IDPConfigAddedEvent:
|
||||
rm.ConfigReadModel.AppendEvents(&e.ConfigAddedEvent)
|
||||
case *IDPConfigChangedEvent:
|
||||
rm.ConfigReadModel.AppendEvents(&e.ConfigChangedEvent)
|
||||
case *IDPConfigDeactivatedEvent:
|
||||
rm.ConfigReadModel.AppendEvents(&e.ConfigDeactivatedEvent)
|
||||
case *IDPConfigReactivatedEvent:
|
||||
rm.ConfigReadModel.AppendEvents(&e.ConfigReactivatedEvent)
|
||||
case *IDPConfigRemovedEvent:
|
||||
rm.ConfigReadModel.AppendEvents(&e.ConfigRemovedEvent)
|
||||
case *idp.ConfigAddedEvent,
|
||||
*idp.ConfigChangedEvent,
|
||||
*idp.ConfigDeactivatedEvent,
|
||||
*idp.ConfigReactivatedEvent,
|
||||
*idp.ConfigRemovedEvent,
|
||||
*oidc.ConfigAddedEvent,
|
||||
*oidc.ConfigChangedEvent:
|
||||
|
||||
rm.ConfigReadModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type IDPConfigWriteModel struct {
|
||||
idp.ConfigWriteModel
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *IDPConfigAddedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigAddedEvent)
|
||||
case *IDPConfigChangedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigChangedEvent)
|
||||
case *IDPConfigDeactivatedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigDeactivatedEvent)
|
||||
case *IDPConfigReactivatedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigReactivatedEvent)
|
||||
case *IDPConfigRemovedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigRemovedEvent)
|
||||
case *idp.ConfigAddedEvent,
|
||||
*idp.ConfigChangedEvent,
|
||||
*idp.ConfigDeactivatedEvent,
|
||||
*idp.ConfigReactivatedEvent,
|
||||
*idp.ConfigRemovedEvent:
|
||||
|
||||
rm.ConfigWriteModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type IDPConfigAddedEvent struct {
|
||||
idp.ConfigAddedEvent
|
||||
}
|
||||
|
||||
func NewIDPConfigAddedEvent(
|
||||
ctx context.Context,
|
||||
configID string,
|
||||
name string,
|
||||
configType idp.ConfigType,
|
||||
stylingType idp.StylingType,
|
||||
) *IDPConfigAddedEvent {
|
||||
|
||||
return &IDPConfigAddedEvent{
|
||||
ConfigAddedEvent: *idp.NewConfigAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPConfigAddedEventType,
|
||||
),
|
||||
configID,
|
||||
name,
|
||||
configType,
|
||||
stylingType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type IDPConfigChangedEvent struct {
|
||||
idp.ConfigChangedEvent
|
||||
}
|
||||
|
||||
func NewIDPConfigChangedEvent(
|
||||
ctx context.Context,
|
||||
current *IDPConfigWriteModel,
|
||||
configID string,
|
||||
name string,
|
||||
configType idp.ConfigType,
|
||||
stylingType idp.StylingType,
|
||||
) (*IDPConfigChangedEvent, error) {
|
||||
event, err := idp.NewConfigChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPConfigChangedEventType,
|
||||
),
|
||||
¤t.ConfigWriteModel,
|
||||
name,
|
||||
stylingType,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IDPConfigChangedEvent{
|
||||
ConfigChangedEvent: *event,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type IDPConfigRemovedEvent struct {
|
||||
idp.ConfigRemovedEvent
|
||||
}
|
||||
|
||||
func NewIDPConfigRemovedEvent(
|
||||
ctx context.Context,
|
||||
configID string,
|
||||
) *IDPConfigRemovedEvent {
|
||||
|
||||
return &IDPConfigRemovedEvent{
|
||||
ConfigRemovedEvent: *idp.NewConfigRemovedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPConfigRemovedEventType,
|
||||
),
|
||||
configID,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type IDPConfigDeactivatedEvent struct {
|
||||
idp.ConfigDeactivatedEvent
|
||||
}
|
||||
|
||||
func NewIDPConfigDeactivatedEvent(
|
||||
ctx context.Context,
|
||||
configID string,
|
||||
) *IDPConfigDeactivatedEvent {
|
||||
|
||||
return &IDPConfigDeactivatedEvent{
|
||||
ConfigDeactivatedEvent: *idp.NewConfigDeactivatedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPConfigDeactivatedEventType,
|
||||
),
|
||||
configID,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type IDPConfigReactivatedEvent struct {
|
||||
idp.ConfigReactivatedEvent
|
||||
}
|
||||
|
||||
func NewIDPConfigReactivatedEvent(
|
||||
ctx context.Context,
|
||||
configID string,
|
||||
) *IDPConfigReactivatedEvent {
|
||||
|
||||
return &IDPConfigReactivatedEvent{
|
||||
ConfigReactivatedEvent: *idp.NewConfigReactivatedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPConfigReactivatedEventType,
|
||||
),
|
||||
configID,
|
||||
),
|
||||
}
|
||||
}
|
104
internal/v2/repository/iam/idp_oidc_config.go
Normal file
104
internal/v2/repository/iam/idp_oidc_config.go
Normal file
@ -0,0 +1,104 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
const (
|
||||
IDPOIDCConfigAddedEventType eventstore.EventType = "iam.idp.oidc.config.added"
|
||||
IDPOIDCConfigChangedEventType eventstore.EventType = "iam.idp.oidc.config.changed"
|
||||
)
|
||||
|
||||
type IDPOIDCConfigWriteModel struct {
|
||||
oidc.ConfigWriteModel
|
||||
}
|
||||
|
||||
func (rm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *IDPOIDCConfigAddedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigAddedEvent)
|
||||
case *IDPOIDCConfigChangedEvent:
|
||||
rm.ConfigWriteModel.AppendEvents(&e.ConfigChangedEvent)
|
||||
case *oidc.ConfigAddedEvent,
|
||||
*oidc.ConfigChangedEvent:
|
||||
|
||||
rm.ConfigWriteModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type IDPOIDCConfigAddedEvent struct {
|
||||
oidc.ConfigAddedEvent
|
||||
}
|
||||
|
||||
func NewIDPOIDCConfigAddedEvent(
|
||||
ctx context.Context,
|
||||
clientID,
|
||||
idpConfigID,
|
||||
issuer string,
|
||||
clientSecret *crypto.CryptoValue,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping oidc.MappingField,
|
||||
scopes ...string,
|
||||
) *IDPOIDCConfigAddedEvent {
|
||||
|
||||
return &IDPOIDCConfigAddedEvent{
|
||||
ConfigAddedEvent: *oidc.NewConfigAddedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPOIDCConfigAddedEventType,
|
||||
),
|
||||
clientID,
|
||||
idpConfigID,
|
||||
issuer,
|
||||
clientSecret,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping,
|
||||
scopes...,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type IDPOIDCConfigChangedEvent struct {
|
||||
oidc.ConfigChangedEvent
|
||||
}
|
||||
|
||||
func NewIDPOIDCConfigChangedEvent(
|
||||
ctx context.Context,
|
||||
current *IDPOIDCConfigWriteModel,
|
||||
clientID,
|
||||
idpConfigID,
|
||||
issuer string,
|
||||
clientSecret *crypto.CryptoValue,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping oidc.MappingField,
|
||||
scopes ...string,
|
||||
) (*IDPOIDCConfigChangedEvent, error) {
|
||||
|
||||
event, err := oidc.NewConfigChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
IDPOIDCConfigAddedEventType,
|
||||
),
|
||||
¤t.ConfigWriteModel,
|
||||
clientID,
|
||||
issuer,
|
||||
clientSecret,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping,
|
||||
scopes...,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IDPOIDCConfigChangedEvent{
|
||||
ConfigChangedEvent: *event,
|
||||
}, nil
|
||||
}
|
@ -87,7 +87,7 @@ func MemberChangedEventFromExisting(
|
||||
roles ...string,
|
||||
) (*MemberChangedEvent, error) {
|
||||
|
||||
m, err := member.ChangeEventFromExisting(
|
||||
event, err := member.ChangeEventFromExisting(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
MemberChangedEventType,
|
||||
@ -100,7 +100,7 @@ func MemberChangedEventFromExisting(
|
||||
}
|
||||
|
||||
return &MemberChangedEvent{
|
||||
ChangedEvent: *m,
|
||||
ChangedEvent: *event,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -89,9 +89,7 @@ func (rm *ReadModel) Reduce() (err error) {
|
||||
}
|
||||
|
||||
func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error {
|
||||
if err := rm.AppendEvents(events...); err != nil {
|
||||
return err
|
||||
}
|
||||
rm.AppendEvents(events...)
|
||||
return rm.Reduce()
|
||||
}
|
||||
|
||||
|
@ -2,37 +2,10 @@ package idp
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
type ConfigAggregate struct {
|
||||
eventstore.Aggregate
|
||||
|
||||
ConfigID string
|
||||
Type ConfigType
|
||||
Name string
|
||||
StylingType StylingType
|
||||
State ConfigState
|
||||
// OIDCConfig *oidc.ConfigReadModel
|
||||
}
|
||||
|
||||
type ConfigReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
ConfigID string
|
||||
Type ConfigType
|
||||
Name string
|
||||
StylingType StylingType
|
||||
State ConfigState
|
||||
OIDCConfig *oidc.ConfigReadModel
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
rm.ReadModel.AppendEvents(events...)
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) Reduce() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConfigType int32
|
||||
@ -40,19 +13,50 @@ type ConfigType int32
|
||||
const (
|
||||
ConfigTypeOIDC ConfigType = iota
|
||||
ConfigTypeSAML
|
||||
|
||||
//count is for validation
|
||||
configTypeCount
|
||||
)
|
||||
|
||||
func (f ConfigType) Valid() bool {
|
||||
return f >= 0 && f < configTypeCount
|
||||
}
|
||||
|
||||
type ConfigState int32
|
||||
|
||||
const (
|
||||
ConfigStateActive ConfigState = iota
|
||||
ConfigStateInactive
|
||||
ConfigStateRemoved
|
||||
|
||||
configStateCount
|
||||
)
|
||||
|
||||
func (f ConfigState) Valid() bool {
|
||||
return f >= 0 && f < configStateCount
|
||||
}
|
||||
|
||||
type StylingType int32
|
||||
|
||||
const (
|
||||
StylingTypeUnspecified StylingType = iota
|
||||
StylingTypeGoogle
|
||||
StylingTypeGoogle StylingType = iota + 1
|
||||
|
||||
stylingTypeCount
|
||||
)
|
||||
|
||||
func (f StylingType) Valid() bool {
|
||||
return f >= 0 && f < stylingTypeCount
|
||||
}
|
||||
|
||||
type ProviderType int8
|
||||
|
||||
const (
|
||||
ProviderTypeSystem ProviderType = iota
|
||||
ProviderTypeOrg
|
||||
|
||||
providerTypeCount
|
||||
)
|
||||
|
||||
func (f ProviderType) Valid() bool {
|
||||
return f >= 0 && f < providerTypeCount
|
||||
}
|
||||
|
64
internal/v2/repository/idp/config_read_model.go
Normal file
64
internal/v2/repository/idp/config_read_model.go
Normal file
@ -0,0 +1,64 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
type ConfigReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
Type ConfigType
|
||||
|
||||
State ConfigState
|
||||
ConfigID string
|
||||
Name string
|
||||
StylingType StylingType
|
||||
ProviderType ProviderType
|
||||
|
||||
OIDCConfig *oidc.ConfigReadModel
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
rm.ReadModel.AppendEvents(events...)
|
||||
for _, event := range events {
|
||||
switch event.(type) {
|
||||
case *oidc.ConfigAddedEvent:
|
||||
rm.OIDCConfig = &oidc.ConfigReadModel{}
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
case *oidc.ConfigChangedEvent:
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
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 rm.ReadModel.Reduce()
|
||||
}
|
50
internal/v2/repository/idp/config_write_model.go
Normal file
50
internal/v2/repository/idp/config_write_model.go
Normal file
@ -0,0 +1,50 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
type ConfigWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
ConfigID string
|
||||
Name string
|
||||
StylingType StylingType
|
||||
OIDCConfig *oidc.ConfigWriteModel
|
||||
}
|
||||
|
||||
func (rm *ConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
rm.WriteModel.AppendEvents(events...)
|
||||
for _, event := range events {
|
||||
switch event.(type) {
|
||||
case *oidc.ConfigAddedEvent:
|
||||
rm.OIDCConfig = &oidc.ConfigWriteModel{}
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
case *oidc.ConfigChangedEvent:
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *ConfigWriteModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
case *ConfigAddedEvent:
|
||||
rm.ConfigID = e.ConfigID
|
||||
rm.Name = e.Name
|
||||
rm.StylingType = e.StylingType
|
||||
case *ConfigChangedEvent:
|
||||
if e.Name != "" {
|
||||
rm.Name = e.Name
|
||||
}
|
||||
if e.StylingType.Valid() {
|
||||
rm.StylingType = e.StylingType
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := rm.OIDCConfig.Reduce(); err != nil {
|
||||
return err
|
||||
}
|
||||
return rm.WriteModel.Reduce()
|
||||
}
|
@ -1,17 +1,23 @@
|
||||
package idp
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigAddedEvent struct {
|
||||
eventstore.BaseEvent
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"idpConfigId"`
|
||||
ConfigID string `json:"idpConfigId"`
|
||||
Name string `json:"name"`
|
||||
Type ConfigType `json:"idpType,omitempty"`
|
||||
Typ ConfigType `json:"idpType,omitempty"`
|
||||
StylingType StylingType `json:"stylingType,omitempty"`
|
||||
}
|
||||
|
||||
func NewAddedEvent(
|
||||
func NewConfigAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
configID string,
|
||||
name string,
|
||||
@ -21,10 +27,10 @@ func NewAddedEvent(
|
||||
|
||||
return &ConfigAddedEvent{
|
||||
BaseEvent: *base,
|
||||
ID: configID,
|
||||
ConfigID: configID,
|
||||
Name: name,
|
||||
StylingType: stylingType,
|
||||
Type: configType,
|
||||
Typ: configType,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +42,15 @@ func (e *ConfigAddedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
type ConfigType uint32
|
||||
func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
type StylingType uint32
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
@ -1,40 +1,44 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"idpConfigId"`
|
||||
ConfigID string `json:"idpConfigId"`
|
||||
Name string `json:"name,omitempty"`
|
||||
StylingType StylingType `json:"stylingType,omitempty"`
|
||||
|
||||
hasChanged bool
|
||||
}
|
||||
|
||||
func NewConfigChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
current,
|
||||
changed *ConfigAggregate,
|
||||
current *ConfigWriteModel,
|
||||
name string,
|
||||
stylingType StylingType,
|
||||
) (*ConfigChangedEvent, error) {
|
||||
|
||||
change := &ConfigChangedEvent{
|
||||
BaseEvent: *base,
|
||||
ConfigID: current.ConfigID,
|
||||
}
|
||||
hasChanged := false
|
||||
|
||||
if current.Name != name {
|
||||
change.Name = name
|
||||
hasChanged = true
|
||||
}
|
||||
if stylingType != current.StylingType {
|
||||
change.StylingType = stylingType
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if current.ConfigID != changed.ConfigID {
|
||||
change.ID = changed.ConfigID
|
||||
change.hasChanged = true
|
||||
}
|
||||
|
||||
if current.StylingType != changed.StylingType {
|
||||
change.StylingType = changed.StylingType
|
||||
change.hasChanged = true
|
||||
}
|
||||
|
||||
if !change.hasChanged {
|
||||
if !hasChanged {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "IDP-UBJbB", "Errors.NoChanges")
|
||||
}
|
||||
|
||||
@ -46,8 +50,18 @@ func (e *ConfigChangedEvent) CheckPrevious() bool {
|
||||
}
|
||||
|
||||
func (e *ConfigChangedEvent) Data() interface{} {
|
||||
if e.current.Name != e.changed.Name {
|
||||
e.Name = e.changed.Name
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
@ -1,28 +1,47 @@
|
||||
package idp
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
type DeactivatedEvent struct {
|
||||
eventstore.BaseEvent
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
ID string `idpConfigId`
|
||||
type ConfigDeactivatedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ConfigID string `idpConfigId`
|
||||
}
|
||||
|
||||
func NewDeactivatedEvent(
|
||||
func NewConfigDeactivatedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
configID string,
|
||||
) *DeactivatedEvent {
|
||||
) *ConfigDeactivatedEvent {
|
||||
|
||||
return &DeactivatedEvent{
|
||||
return &ConfigDeactivatedEvent{
|
||||
BaseEvent: *base,
|
||||
ID: configID,
|
||||
ConfigID: configID,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DeactivatedEvent) CheckPrevious() bool {
|
||||
func (e *ConfigDeactivatedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *DeactivatedEvent) Data() interface{} {
|
||||
func (e *ConfigDeactivatedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func ConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigDeactivatedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
47
internal/v2/repository/idp/event_config_reactivated.go
Normal file
47
internal/v2/repository/idp/event_config_reactivated.go
Normal file
@ -0,0 +1,47 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigReactivatedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ConfigID string `idpConfigId`
|
||||
}
|
||||
|
||||
func NewConfigReactivatedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
configID string,
|
||||
) *ConfigReactivatedEvent {
|
||||
|
||||
return &ConfigReactivatedEvent{
|
||||
BaseEvent: *base,
|
||||
ConfigID: configID,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ConfigReactivatedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *ConfigReactivatedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func ConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigReactivatedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
47
internal/v2/repository/idp/event_config_removed.go
Normal file
47
internal/v2/repository/idp/event_config_removed.go
Normal file
@ -0,0 +1,47 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigRemovedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ConfigID string `idpConfigId`
|
||||
}
|
||||
|
||||
func NewConfigRemovedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
configID string,
|
||||
) *ConfigRemovedEvent {
|
||||
|
||||
return &ConfigRemovedEvent{
|
||||
BaseEvent: *base,
|
||||
ConfigID: configID,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ConfigRemovedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *ConfigRemovedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func ConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigRemovedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package oidc
|
||||
|
||||
import "github.com/caos/zitadel/internal/crypto"
|
||||
|
||||
type AddedEvent struct {
|
||||
eventstore.BaseEvent
|
||||
|
||||
IDPConfigID string `json:"idpConfigId"`
|
||||
ClientID string `json:"clientId"`
|
||||
Secret *crypto.CryptoValue `json:"clientSecret"`
|
||||
Issuer string `json:"issuer"`
|
||||
Scopes []string `json:"scpoes"`
|
||||
IDPDisplayNameMapping int32 `json:"idpDisplayNameMapping,omitempty"`
|
||||
UsernameMapping int32 `json:"usernameMapping,omitempty"`
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package oidc
|
||||
|
||||
type ChangedEvent struct{}
|
@ -1,35 +0,0 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
)
|
||||
|
||||
type ConfigReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
IDPConfigID string
|
||||
ClientID string
|
||||
ClientSecret *crypto.CryptoValue
|
||||
ClientSecretString string
|
||||
Issuer string
|
||||
Scopes []string
|
||||
IDPDisplayNameMapping MappingField
|
||||
UsernameMapping MappingField
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
rm.ReadModel.AppendEvents(events...)
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) Reduce() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type MappingField int32
|
||||
|
||||
const (
|
||||
OIDCMappingFieldUnspecified MappingField = iota
|
||||
OIDCMappingFieldPreferredLoginName
|
||||
OIDCMappingFieldEmail
|
||||
)
|
51
internal/v2/repository/idp/oidc/config_read_model.go
Normal file
51
internal/v2/repository/idp/oidc/config_read_model.go
Normal file
@ -0,0 +1,51 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
)
|
||||
|
||||
type ConfigReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
IDPConfigID string
|
||||
ClientID string
|
||||
ClientSecret *crypto.CryptoValue
|
||||
Issuer string
|
||||
Scopes []string
|
||||
IDPDisplayNameMapping MappingField
|
||||
UserNameMapping MappingField
|
||||
}
|
||||
|
||||
func (rm *ConfigReadModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
case *ConfigAddedEvent:
|
||||
rm.IDPConfigID = e.IDPConfigID
|
||||
rm.ClientID = e.ClientID
|
||||
rm.ClientSecret = e.ClientSecret
|
||||
rm.Issuer = e.Issuer
|
||||
rm.Scopes = e.Scopes
|
||||
rm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
rm.UserNameMapping = e.UserNameMapping
|
||||
case *ConfigChangedEvent:
|
||||
if e.ClientID != "" {
|
||||
rm.ClientID = e.ClientID
|
||||
}
|
||||
if e.Issuer != "" {
|
||||
rm.Issuer = e.Issuer
|
||||
}
|
||||
if len(e.Scopes) > 0 {
|
||||
rm.Scopes = e.Scopes
|
||||
}
|
||||
if e.IDPDisplayNameMapping.Valid() {
|
||||
rm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
}
|
||||
if e.UserNameMapping.Valid() {
|
||||
rm.UserNameMapping = e.UserNameMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rm.ReadModel.Reduce()
|
||||
}
|
52
internal/v2/repository/idp/oidc/config_write_model.go
Normal file
52
internal/v2/repository/idp/oidc/config_write_model.go
Normal file
@ -0,0 +1,52 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
)
|
||||
|
||||
type ConfigWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
IDPConfigID string
|
||||
ClientID string
|
||||
ClientSecret *crypto.CryptoValue
|
||||
Issuer string
|
||||
Scopes []string
|
||||
|
||||
IDPDisplayNameMapping MappingField
|
||||
UserNameMapping MappingField
|
||||
}
|
||||
|
||||
func (wm *ConfigWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *ConfigAddedEvent:
|
||||
wm.IDPConfigID = e.IDPConfigID
|
||||
wm.ClientID = e.ClientID
|
||||
wm.ClientSecret = e.ClientSecret
|
||||
wm.Issuer = e.Issuer
|
||||
wm.Scopes = e.Scopes
|
||||
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
wm.UserNameMapping = e.UserNameMapping
|
||||
case *ConfigChangedEvent:
|
||||
if e.ClientID != "" {
|
||||
wm.ClientID = e.ClientID
|
||||
}
|
||||
if e.Issuer != "" {
|
||||
wm.Issuer = e.Issuer
|
||||
}
|
||||
if len(e.Scopes) > 0 {
|
||||
wm.Scopes = e.Scopes
|
||||
}
|
||||
if e.IDPDisplayNameMapping.Valid() {
|
||||
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
}
|
||||
if e.UserNameMapping.Valid() {
|
||||
wm.UserNameMapping = e.UserNameMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package oidc
|
||||
|
||||
type DeactivatedEvent struct{}
|
67
internal/v2/repository/idp/oidc/event_added.go
Normal file
67
internal/v2/repository/idp/oidc/event_added.go
Normal file
@ -0,0 +1,67 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigAddedEvent struct {
|
||||
eventstore.BaseEvent
|
||||
|
||||
IDPConfigID string `json:"idpConfigId"`
|
||||
ClientID string `json:"clientId"`
|
||||
ClientSecret *crypto.CryptoValue `json:"clientSecret"`
|
||||
Issuer string `json:"issuer"`
|
||||
Scopes []string `json:"scpoes"`
|
||||
|
||||
IDPDisplayNameMapping MappingField `json:"idpDisplayNameMapping"`
|
||||
UserNameMapping MappingField `json:"usernameMapping"`
|
||||
}
|
||||
|
||||
func (e *ConfigAddedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *ConfigAddedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func NewConfigAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
clientID,
|
||||
idpConfigID,
|
||||
issuer string,
|
||||
clientSecret *crypto.CryptoValue,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping MappingField,
|
||||
scopes ...string,
|
||||
) *ConfigAddedEvent {
|
||||
|
||||
return &ConfigAddedEvent{
|
||||
BaseEvent: *base,
|
||||
IDPConfigID: idpConfigID,
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Issuer: issuer,
|
||||
Scopes: scopes,
|
||||
IDPDisplayNameMapping: idpDisplayNameMapping,
|
||||
UserNameMapping: userNameMapping,
|
||||
}
|
||||
}
|
||||
|
||||
func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
105
internal/v2/repository/idp/oidc/event_changed.go
Normal file
105
internal/v2/repository/idp/oidc/event_changed.go
Normal file
@ -0,0 +1,105 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
type ConfigChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
IDPConfigID string `json:"idpConfigId"`
|
||||
|
||||
ClientID string `json:"clientId"`
|
||||
ClientSecret *crypto.CryptoValue `json:"clientSecret"`
|
||||
Issuer string `json:"issuer"`
|
||||
Scopes []string `json:"scpoes"`
|
||||
|
||||
IDPDisplayNameMapping MappingField `json:"idpDisplayNameMapping"`
|
||||
UserNameMapping MappingField `json:"usernameMapping"`
|
||||
}
|
||||
|
||||
func (e *ConfigChangedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *ConfigChangedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func NewConfigChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
current *ConfigWriteModel,
|
||||
clientID,
|
||||
issuer string,
|
||||
clientSecret *crypto.CryptoValue,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping MappingField,
|
||||
scopes ...string,
|
||||
) (*ConfigChangedEvent, error) {
|
||||
|
||||
event := &ConfigChangedEvent{
|
||||
BaseEvent: *base,
|
||||
IDPConfigID: current.IDPConfigID,
|
||||
}
|
||||
hasChanged := false
|
||||
|
||||
if clientID != "" && clientID != current.ClientID {
|
||||
event.ClientID = clientID
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if issuer != "" && issuer != current.Issuer {
|
||||
event.Issuer = issuer
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if clientSecret != nil && clientSecret != current.ClientSecret {
|
||||
event.ClientSecret = clientSecret
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if idpDisplayNameMapping.Valid() && idpDisplayNameMapping != current.IDPDisplayNameMapping {
|
||||
event.IDPDisplayNameMapping = idpDisplayNameMapping
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if userNameMapping.Valid() && userNameMapping != current.UserNameMapping {
|
||||
event.UserNameMapping = userNameMapping
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if len(scopes) > 0 {
|
||||
sort.Strings(scopes)
|
||||
sort.Strings(current.Scopes)
|
||||
if !reflect.DeepEqual(scopes, current.Scopes) {
|
||||
event.Scopes = scopes
|
||||
hasChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasChanged {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "OIDC-zPDOL", "Errors.NoChanges")
|
||||
}
|
||||
|
||||
return event, nil
|
||||
}
|
||||
|
||||
func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
e := &ConfigChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(event.Data, e)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event")
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
14
internal/v2/repository/idp/oidc/mapping_field.go
Normal file
14
internal/v2/repository/idp/oidc/mapping_field.go
Normal file
@ -0,0 +1,14 @@
|
||||
package oidc
|
||||
|
||||
type MappingField int32
|
||||
|
||||
const (
|
||||
MappingFieldPreferredLoginName MappingField = iota + 1
|
||||
MappingFieldEmail
|
||||
// count is for validation purposes
|
||||
mappingFieldCount
|
||||
)
|
||||
|
||||
func (f MappingField) Valid() bool {
|
||||
return f > 0 && f < mappingFieldCount
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package oidc
|
||||
|
||||
type RemovedEvent struct{}
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
es_repo "github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -40,7 +40,7 @@ func NewAddedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
func AddedEventMapper(event *es_repo.Event) (eventstore.EventReader, error) {
|
||||
e := &AddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ type ChangedEvent struct {
|
||||
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
UserID string `json:"userId,omitempty"`
|
||||
|
||||
hasChanged bool
|
||||
}
|
||||
|
||||
func (e *ChangedEvent) CheckPrevious() bool {
|
||||
@ -38,15 +36,16 @@ func ChangeEventFromExisting(
|
||||
) (*ChangedEvent, error) {
|
||||
|
||||
change := NewChangedEvent(base, current.userID)
|
||||
hasChanged := false
|
||||
|
||||
sort.Strings(current.Roles)
|
||||
sort.Strings(roles)
|
||||
if !reflect.DeepEqual(current.Roles, roles) {
|
||||
change.Roles = roles
|
||||
change.hasChanged = true
|
||||
hasChanged = true
|
||||
}
|
||||
|
||||
if !change.hasChanged {
|
||||
if !hasChanged {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "MEMBE-SeKlD", "Errors.NoChanges")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user