mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
try with writemodel
This commit is contained in:
parent
147782332f
commit
4d6497f6c1
@ -115,3 +115,7 @@ func readModelToMember(readModel *member.ReadModel) *model.IAMMember {
|
||||
UserID: readModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelFromMember(member *model.IAMMember) *member.WriteModel {
|
||||
return &member.WriteModel{}
|
||||
}
|
||||
|
@ -54,13 +54,13 @@ func (r *Repository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMM
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, currentMember := iam.Members.MemberByUserID(member.UserID)
|
||||
if currentMember == nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-GPhuz", "Errors.IAM.MemberNotExisting")
|
||||
existingMember, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromReadModel(iam).
|
||||
PushEvents(iam_repo.NewMemberChangedEvent(ctx, member.UserID, member.Roles...))
|
||||
PushMemberChanged(ctx, existingMember, nil)
|
||||
|
||||
events, err := r.eventstore.PushAggregates(ctx, iamAgg)
|
||||
if err != nil {
|
||||
|
@ -3,10 +3,12 @@ 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"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/member"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
@ -46,3 +48,52 @@ 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) }()
|
||||
|
||||
query := eventstore.NewSearchQueryFactory(eventstore.ColumnsEvent, iam_repo.AggregateType).AggregateIDs(iamID)
|
||||
|
||||
writeModel := new(memberWriteModel)
|
||||
err = r.eventstore.FilterToReducer(ctx, query, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if writeModel.isDeleted {
|
||||
return nil, errors.ThrowNotFound(nil, "IAM-D8JxR", "Errors.NotFound")
|
||||
}
|
||||
|
||||
return &writeModel.MemberWriteModel, nil
|
||||
}
|
||||
|
||||
type memberWriteModel struct {
|
||||
iam_repo.MemberWriteModel
|
||||
|
||||
userID string
|
||||
isDeleted bool
|
||||
}
|
||||
|
||||
func (wm *memberWriteModel) AppendEvents(events ...eventstore.EventReader) error {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *member.AddedEvent:
|
||||
if e.UserID == wm.userID {
|
||||
wm.isDeleted = false
|
||||
wm.MemberWriteModel.AppendEvents(event)
|
||||
}
|
||||
case *member.ChangedEvent:
|
||||
if e.UserID == wm.userID {
|
||||
wm.MemberWriteModel.AppendEvents(event)
|
||||
}
|
||||
case *member.RemovedEvent:
|
||||
if e.UserID == wm.userID {
|
||||
wm.isDeleted = true
|
||||
wm.MemberWriteModel = iam_repo.MemberWriteModel{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package iam
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
)
|
||||
|
||||
@ -29,7 +30,13 @@ func NewAggregate(
|
||||
) *Aggregate {
|
||||
|
||||
return &Aggregate{
|
||||
Aggregate: *eventstore.NewAggregate(id, AggregateType, resourceOwner, AggregateVersion, previousSequence),
|
||||
Aggregate: *eventstore.NewAggregate(
|
||||
id,
|
||||
AggregateType,
|
||||
resourceOwner,
|
||||
AggregateVersion,
|
||||
previousSequence,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,8 +53,14 @@ func (a *Aggregate) PushMemberAdded(ctx context.Context, userID string, roles ..
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Aggregate) PushMemberChanged(ctx context.Context, userID string, roles ...string) *Aggregate {
|
||||
a.Aggregate = *a.PushEvents(NewMemberChangedEvent(ctx, userID, roles...))
|
||||
func (a *Aggregate) PushMemberChanged(ctx context.Context, current, changed *MemberWriteModel) *Aggregate {
|
||||
e, err := NewMemberChangedEvent(ctx, current, changed)
|
||||
if err != nil {
|
||||
logging.Log("IAM-KH21C").OnError(err).Warn("unable to push member changed")
|
||||
return a
|
||||
}
|
||||
|
||||
a.Aggregate = *a.PushEvents(e)
|
||||
return a
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,13 @@ var (
|
||||
MemberRemovedEventType = iamEventTypePrefix + member.RemovedEventType
|
||||
)
|
||||
|
||||
type MemberReadModel member.ReadModel
|
||||
type MemberWriteModel struct {
|
||||
member.WriteModel
|
||||
}
|
||||
|
||||
type MemberReadModel struct {
|
||||
member.ReadModel
|
||||
}
|
||||
|
||||
func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) (err error) {
|
||||
for _, event := range events {
|
||||
@ -60,20 +66,25 @@ func NewMemberAddedEvent(
|
||||
|
||||
func NewMemberChangedEvent(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
roles ...string,
|
||||
) *MemberChangedEvent {
|
||||
current,
|
||||
changed *MemberWriteModel,
|
||||
) (*MemberChangedEvent, error) {
|
||||
|
||||
m, err := member.NewChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
MemberChangedEventType,
|
||||
),
|
||||
¤t.WriteModel,
|
||||
&changed.WriteModel,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MemberChangedEvent{
|
||||
ChangedEvent: *member.NewChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
MemberChangedEventType,
|
||||
),
|
||||
userID,
|
||||
roles...,
|
||||
),
|
||||
}
|
||||
ChangedEvent: *m,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMemberRemovedEvent(
|
||||
|
@ -2,30 +2,40 @@ package idp
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
|
||||
type AddedEvent struct {
|
||||
type ConfigAddedEvent struct {
|
||||
eventstore.BaseEvent
|
||||
|
||||
ID string `idpConfigId`
|
||||
Name string `name`
|
||||
ID string `json:"idpConfigId"`
|
||||
Name string `json:"name"`
|
||||
Type ConfigType `json:"idpType,omitempty"`
|
||||
StylingType StylingType `json:"stylingType,omitempty"`
|
||||
}
|
||||
|
||||
func NewAddedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
configID string,
|
||||
name string,
|
||||
) *AddedEvent {
|
||||
configType ConfigType,
|
||||
stylingType StylingType,
|
||||
) *ConfigAddedEvent {
|
||||
|
||||
return &AddedEvent{
|
||||
BaseEvent: *base,
|
||||
ID: configID,
|
||||
Name: name,
|
||||
return &ConfigAddedEvent{
|
||||
BaseEvent: *base,
|
||||
ID: configID,
|
||||
Name: name,
|
||||
StylingType: stylingType,
|
||||
Type: configType,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *AddedEvent) CheckPrevious() bool {
|
||||
func (e *ConfigAddedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *AddedEvent) Data() interface{} {
|
||||
func (e *ConfigAddedEvent) Data() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
type ConfigType uint32
|
||||
|
||||
type StylingType uint32
|
||||
|
@ -1,35 +1,51 @@
|
||||
package idp
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
)
|
||||
|
||||
type ChangedEdvent struct {
|
||||
type ConfigChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
current *ConfigAggregate
|
||||
changed *ConfigAggregate
|
||||
ID string `json:"idpConfigId"`
|
||||
StylingType StylingType `json:"stylingType,omitempty"`
|
||||
|
||||
Name string `json:"name"`
|
||||
hasChanged bool
|
||||
}
|
||||
|
||||
func ChangedEvent(
|
||||
func NewConfigChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
current *ConfigAggregate,
|
||||
changed *ConfigAggregate,
|
||||
) (*ChangedEdvent, error) {
|
||||
//TODO: who to handle chanes?
|
||||
) (*ConfigChangedEvent, error) {
|
||||
|
||||
return &ChangedEdvent{
|
||||
change := &ConfigChangedEvent{
|
||||
BaseEvent: *base,
|
||||
current: current,
|
||||
changed: changed,
|
||||
}, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "IDP-UBJbB", "Errors.NoChanges")
|
||||
}
|
||||
|
||||
return change, nil
|
||||
}
|
||||
|
||||
func (e *ChangedEdvent) CheckPrevious() bool {
|
||||
func (e *ConfigChangedEvent) CheckPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *ChangedEdvent) Data() interface{} {
|
||||
func (e *ConfigChangedEvent) Data() interface{} {
|
||||
if e.current.Name != e.changed.Name {
|
||||
e.Name = e.changed.Name
|
||||
}
|
||||
|
@ -1,3 +1,15 @@
|
||||
package oidc
|
||||
|
||||
type AddedEvent struct{}
|
||||
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"`
|
||||
}
|
||||
|
@ -9,8 +9,10 @@ type Aggregate struct {
|
||||
Roles []string
|
||||
}
|
||||
|
||||
func NewMemberAggregate(userID string) *ReadModel {
|
||||
return &ReadModel{
|
||||
ReadModel: *eventstore.NewReadModel(),
|
||||
func NewAggregate(aggregate *eventstore.Aggregate, userID string, roles ...string) *Aggregate {
|
||||
return &Aggregate{
|
||||
Aggregate: *aggregate,
|
||||
Roles: roles,
|
||||
UserID: userID,
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package member
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
@ -15,8 +17,10 @@ const (
|
||||
type ChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Roles []string `json:"roles"`
|
||||
UserID string `json:"userId"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
UserID string `json:"userId,omitempty"`
|
||||
|
||||
hasChanged bool
|
||||
}
|
||||
|
||||
func (e *ChangedEvent) CheckPrevious() bool {
|
||||
@ -29,15 +33,32 @@ func (e *ChangedEvent) Data() interface{} {
|
||||
|
||||
func NewChangedEvent(
|
||||
base *eventstore.BaseEvent,
|
||||
userID string,
|
||||
roles ...string,
|
||||
) *ChangedEvent {
|
||||
current,
|
||||
changed *WriteModel,
|
||||
) (*ChangedEvent, error) {
|
||||
|
||||
return &ChangedEvent{
|
||||
change := &ChangedEvent{
|
||||
BaseEvent: *base,
|
||||
Roles: roles,
|
||||
UserID: userID,
|
||||
}
|
||||
|
||||
if current.UserID != changed.UserID {
|
||||
change.UserID = changed.UserID
|
||||
change.hasChanged = true
|
||||
}
|
||||
|
||||
sort.Strings(current.Roles)
|
||||
sort.Strings(changed.Roles)
|
||||
if !reflect.DeepEqual(current.Roles, changed.Roles) {
|
||||
change.Roles = changed.Roles
|
||||
change.hasChanged = true
|
||||
}
|
||||
|
||||
if !change.hasChanged {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "MEMBE-SeKlD", "Errors.NoChanges")
|
||||
}
|
||||
|
||||
return change, nil
|
||||
|
||||
}
|
||||
|
||||
func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
|
||||
|
@ -2,6 +2,8 @@ package member
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
|
||||
//ReadModel represenets the default member view.
|
||||
// It's computed from events.
|
||||
type ReadModel struct {
|
||||
eventstore.ReadModel
|
||||
|
||||
@ -9,6 +11,7 @@ type ReadModel struct {
|
||||
Roles []string
|
||||
}
|
||||
|
||||
//NewMemberReadModel is the default constructor of ReadModel
|
||||
func NewMemberReadModel(userID string) *ReadModel {
|
||||
return &ReadModel{
|
||||
ReadModel: *eventstore.NewReadModel(),
|
||||
@ -16,6 +19,7 @@ func NewMemberReadModel(userID string) *ReadModel {
|
||||
}
|
||||
}
|
||||
|
||||
//Reduce extends eventstore.ReadModel
|
||||
func (rm *ReadModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
@ -29,3 +33,7 @@ func (rm *ReadModel) Reduce() error {
|
||||
}
|
||||
return rm.ReadModel.Reduce()
|
||||
}
|
||||
|
||||
//WriteModel is used to create events
|
||||
// It has no computed fields and represents the data
|
||||
type WriteModel ReadModel
|
||||
|
@ -18,6 +18,19 @@ var (
|
||||
MemberRemovedEventType = orgEventTypePrefix + member.RemovedEventType
|
||||
)
|
||||
|
||||
type MemberWriteModel struct {
|
||||
member.WriteModel
|
||||
}
|
||||
|
||||
// func NewMemberAggregate(userID string) *MemberAggregate {
|
||||
// return &MemberAggregate{
|
||||
// Aggregate: member.NewAggregate(
|
||||
// eventstore.NewAggregate(userID, MemberAggregateType, "RO", AggregateVersion, 0),
|
||||
// ),
|
||||
// // Aggregate: member.NewMemberAggregate(userID),
|
||||
// }
|
||||
// }
|
||||
|
||||
type MembersReadModel struct {
|
||||
members.ReadModel
|
||||
}
|
||||
@ -81,20 +94,24 @@ func NewMemberAddedEvent(
|
||||
|
||||
func NewMemberChangedEvent(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
roles ...string,
|
||||
) *MemberChangedEvent {
|
||||
current,
|
||||
changed *MemberWriteModel,
|
||||
) (*MemberChangedEvent, error) {
|
||||
|
||||
return &MemberChangedEvent{
|
||||
ChangedEvent: *member.NewChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
MemberChangedEventType,
|
||||
),
|
||||
userID,
|
||||
roles...,
|
||||
event, err := member.NewChangedEvent(
|
||||
eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
MemberChangedEventType,
|
||||
),
|
||||
¤t.WriteModel,
|
||||
&changed.WriteModel,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &MemberChangedEvent{
|
||||
ChangedEvent: *event,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewMemberRemovedEvent(
|
||||
|
Loading…
Reference in New Issue
Block a user