feat: handle instanceID in projections (#3442)

* feat: handle instanceID in projections

* rename functions

* fix key lock

* fix import
This commit is contained in:
Livio Amstutz
2022-04-19 08:26:12 +02:00
committed by GitHub
parent c25d853820
commit 1305c14e49
120 changed files with 2078 additions and 1209 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/domain"
@@ -30,7 +31,7 @@ type TokenVerifierRepo struct {
}
func (repo *TokenVerifierRepo) tokenByID(ctx context.Context, tokenID, userID string) (*usr_model.TokenView, error) {
token, viewErr := repo.View.TokenByID(tokenID)
token, viewErr := repo.View.TokenByID(tokenID, authz.GetInstance(ctx).InstanceID())
if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
return nil, viewErr
}
@@ -40,7 +41,7 @@ func (repo *TokenVerifierRepo) tokenByID(ctx context.Context, tokenID, userID st
token.UserID = userID
}
events, esErr := repo.getUserEvents(ctx, userID, token.Sequence)
events, esErr := repo.getUserEvents(ctx, userID, token.InstanceID, token.Sequence)
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4T90g", "Errors.Token.NotFound")
}
@@ -251,8 +252,8 @@ func (repo *TokenVerifierRepo) VerifierClientID(ctx context.Context, appName str
return clientID, app.ProjectID, nil
}
func (r *TokenVerifierRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
query, err := usr_view.UserByIDQuery(userID, sequence)
func (r *TokenVerifierRepo) getUserEvents(ctx context.Context, userID, instanceID string, sequence uint64) ([]*models.Event, error) {
query, err := usr_view.UserByIDQuery(userID, instanceID, sequence)
if err != nil {
return nil, err
}

View File

@@ -68,8 +68,8 @@ func (_ *UserMembership) AggregateTypes() []es_models.AggregateType {
return []es_models.AggregateType{instance.AggregateType, org.AggregateType, project.AggregateType, user.AggregateType}
}
func (m *UserMembership) CurrentSequence() (uint64, error) {
sequence, err := m.view.GetLatestUserMembershipSequence()
func (m *UserMembership) CurrentSequence(instanceID string) (uint64, error) {
sequence, err := m.view.GetLatestUserMembershipSequence(instanceID)
if err != nil {
return 0, err
}
@@ -77,13 +77,29 @@ func (m *UserMembership) CurrentSequence() (uint64, error) {
}
func (m *UserMembership) EventQuery() (*es_models.SearchQuery, error) {
sequence, err := m.view.GetLatestUserMembershipSequence()
sequences, err := m.view.GetLatestUserMembershipSequences()
if err != nil {
return nil, err
}
return es_models.NewSearchQuery().
query := es_models.NewSearchQuery()
instances := make([]string, 0)
for _, sequence := range sequences {
for _, instance := range instances {
if sequence.InstanceID == instance {
break
}
}
instances = append(instances, sequence.InstanceID)
query.AddQuery().
AggregateTypeFilter(m.AggregateTypes()...).
LatestSequenceFilter(sequence.CurrentSequence).
InstanceIDFilter(sequence.InstanceID)
}
return query.AddQuery().
AggregateTypeFilter(m.AggregateTypes()...).
LatestSequenceFilter(sequence.CurrentSequence), nil
LatestSequenceFilter(0).
ExcludedInstanceIDsFilter(instances...).
SearchQuery(), nil
}
func (m *UserMembership) Reduce(event *es_models.Event) (err error) {
@@ -110,14 +126,14 @@ func (m *UserMembership) processIAM(event *es_models.Event) (err error) {
case instance.MemberAddedEventType:
m.fillIamDisplayName(member)
case instance.MemberChangedEventType:
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam)
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeIam)
if err != nil {
return err
}
err = member.AppendEvent(event)
case instance.MemberRemovedEventType,
instance.MemberCascadeRemovedEventType:
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam, event)
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeIam, event)
default:
return m.view.ProcessedUserMembershipSequence(event)
}
@@ -142,14 +158,14 @@ func (m *UserMembership) processOrg(event *es_models.Event) (err error) {
case org.MemberAddedEventType:
err = m.fillOrgName(member)
case org.MemberChangedEventType:
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation)
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeOrganisation)
if err != nil {
return err
}
err = member.AppendEvent(event)
case org.MemberRemovedEventType,
org.MemberCascadeRemovedEventType:
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation, event)
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeOrganisation, event)
case org.OrgChangedEventType:
return m.updateOrgName(event)
default:
@@ -179,7 +195,7 @@ func (m *UserMembership) updateOrgName(event *es_models.Event) error {
return err
}
memberships, err := m.view.UserMembershipsByResourceOwner(event.ResourceOwner)
memberships, err := m.view.UserMembershipsByResourceOwner(event.ResourceOwner, event.InstanceID)
if err != nil {
return err
}
@@ -206,28 +222,28 @@ func (m *UserMembership) processProject(event *es_models.Event) (err error) {
}
err = m.fillOrgName(member)
case project.MemberChangedType:
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject)
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeProject)
if err != nil {
return err
}
err = member.AppendEvent(event)
case project.MemberRemovedType, project.MemberCascadeRemovedType:
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject, event)
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, event.InstanceID, usr_model.MemberTypeProject, event)
case project.GrantMemberChangedType:
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant)
member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, member.ObjectID, event.InstanceID, usr_model.MemberTypeProjectGrant)
if err != nil {
return err
}
err = member.AppendEvent(event)
case project.GrantMemberRemovedType,
project.GrantMemberCascadeRemovedType:
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant, event)
return m.view.DeleteUserMembership(member.UserID, event.AggregateID, member.ObjectID, member.InstanceID, usr_model.MemberTypeProjectGrant, event)
case project.ProjectChangedType:
return m.updateProjectDisplayName(event)
case project.ProjectRemovedType:
return m.view.DeleteUserMembershipsByAggregateID(event.AggregateID, event)
return m.view.DeleteUserMembershipsByAggregateID(event.AggregateID, event.InstanceID, event)
case project.GrantRemovedType:
return m.view.DeleteUserMembershipsByAggregateIDAndObjectID(event.AggregateID, member.ObjectID, event)
return m.view.DeleteUserMembershipsByAggregateIDAndObjectID(event.AggregateID, member.ObjectID, member.InstanceID, event)
default:
return m.view.ProcessedUserMembershipSequence(event)
}
@@ -238,7 +254,7 @@ func (m *UserMembership) processProject(event *es_models.Event) (err error) {
}
func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) {
project, err := m.getProjectByID(context.Background(), member.AggregateID)
project, err := m.getProjectByID(context.Background(), member.AggregateID, member.InstanceID)
if err != nil {
return err
}
@@ -256,7 +272,7 @@ func (m *UserMembership) updateProjectDisplayName(event *es_models.Event) error
return m.view.ProcessedUserMembershipSequence(event)
}
memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID)
memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID, event.InstanceID)
if err != nil {
return err
}
@@ -269,7 +285,7 @@ func (m *UserMembership) updateProjectDisplayName(event *es_models.Event) error
func (m *UserMembership) processUser(event *es_models.Event) (err error) {
switch eventstore.EventType(event.Type) {
case user.UserRemovedType:
return m.view.DeleteUserMembershipsByUserID(event.AggregateID, event)
return m.view.DeleteUserMembershipsByUserID(event.AggregateID, event.InstanceID, event)
default:
return m.view.ProcessedUserMembershipSequence(event)
}
@@ -306,8 +322,8 @@ func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_mod
return org_es_model.OrgToModel(esOrg), nil
}
func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
query, err := proj_view.ProjectByIDQuery(projID, 0)
func (u *UserMembership) getProjectByID(ctx context.Context, projID, instanceID string) (*proj_model.Project, error) {
query, err := proj_view.ProjectByIDQuery(projID, instanceID, 0)
if err != nil {
return nil, err
}

View File

@@ -2,8 +2,9 @@ package spooler
import (
"database/sql"
es_locker "github.com/caos/zitadel/internal/eventstore/v1/locker"
"time"
es_locker "github.com/caos/zitadel/internal/eventstore/v1/locker"
)
const (
@@ -14,6 +15,6 @@ type locker struct {
dbClient *sql.DB
}
func (l *locker) Renew(lockerID, viewModel string, waitTime time.Duration) error {
return es_locker.Renew(l.dbClient, lockTable, lockerID, viewModel, waitTime)
func (l *locker) Renew(lockerID, viewModel, instanceID string, waitTime time.Duration) error {
return es_locker.Renew(l.dbClient, lockTable, lockerID, viewModel, instanceID, waitTime)
}

View File

@@ -12,6 +12,6 @@ func (v *View) saveFailedEvent(failedEvent *repository.FailedEvent) error {
return repository.SaveFailedEvent(v.Db, errTable, failedEvent)
}
func (v *View) latestFailedEvent(viewName string, sequence uint64) (*repository.FailedEvent, error) {
return repository.LatestFailedEvent(v.Db, errTable, viewName, sequence)
func (v *View) latestFailedEvent(viewName, instanceID string, sequence uint64) (*repository.FailedEvent, error) {
return repository.LatestFailedEvent(v.Db, errTable, viewName, instanceID, sequence)
}

View File

@@ -12,21 +12,27 @@ const (
)
func (v *View) saveCurrentSequence(viewName string, event *models.Event) error {
return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate)
return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.InstanceID, event.Sequence, event.CreationDate)
}
func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) {
return repository.LatestSequence(v.Db, sequencesTable, viewName)
func (v *View) latestSequence(viewName, instanceID string) (*repository.CurrentSequence, error) {
return repository.LatestSequence(v.Db, sequencesTable, viewName, instanceID)
}
func (v *View) latestSequences(viewName string) ([]*repository.CurrentSequence, error) {
return repository.LatestSequences(v.Db, sequencesTable, viewName)
}
func (v *View) updateSpoolerRunSequence(viewName string) error {
currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName)
currentSequences, err := repository.LatestSequences(v.Db, sequencesTable, viewName)
if err != nil {
return err
}
if currentSequence.ViewName == "" {
currentSequence.ViewName = viewName
for _, currentSequence := range currentSequences {
if currentSequence.ViewName == "" {
currentSequence.ViewName = viewName
}
currentSequence.LastSuccessfulSpoolerRun = time.Now()
}
currentSequence.LastSuccessfulSpoolerRun = time.Now()
return repository.UpdateCurrentSequence(v.Db, sequencesTable, currentSequence)
return repository.UpdateCurrentSequences(v.Db, sequencesTable, currentSequences)
}

View File

@@ -12,8 +12,8 @@ const (
tokenTable = "auth.tokens"
)
func (v *View) TokenByID(tokenID string) (*usr_view_model.TokenView, error) {
return usr_view.TokenByID(v.Db, tokenTable, tokenID)
func (v *View) TokenByID(tokenID, instanceID string) (*usr_view_model.TokenView, error) {
return usr_view.TokenByID(v.Db, tokenTable, tokenID, instanceID)
}
func (v *View) PutToken(token *usr_view_model.TokenView, event *models.Event) error {
@@ -24,24 +24,24 @@ func (v *View) PutToken(token *usr_view_model.TokenView, event *models.Event) er
return v.ProcessedTokenSequence(event)
}
func (v *View) DeleteToken(tokenID string, event *models.Event) error {
err := usr_view.DeleteToken(v.Db, tokenTable, tokenID)
func (v *View) DeleteToken(tokenID, instanceID string, event *models.Event) error {
err := usr_view.DeleteToken(v.Db, tokenTable, tokenID, instanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedTokenSequence(event)
}
func (v *View) DeleteSessionTokens(agentID, userID string, event *models.Event) error {
err := usr_view.DeleteSessionTokens(v.Db, tokenTable, agentID, userID)
func (v *View) DeleteSessionTokens(agentID, userID, instanceID string, event *models.Event) error {
err := usr_view.DeleteSessionTokens(v.Db, tokenTable, agentID, userID, instanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedTokenSequence(event)
}
func (v *View) GetLatestTokenSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(tokenTable)
func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(tokenTable, instanceID)
}
func (v *View) ProcessedTokenSequence(event *models.Event) error {
@@ -52,8 +52,8 @@ func (v *View) UpdateTokenSpoolerRunTimestamp() error {
return v.updateSpoolerRunSequence(tokenTable)
}
func (v *View) GetLatestTokenFailedEvent(sequence uint64) (*repository.FailedEvent, error) {
return v.latestFailedEvent(tokenTable, sequence)
func (v *View) GetLatestTokenFailedEvent(sequence uint64, instanceID string) (*repository.FailedEvent, error) {
return v.latestFailedEvent(tokenTable, instanceID, sequence)
}
func (v *View) ProcessedTokenFailedEvent(failedEvent *repository.FailedEvent) error {

View File

@@ -13,16 +13,16 @@ const (
userMembershipTable = "authz.user_memberships"
)
func (v *View) UserMembershipByIDs(userID, aggregateID, objectID string, memberType usr_model.MemberType) (*model.UserMembershipView, error) {
return view.UserMembershipByIDs(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType)
func (v *View) UserMembershipByIDs(userID, aggregateID, objectID, instanceID string, memberType usr_model.MemberType) (*model.UserMembershipView, error) {
return view.UserMembershipByIDs(v.Db, userMembershipTable, userID, aggregateID, objectID, instanceID, memberType)
}
func (v *View) UserMembershipsByAggregateID(aggregateID string) ([]*model.UserMembershipView, error) {
return view.UserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID)
func (v *View) UserMembershipsByAggregateID(aggregateID, instanceID string) ([]*model.UserMembershipView, error) {
return view.UserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID, instanceID)
}
func (v *View) UserMembershipsByResourceOwner(resourceOwner string) ([]*model.UserMembershipView, error) {
return view.UserMembershipsByResourceOwner(v.Db, userMembershipTable, resourceOwner)
func (v *View) UserMembershipsByResourceOwner(resourceOwner, instanceID string) ([]*model.UserMembershipView, error) {
return view.UserMembershipsByResourceOwner(v.Db, userMembershipTable, resourceOwner, instanceID)
}
func (v *View) SearchUserMemberships(request *usr_model.UserMembershipSearchRequest) ([]*model.UserMembershipView, uint64, error) {
@@ -45,40 +45,44 @@ func (v *View) BulkPutUserMemberships(memberships []*model.UserMembershipView, e
return v.ProcessedUserMembershipSequence(event)
}
func (v *View) DeleteUserMembership(userID, aggregateID, objectID string, memberType usr_model.MemberType, event *models.Event) error {
err := view.DeleteUserMembership(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType)
func (v *View) DeleteUserMembership(userID, aggregateID, objectID, instanceID string, memberType usr_model.MemberType, event *models.Event) error {
err := view.DeleteUserMembership(v.Db, userMembershipTable, userID, aggregateID, objectID, instanceID, memberType)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserMembershipSequence(event)
}
func (v *View) DeleteUserMembershipsByUserID(userID string, event *models.Event) error {
err := view.DeleteUserMembershipsByUserID(v.Db, userMembershipTable, userID)
func (v *View) DeleteUserMembershipsByUserID(userID, instanceID string, event *models.Event) error {
err := view.DeleteUserMembershipsByUserID(v.Db, userMembershipTable, userID, instanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserMembershipSequence(event)
}
func (v *View) DeleteUserMembershipsByAggregateID(aggregateID string, event *models.Event) error {
err := view.DeleteUserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID)
func (v *View) DeleteUserMembershipsByAggregateID(aggregateID, instanceID string, event *models.Event) error {
err := view.DeleteUserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID, instanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserMembershipSequence(event)
}
func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, objectID string, event *models.Event) error {
err := view.DeleteUserMembershipsByAggregateIDAndObjectID(v.Db, userMembershipTable, aggregateID, objectID)
func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, objectID, instanceID string, event *models.Event) error {
err := view.DeleteUserMembershipsByAggregateIDAndObjectID(v.Db, userMembershipTable, aggregateID, objectID, instanceID)
if err != nil && !errors.IsNotFound(err) {
return err
}
return v.ProcessedUserMembershipSequence(event)
}
func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) {
return v.latestSequence(userMembershipTable)
func (v *View) GetLatestUserMembershipSequence(instanceID string) (*repository.CurrentSequence, error) {
return v.latestSequence(userMembershipTable, instanceID)
}
func (v *View) GetLatestUserMembershipSequences() ([]*repository.CurrentSequence, error) {
return v.latestSequences(userMembershipTable)
}
func (v *View) ProcessedUserMembershipSequence(event *models.Event) error {
@@ -89,8 +93,8 @@ func (v *View) UpdateUserMembershipSpoolerRunTimestamp() error {
return v.updateSpoolerRunSequence(userMembershipTable)
}
func (v *View) GetLatestUserMembershipFailedEvent(sequence uint64) (*repository.FailedEvent, error) {
return v.latestFailedEvent(userMembershipTable, sequence)
func (v *View) GetLatestUserMembershipFailedEvent(sequence uint64, instanceID string) (*repository.FailedEvent, error) {
return v.latestFailedEvent(userMembershipTable, instanceID, sequence)
}
func (v *View) ProcessedUserMembershipFailedEvent(failedEvent *repository.FailedEvent) error {