mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-19 14:27:32 +00:00
191 lines
6.2 KiB
Go
191 lines
6.2 KiB
Go
|
package eventsourcing
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"github.com/caos/zitadel/internal/cache/config"
|
||
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||
|
es_int "github.com/caos/zitadel/internal/eventstore"
|
||
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||
|
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||
|
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||
|
)
|
||
|
|
||
|
type IamEventstore struct {
|
||
|
es_int.Eventstore
|
||
|
iamCache *IamCache
|
||
|
}
|
||
|
|
||
|
type IamConfig struct {
|
||
|
es_int.Eventstore
|
||
|
Cache *config.CacheConfig
|
||
|
}
|
||
|
|
||
|
func StartIam(conf IamConfig, systemDefaults sd.SystemDefaults) (*IamEventstore, error) {
|
||
|
iamCache, err := StartCache(conf.Cache)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &IamEventstore{
|
||
|
Eventstore: conf.Eventstore,
|
||
|
iamCache: iamCache,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) IamByID(ctx context.Context, id string) (*iam_model.Iam, error) {
|
||
|
iam := es.iamCache.getIam(id)
|
||
|
|
||
|
query, err := IamByIDQuery(iam.AggregateID, iam.Sequence)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
err = es_sdk.Filter(ctx, es.FilterEvents, iam.AppendEvents, query)
|
||
|
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||
|
return nil, err
|
||
|
}
|
||
|
es.iamCache.cacheIam(iam)
|
||
|
return model.IamToModel(iam), nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) StartSetup(ctx context.Context, iamID string) (*iam_model.Iam, error) {
|
||
|
iam, err := es.IamByID(ctx, iamID)
|
||
|
if err != nil && !caos_errs.IsNotFound(err) {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if iam != nil && iam.SetUpStarted {
|
||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started")
|
||
|
}
|
||
|
|
||
|
repoIam := &model.Iam{ObjectRoot: models.ObjectRoot{AggregateID: iamID}}
|
||
|
createAggregate := IamSetupStartedAggregate(es.AggregateCreator(), repoIam)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
return model.IamToModel(repoIam), nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) SetupDone(ctx context.Context, iamID string) (*iam_model.Iam, error) {
|
||
|
iam, err := es.IamByID(ctx, iamID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
repoIam := model.IamFromModel(iam)
|
||
|
createAggregate := IamSetupDoneAggregate(es.AggregateCreator(), repoIam)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
return model.IamToModel(repoIam), nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) SetGlobalOrg(ctx context.Context, iamID, globalOrg string) (*iam_model.Iam, error) {
|
||
|
iam, err := es.IamByID(ctx, iamID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
repoIam := model.IamFromModel(iam)
|
||
|
createAggregate := IamSetGlobalOrgAggregate(es.AggregateCreator(), repoIam, globalOrg)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
return model.IamToModel(repoIam), nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) SetIamProject(ctx context.Context, iamID, iamProjectID string) (*iam_model.Iam, error) {
|
||
|
iam, err := es.IamByID(ctx, iamID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
repoIam := model.IamFromModel(iam)
|
||
|
createAggregate := IamSetIamProjectAggregate(es.AggregateCreator(), repoIam, iamProjectID)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
return model.IamToModel(repoIam), nil
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) AddIamMember(ctx context.Context, member *iam_model.IamMember) (*iam_model.IamMember, error) {
|
||
|
if !member.IsValid() {
|
||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-89osr", "UserID and Roles are required")
|
||
|
}
|
||
|
existing, err := es.IamByID(ctx, member.AggregateID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if _, m := existing.GetMember(member.UserID); m != nil {
|
||
|
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "User is already member of this Iam")
|
||
|
}
|
||
|
repoIam := model.IamFromModel(existing)
|
||
|
repoMember := model.IamMemberFromModel(member)
|
||
|
|
||
|
addAggregate := IamMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
|
||
|
if _, m := model.GetIamMember(repoIam.Members, member.UserID); m != nil {
|
||
|
return model.IamMemberToModel(m), nil
|
||
|
}
|
||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-s90pw", "Could not find member in list")
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) ChangeIamMember(ctx context.Context, member *iam_model.IamMember) (*iam_model.IamMember, error) {
|
||
|
if !member.IsValid() {
|
||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-s9ipe", "UserID and Roles are required")
|
||
|
}
|
||
|
existing, err := es.IamByID(ctx, member.AggregateID)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if _, m := existing.GetMember(member.UserID); m == nil {
|
||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-s7ucs", "User is not member of this project")
|
||
|
}
|
||
|
repoIam := model.IamFromModel(existing)
|
||
|
repoMember := model.IamMemberFromModel(member)
|
||
|
|
||
|
projectAggregate := IamMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate)
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
|
||
|
if _, m := model.GetIamMember(repoIam.Members, member.UserID); m != nil {
|
||
|
return model.IamMemberToModel(m), nil
|
||
|
}
|
||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-29cws", "Could not find member in list")
|
||
|
}
|
||
|
|
||
|
func (es *IamEventstore) RemoveIamMember(ctx context.Context, member *iam_model.IamMember) error {
|
||
|
if member.UserID == "" {
|
||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-0pors", "UserID and Roles are required")
|
||
|
}
|
||
|
existing, err := es.IamByID(ctx, member.AggregateID)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if _, m := existing.GetMember(member.UserID); m == nil {
|
||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-29skr", "User is not member of this project")
|
||
|
}
|
||
|
repoIam := model.IamFromModel(existing)
|
||
|
repoMember := model.IamMemberFromModel(member)
|
||
|
|
||
|
projectAggregate := IamMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember)
|
||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate)
|
||
|
es.iamCache.cacheIam(repoIam)
|
||
|
return err
|
||
|
}
|