zitadel/internal/iam/repository/eventsourcing/eventstore.go

191 lines
6.2 KiB
Go
Raw Normal View History

feat: setup and iam commands (#99) * start org * refactor(eventstore): filter in sql for querier * feat(eventstore): Aggregate precondition preconditions are checked right before insert. Insert is still transaction save * feat(eventstore): check preconditions in repository * test(eventstore): test precondition in models * test(eventstore): precondition-tests * start org * refactor(eventstore): filter in sql for querier * feat(eventstore): Aggregate precondition preconditions are checked right before insert. Insert is still transaction save * feat(admin): start implement org * feat(eventstore): check preconditions in repository * fix(eventstore): data as NULL if empty refactor(eventstore): naming in sequence methods * feat(admin): org command side * feat(management): start org-repo * feat(org): member * fix: replace ObjectRoot.ID with ObjectRoot.AggregateID * aggregateID * add remove,change member * refactor(org): namings * refactor(eventstore): querier as type * fix(precondition): rename validation from precondition to validation * test(eventstore): isErr func instead of wantErr bool * fix(tests): Data * fix(eventstore): correct check for existing events in push, simplify insert statement * fix(eventstore): aggregate id public * test(org): eventsourcing * test(org): eventstore * test(org): deactivate, reactivate, orgbyid * test(org): getMemberByIDs * tests * running tests * add config * add user repo to admin * thorw not found if no org found * iam setup * eventstore tests done * setup iam * lauft * iam eventstore * validate if user is already member of org * modules * delete unused file * iam member * add member validation test * iam member * return error if unable to validat member * generate org id once, set resourceowner of org * start iam repo * set resourceowner on unique aggregates * setup user const * better code * generate files * fix tests * Update internal/admin/repository/eventsourcing/repository.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> * set ctx data Co-authored-by: adlerhurst <silvan.reusser@gmail.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com>
2020-05-18 09:32:16 +00:00
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
}