fix: Project checks (#141)

* project validations

* unique project on resourceowner
This commit is contained in:
Fabi
2020-05-28 06:53:12 +02:00
committed by GitHub
parent d447f68d78
commit 2758bf30b1
7 changed files with 191 additions and 14 deletions

View File

@@ -6,7 +6,9 @@ import (
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
)
func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
@@ -40,8 +42,12 @@ func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *mod
if err != nil {
return nil, err
}
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(model.ProjectAggregate).
EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved)
return agg.AppendEvent(model.ProjectAdded, project)
validation := addProjectValidation(project.Name)
return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectAdded, project)
}
}
@@ -55,6 +61,17 @@ func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *mo
return nil, err
}
changes := existing.Changes(new)
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9soPE", "no changes found")
}
if existing.Name != new.Name {
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(model.ProjectAggregate).
EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved)
validation := addProjectValidation(new.Name)
agg.SetPrecondition(validationQuery, validation)
}
return agg.AppendEvent(model.ProjectChanged, changes)
}
}
@@ -86,7 +103,12 @@ func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existin
if err != nil {
return nil, err
}
return agg.AppendEvent(model.ProjectMemberAdded, member)
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(usr_model.UserAggregate).
AggregateIDFilter(member.UserID)
validation := addProjectMemberValidation()
return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectMemberAdded, member)
}
}
@@ -287,7 +309,12 @@ func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, existing
if err != nil {
return nil, err
}
agg.AppendEvent(model.ProjectGrantAdded, grant)
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(org_model.OrgAggregate).
AggregateIDFilter(grant.GrantedOrgID)
validation := addProjectGrantValidation()
agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectGrantAdded, grant)
return agg, nil
}
}
@@ -352,9 +379,7 @@ func ProjectGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, ex
if err != nil {
return nil, err
}
agg.AppendEvent(model.ProjectGrantReactivated, &model.ProjectGrantID{GrantID: grant.GrantID})
return agg, nil
return agg.AppendEvent(model.ProjectGrantReactivated, &model.ProjectGrantID{GrantID: grant.GrantID})
}
}
@@ -367,8 +392,12 @@ func ProjectGrantMemberAddedAggregate(aggCreator *es_models.AggregateCreator, ex
if err != nil {
return nil, err
}
agg.AppendEvent(model.ProjectGrantMemberAdded, member)
return agg, nil
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(usr_model.UserAggregate).
AggregateIDFilter(member.UserID)
validation := addProjectGrantMemberValidation()
return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectGrantMemberAdded, member)
}
}
@@ -403,3 +432,86 @@ func ProjectGrantMemberRemovedAggregate(aggCreator *es_models.AggregateCreator,
return agg.AppendEvent(model.ProjectGrantMemberRemoved, member)
}
}
func addProjectValidation(projectName string) func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
projects := make([]*model.Project, 0)
for _, event := range events {
switch event.Type {
case model.ProjectAdded:
project := &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: event.AggregateID}}
project.AppendAddProjectEvent(event)
projects = append(projects, project)
case model.ProjectChanged:
_, project := model.GetProject(projects, event.AggregateID)
project.AppendAddProjectEvent(event)
case model.ProjectRoleRemoved:
for i, project := range projects {
if project.AggregateID == event.AggregateID {
projects[i] = projects[len(projects)-1]
projects[len(projects)-1] = nil
projects = projects[:len(projects)-1]
}
}
}
}
for _, p := range projects {
if p.Name == projectName {
return errors.ThrowPreconditionFailed(nil, "EVENT-s9oPw", "conditions not met")
}
}
return nil
}
}
func addProjectMemberValidation() func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
return checkExistsUser(events...)
}
}
func addProjectGrantValidation() func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
existsOrg := false
for _, event := range events {
switch event.AggregateType {
case org_model.OrgAggregate:
switch event.Type {
case org_model.OrgAdded:
existsOrg = true
case org_model.OrgRemoved:
existsOrg = false
}
}
}
if existsOrg {
return nil
}
return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "conditions not met")
}
}
func addProjectGrantMemberValidation() func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
return checkExistsUser(events...)
}
}
func checkExistsUser(events ...*es_models.Event) error {
existsUser := false
for _, event := range events {
switch event.AggregateType {
case usr_model.UserAggregate:
switch event.Type {
case usr_model.UserAdded, usr_model.UserRegistered:
existsUser = true
case usr_model.UserRemoved:
existsUser = false
}
}
}
if existsUser {
return nil
}
return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "conditions not met")
}