From 0ea42f1ddf9f26d4564aa89faaccfd89e1be4063 Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Wed, 12 Feb 2025 12:48:28 +0100 Subject: [PATCH] fix: no project owner at project creation and cleanup (#9317) # Which Problems Are Solved Project creation always requires a user as project owner, in case of a system user creating the project, there is no valid user existing at that moment. # How the Problems Are Solved Remove the initially created project owner membership, as this is something which was necessary in old versions, and all should work perfectly without. The call to add a project automatically designates the calling user as the project owner, which is irrelevant currently, as this user always already has higher permissions to be able to even create the project. # Additional Changes Cleanup of the existing checks for the project, which can be improved through the usage of the fields table. # Additional Context Closes #9182 --- internal/api/grpc/management/project.go | 3 +- internal/command/instance_test.go | 5 - internal/command/project.go | 132 ++++--------------- internal/command/project_application_api.go | 14 +- internal/command/project_application_oidc.go | 12 +- internal/command/project_application_saml.go | 6 +- internal/command/project_model.go | 13 ++ internal/command/project_old.go | 94 +------------ internal/command/project_test.go | 81 +++++------- 9 files changed, 87 insertions(+), 273 deletions(-) diff --git a/internal/api/grpc/management/project.go b/internal/api/grpc/management/project.go index e7fad52c5..00ccbd215 100644 --- a/internal/api/grpc/management/project.go +++ b/internal/api/grpc/management/project.go @@ -177,8 +177,7 @@ func (s *Server) ListProjectChanges(ctx context.Context, req *mgmt_pb.ListProjec } func (s *Server) AddProject(ctx context.Context, req *mgmt_pb.AddProjectRequest) (*mgmt_pb.AddProjectResponse, error) { - ctxData := authz.GetCtxData(ctx) - project, err := s.command.AddProject(ctx, ProjectCreateToDomain(req), ctxData.OrgID, ctxData.UserID) + project, err := s.command.AddProject(ctx, ProjectCreateToDomain(req), authz.GetCtxData(ctx).OrgID) if err != nil { return nil, err } diff --git a/internal/command/instance_test.go b/internal/command/instance_test.go index fd21e0e70..2ea248dfb 100644 --- a/internal/command/instance_test.go +++ b/internal/command/instance_test.go @@ -50,11 +50,6 @@ func projectAddedEvents(ctx context.Context, instanceID, orgID, id, owner string false, domain.PrivateLabelingSettingUnspecified, ), - project.NewProjectMemberAddedEvent(ctx, - &project.NewAggregate(id, orgID).Aggregate, - owner, - domain.RoleProjectOwner, - ), instance.NewIAMProjectSetEvent(ctx, &instance.NewAggregate(instanceID).Aggregate, id, diff --git a/internal/command/project.go b/internal/command/project.go index 6923f1169..df4f8ab54 100644 --- a/internal/command/project.go +++ b/internal/command/project.go @@ -26,13 +26,8 @@ func (c *Commands) AddProjectWithID(ctx context.Context, project *domain.Project if projectID == "" { return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-nDXf5vXoUj", "Errors.IDMissing") } - - existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - if existingProject.State != domain.ProjectStateUnspecified { - return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-opamwu", "Errors.Project.AlreadyExisting") + if !project.IsValid() { + return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-IOVCC", "Errors.Project.Invalid") } project, err = c.addProjectWithID(ctx, project, resourceOwner, projectID) if err != nil { @@ -41,23 +36,22 @@ func (c *Commands) AddProjectWithID(ctx context.Context, project *domain.Project return project, nil } -func (c *Commands) AddProject(ctx context.Context, project *domain.Project, resourceOwner, ownerUserID string) (_ *domain.Project, err error) { +func (c *Commands) AddProject(ctx context.Context, project *domain.Project, resourceOwner string) (_ *domain.Project, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() if !project.IsValid() { return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-IOVCC", "Errors.Project.Invalid") } if resourceOwner == "" { return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-fmq7bqQX1s", "Errors.ResourceOwnerMissing") } - if ownerUserID == "" { - return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-xe95Gl3Dro", "Errors.IDMissing") - } projectID, err := c.idGenerator.Next() if err != nil { return nil, err } - project, err = c.addProjectWithIDWithOwner(ctx, project, resourceOwner, ownerUserID, projectID) + project, err = c.addProjectWithID(ctx, project, resourceOwner, projectID) if err != nil { return nil, err } @@ -66,13 +60,19 @@ func (c *Commands) AddProject(ctx context.Context, project *domain.Project, reso func (c *Commands) addProjectWithID(ctx context.Context, projectAdd *domain.Project, resourceOwner, projectID string) (_ *domain.Project, err error) { projectAdd.AggregateID = projectID - addedProject := NewProjectWriteModel(projectAdd.AggregateID, resourceOwner) - projectAgg := ProjectAggregateFromWriteModel(&addedProject.WriteModel) + projectWriteModel, err := c.getProjectWriteModelByID(ctx, projectAdd.AggregateID, resourceOwner) + if err != nil { + return nil, err + } + if isProjectStateExists(projectWriteModel.State) { + return nil, zerrors.ThrowAlreadyExists(nil, "COMMAND-opamwu", "Errors.Project.AlreadyExisting") + } events := []eventstore.Command{ project.NewProjectAddedEvent( ctx, - projectAgg, + //nolint: contextcheck + ProjectAggregateFromWriteModel(&projectWriteModel.WriteModel), projectAdd.Name, projectAdd.ProjectRoleAssertion, projectAdd.ProjectRoleCheck, @@ -88,47 +88,11 @@ func (c *Commands) addProjectWithID(ctx context.Context, projectAdd *domain.Proj return nil, err } postCommit(ctx) - err = AppendAndReduce(addedProject, pushedEvents...) + err = AppendAndReduce(projectWriteModel, pushedEvents...) if err != nil { return nil, err } - return projectWriteModelToProject(addedProject), nil -} - -func (c *Commands) addProjectWithIDWithOwner(ctx context.Context, projectAdd *domain.Project, resourceOwner, ownerUserID, projectID string) (_ *domain.Project, err error) { - if !projectAdd.IsValid() { - return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-IOVCC", "Errors.Project.Invalid") - } - projectAdd.AggregateID = projectID - addedProject := NewProjectWriteModel(projectAdd.AggregateID, resourceOwner) - projectAgg := ProjectAggregateFromWriteModel(&addedProject.WriteModel) - - projectRole := domain.RoleProjectOwner - events := []eventstore.Command{ - project.NewProjectAddedEvent( - ctx, - projectAgg, - projectAdd.Name, - projectAdd.ProjectRoleAssertion, - projectAdd.ProjectRoleCheck, - projectAdd.HasProjectCheck, - projectAdd.PrivateLabelingSetting), - project.NewProjectMemberAddedEvent(ctx, projectAgg, ownerUserID, projectRole), - } - postCommit, err := c.projectCreatedMilestone(ctx, &events) - if err != nil { - return nil, err - } - pushedEvents, err := c.eventstore.Push(ctx, events...) - if err != nil { - return nil, err - } - postCommit(ctx) - err = AppendAndReduce(addedProject, pushedEvents...) - if err != nil { - return nil, err - } - return projectWriteModelToProject(addedProject), nil + return projectWriteModelToProject(projectWriteModel), nil } func AddProjectCommand( @@ -159,9 +123,6 @@ func AddProjectCommand( hasProjectCheck, privateLabelingSetting, ), - project.NewProjectMemberAddedEvent(ctx, &a.Aggregate, - owner, - domain.RoleProjectOwner), }, nil }, nil } @@ -182,20 +143,6 @@ func projectWriteModel(ctx context.Context, filter preparation.FilterToQueryRedu return project, nil } -func (c *Commands) getProjectByID(ctx context.Context, projectID, resourceOwner string) (_ *domain.Project, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - projectWriteModel, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - if projectWriteModel.State == domain.ProjectStateUnspecified || projectWriteModel.State == domain.ProjectStateRemoved { - return nil, zerrors.ThrowNotFound(nil, "PROJECT-Gd2hh", "Errors.Project.NotFound") - } - return projectWriteModelToProject(projectWriteModel), nil -} - func (c *Commands) projectAggregateByID(ctx context.Context, projectID, resourceOwner string) (*eventstore.Aggregate, domain.ProjectState, error) { result, err := c.projectState(ctx, projectID, resourceOwner) if err != nil { @@ -250,15 +197,11 @@ func (c *Commands) ChangeProject(ctx context.Context, projectChange *domain.Proj return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-4m9vS", "Errors.Project.Invalid") } - if !authz.GetFeatures(ctx).ShouldUseImprovedPerformance(feature.ImprovedPerformanceTypeProject) { - return c.changeProjectOld(ctx, projectChange, resourceOwner) - } - existingProject, err := c.getProjectWriteModelByID(ctx, projectChange.AggregateID, resourceOwner) if err != nil { return nil, err } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { + if !isProjectStateExists(existingProject.State) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } @@ -277,11 +220,7 @@ func (c *Commands) ChangeProject(ctx context.Context, projectChange *domain.Proj if !hasChanged { return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-2M0fs", "Errors.NoChangesFound") } - pushedEvents, err := c.eventstore.Push(ctx, changedEvent) - if err != nil { - return nil, err - } - err = AppendAndReduce(existingProject, pushedEvents...) + err = c.pushAppendAndReduce(ctx, existingProject, changedEvent) if err != nil { return nil, err } @@ -302,7 +241,7 @@ func (c *Commands) DeactivateProject(ctx context.Context, projectID string, reso return nil, err } - if state == domain.ProjectStateUnspecified || state == domain.ProjectStateRemoved { + if !isProjectStateExists(state) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-112M9", "Errors.Project.NotFound") } if state != domain.ProjectStateActive { @@ -314,17 +253,6 @@ func (c *Commands) DeactivateProject(ctx context.Context, projectID string, reso return nil, err } - existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { - return nil, zerrors.ThrowNotFound(nil, "COMMAND-112M9", "Errors.Project.NotFound") - } - if existingProject.State != domain.ProjectStateActive { - return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-mki55", "Errors.Project.NotActive") - } - return &domain.ObjectDetails{ ResourceOwner: pushedEvents[0].Aggregate().ResourceOwner, Sequence: pushedEvents[0].Sequence(), @@ -346,25 +274,13 @@ func (c *Commands) ReactivateProject(ctx context.Context, projectID string, reso return nil, err } - if state == domain.ProjectStateUnspecified || state == domain.ProjectStateRemoved { + if !isProjectStateExists(state) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } - if state != domain.ProjectStateInactive { return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-5M9bs", "Errors.Project.NotInactive") } - existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { - return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") - } - if existingProject.State != domain.ProjectStateInactive { - return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-5M9bs", "Errors.Project.NotInactive") - } - pushedEvents, err := c.eventstore.Push(ctx, project.NewProjectReactivatedEvent(ctx, projectAgg)) if err != nil { return nil, err @@ -382,15 +298,11 @@ func (c *Commands) RemoveProject(ctx context.Context, projectID, resourceOwner s return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-66hM9", "Errors.Project.ProjectIDMissing") } - if !authz.GetFeatures(ctx).ShouldUseImprovedPerformance(feature.ImprovedPerformanceTypeProject) { - return c.removeProjectOld(ctx, projectID, resourceOwner) - } - existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) if err != nil { return nil, err } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { + if !isProjectStateExists(existingProject.State) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } diff --git a/internal/command/project_application_api.go b/internal/command/project_application_api.go index e3718b501..21c3bc5ee 100644 --- a/internal/command/project_application_api.go +++ b/internal/command/project_application_api.go @@ -78,11 +78,10 @@ func (c *Commands) AddAPIApplicationWithID(ctx context.Context, apiApp *domain.A if existingAPI.State != domain.AppStateUnspecified { return nil, zerrors.ThrowPreconditionFailed(nil, "PROJECT-mabu12", "Errors.Project.App.AlreadyExisting") } - _, err = c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner) - if err != nil { - return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-9fnsa", "Errors.Project.NotFound") - } + if err := c.checkProjectExists(ctx, apiApp.AggregateID, resourceOwner); err != nil { + return nil, err + } return c.addAPIApplicationWithID(ctx, apiApp, resourceOwner, appID) } @@ -90,11 +89,10 @@ func (c *Commands) AddAPIApplication(ctx context.Context, apiApp *domain.APIApp, if apiApp == nil || apiApp.AggregateID == "" { return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-5m9E", "Errors.Project.App.Invalid") } - _, err = c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner) - if err != nil { - return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-9fnsf", "Errors.Project.NotFound") - } + if err := c.checkProjectExists(ctx, apiApp.AggregateID, resourceOwner); err != nil { + return nil, err + } if !apiApp.IsValid() { return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-Bff2g", "Errors.Project.App.Invalid") } diff --git a/internal/command/project_application_oidc.go b/internal/command/project_application_oidc.go index 257cdeaec..fccb0efe0 100644 --- a/internal/command/project_application_oidc.go +++ b/internal/command/project_application_oidc.go @@ -132,11 +132,9 @@ func (c *Commands) AddOIDCApplicationWithID(ctx context.Context, oidcApp *domain return nil, zerrors.ThrowPreconditionFailed(nil, "PROJECT-lxowmp", "Errors.Project.App.AlreadyExisting") } - _, err = c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner) - if err != nil { - return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-3m9s2", "Errors.Project.NotFound") + if err := c.checkProjectExists(ctx, oidcApp.AggregateID, resourceOwner); err != nil { + return nil, err } - return c.addOIDCApplicationWithID(ctx, oidcApp, resourceOwner, appID) } @@ -144,11 +142,9 @@ func (c *Commands) AddOIDCApplication(ctx context.Context, oidcApp *domain.OIDCA if oidcApp == nil || oidcApp.AggregateID == "" { return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-34Fm0", "Errors.Project.App.Invalid") } - _, err = c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner) - if err != nil { - return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-3m9ss", "Errors.Project.NotFound") + if err := c.checkProjectExists(ctx, oidcApp.AggregateID, resourceOwner); err != nil { + return nil, err } - if oidcApp.AppName == "" || !oidcApp.IsValid() { return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-1n8df", "Errors.Project.App.Invalid") } diff --git a/internal/command/project_application_saml.go b/internal/command/project_application_saml.go index 612c2dbd5..76297ad93 100644 --- a/internal/command/project_application_saml.go +++ b/internal/command/project_application_saml.go @@ -16,11 +16,9 @@ func (c *Commands) AddSAMLApplication(ctx context.Context, application *domain.S return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-35Fn0", "Errors.Project.App.Invalid") } - _, err = c.getProjectByID(ctx, application.AggregateID, resourceOwner) - if err != nil { - return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-3p9ss", "Errors.Project.NotFound") + if err := c.checkProjectExists(ctx, application.AggregateID, resourceOwner); err != nil { + return nil, err } - addedApplication := NewSAMLApplicationWriteModel(application.AggregateID, resourceOwner) projectAgg := ProjectAggregateFromWriteModel(&addedApplication.WriteModel) events, err := c.addSAMLApplication(ctx, projectAgg, application) diff --git a/internal/command/project_model.go b/internal/command/project_model.go index 99b878885..a46b07a8f 100644 --- a/internal/command/project_model.go +++ b/internal/command/project_model.go @@ -124,6 +124,19 @@ func (wm *ProjectWriteModel) NewChangedEvent( return changeEvent, true, nil } +func isProjectStateExists(state domain.ProjectState) bool { + return !hasProjectState(state, domain.ProjectStateRemoved, domain.ProjectStateUnspecified) +} + func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { return eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion) } + +func hasProjectState(check domain.ProjectState, states ...domain.ProjectState) bool { + for _, state := range states { + if check == state { + return true + } + } + return false +} diff --git a/internal/command/project_old.go b/internal/command/project_old.go index b31b4e58b..35ea9b3eb 100644 --- a/internal/command/project_old.go +++ b/internal/command/project_old.go @@ -3,10 +3,7 @@ package command import ( "context" - "github.com/zitadel/logging" - "github.com/zitadel/zitadel/internal/domain" - "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/telemetry/tracing" "github.com/zitadel/zitadel/internal/zerrors" @@ -20,58 +17,18 @@ func (c *Commands) checkProjectExistsOld(ctx context.Context, projectID, resourc if err != nil { return err } - if projectWriteModel.State == domain.ProjectStateUnspecified || projectWriteModel.State == domain.ProjectStateRemoved { + if !isProjectStateExists(projectWriteModel.State) { return zerrors.ThrowPreconditionFailed(nil, "COMMAND-EbFMN", "Errors.Project.NotFound") } return nil } -func (c *Commands) changeProjectOld(ctx context.Context, projectChange *domain.Project, resourceOwner string) (*domain.Project, error) { - if !projectChange.IsValid() || projectChange.AggregateID == "" { - return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-4m9vS", "Errors.Project.Invalid") - } - - existingProject, err := c.getProjectWriteModelByID(ctx, projectChange.AggregateID, resourceOwner) - if err != nil { - return nil, err - } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { - return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") - } - - //nolint: contextcheck - projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - changedEvent, hasChanged, err := existingProject.NewChangedEvent( - ctx, - projectAgg, - projectChange.Name, - projectChange.ProjectRoleAssertion, - projectChange.ProjectRoleCheck, - projectChange.HasProjectCheck, - projectChange.PrivateLabelingSetting) - if err != nil { - return nil, err - } - if !hasChanged { - return nil, zerrors.ThrowPreconditionFailed(nil, "COMMAND-2M0fs", "Errors.NoChangesFound") - } - pushedEvents, err := c.eventstore.Push(ctx, changedEvent) - if err != nil { - return nil, err - } - err = AppendAndReduce(existingProject, pushedEvents...) - if err != nil { - return nil, err - } - return projectWriteModelToProject(existingProject), nil -} - func (c *Commands) deactivateProjectOld(ctx context.Context, projectID string, resourceOwner string) (*domain.ObjectDetails, error) { existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) if err != nil { return nil, err } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { + if !isProjectStateExists(existingProject.State) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-112M9", "Errors.Project.NotFound") } if existingProject.State != domain.ProjectStateActive { @@ -96,7 +53,7 @@ func (c *Commands) reactivateProjectOld(ctx context.Context, projectID string, r if err != nil { return nil, err } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { + if !isProjectStateExists(existingProject.State) { return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") } if existingProject.State != domain.ProjectStateInactive { @@ -116,51 +73,6 @@ func (c *Commands) reactivateProjectOld(ctx context.Context, projectID string, r return writeModelToObjectDetails(&existingProject.WriteModel), nil } -func (c *Commands) removeProjectOld(ctx context.Context, projectID, resourceOwner string, cascadingUserGrantIDs ...string) (*domain.ObjectDetails, error) { - existingProject, err := c.getProjectWriteModelByID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved { - return nil, zerrors.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound") - } - - samlEntityIDsAgg, err := c.getSAMLEntityIdsWriteModelByProjectID(ctx, projectID, resourceOwner) - if err != nil { - return nil, err - } - - uniqueConstraints := make([]*eventstore.UniqueConstraint, len(samlEntityIDsAgg.EntityIDs)) - for i, entityID := range samlEntityIDsAgg.EntityIDs { - uniqueConstraints[i] = project.NewRemoveSAMLConfigEntityIDUniqueConstraint(entityID.EntityID) - } - - //nolint: contextcheck - projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel) - events := []eventstore.Command{ - project.NewProjectRemovedEvent(ctx, projectAgg, existingProject.Name, uniqueConstraints), - } - - for _, grantID := range cascadingUserGrantIDs { - event, _, err := c.removeUserGrant(ctx, grantID, "", true) - if err != nil { - logging.WithFields("usergrantid", grantID).WithError(err).Warn("could not cascade remove user grant") - continue - } - events = append(events, event) - } - - pushedEvents, err := c.eventstore.Push(ctx, events...) - if err != nil { - return nil, err - } - err = AppendAndReduce(existingProject, pushedEvents...) - if err != nil { - return nil, err - } - return writeModelToObjectDetails(&existingProject.WriteModel), nil -} - func (c *Commands) checkProjectGrantPreConditionOld(ctx context.Context, projectGrant *domain.ProjectGrant, resourceOwner string) error { preConditions := NewProjectGrantPreConditionReadModel(projectGrant.AggregateID, projectGrant.GrantedOrgID, resourceOwner) err := c.eventstore.FilterToQueryReducer(ctx, preConditions) diff --git a/internal/command/project_test.go b/internal/command/project_test.go index 4f8ad149e..645371e2f 100644 --- a/internal/command/project_test.go +++ b/internal/command/project_test.go @@ -25,7 +25,6 @@ func TestCommandSide_AddProject(t *testing.T) { ctx context.Context project *domain.Project resourceOwner string - ownerID string } type res struct { want *domain.Project @@ -54,7 +53,7 @@ func TestCommandSide_AddProject(t *testing.T) { }, }, { - name: "org with project owner, resourceowner empty", + name: "project, resourceowner empty", fields: fields{ eventstore: eventstoreExpect( t, @@ -70,40 +69,17 @@ func TestCommandSide_AddProject(t *testing.T) { PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, }, resourceOwner: "", - ownerID: "user1", }, res: res{ err: zerrors.IsErrorInvalidArgument, }, }, { - name: "org with project owner, ownerID empty", - fields: fields{ - eventstore: eventstoreExpect( - t, - ), - }, - args: args{ - ctx: context.Background(), - project: &domain.Project{ - Name: "project", - ProjectRoleAssertion: true, - ProjectRoleCheck: true, - HasProjectCheck: true, - PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, - }, - resourceOwner: "org1", - ownerID: "", - }, - res: res{ - err: zerrors.IsErrorInvalidArgument, - }, - }, - { - name: "org with project owner, error already exists", + name: "project, error already exists", fields: fields{ eventstore: eventstoreExpect( t, + expectFilter(), expectPushFailed(zerrors.ThrowAlreadyExists(nil, "ERROR", "internl"), project.NewProjectAddedEvent( context.Background(), @@ -111,11 +87,36 @@ func TestCommandSide_AddProject(t *testing.T) { "project", true, true, true, domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, ), - project.NewProjectMemberAddedEvent( - context.Background(), - &project.NewAggregate("project1", "org1").Aggregate, - "user1", - []string{domain.RoleProjectOwner}..., + ), + ), + idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "project1"), + }, + args: args{ + ctx: authz.WithInstanceID(context.Background(), "instanceID"), + project: &domain.Project{ + Name: "project", + ProjectRoleAssertion: true, + ProjectRoleCheck: true, + HasProjectCheck: true, + PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, + }, + resourceOwner: "org1", + }, + res: res{ + err: zerrors.IsErrorAlreadyExists, + }, + }, + { + name: "project, already exists", + fields: fields{ + eventstore: eventstoreExpect( + t, + expectFilter( + eventFromEventPusher( + project.NewProjectAddedEvent(context.Background(), + &project.NewAggregate("project1", "org1").Aggregate, + "project", true, true, true, + domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy), ), ), ), @@ -131,17 +132,17 @@ func TestCommandSide_AddProject(t *testing.T) { PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, }, resourceOwner: "org1", - ownerID: "user1", }, res: res{ err: zerrors.IsErrorAlreadyExists, }, }, { - name: "org with project owner, ok", + name: "project, ok", fields: fields{ eventstore: eventstoreExpect( t, + expectFilter(), expectPush( project.NewProjectAddedEvent( context.Background(), @@ -149,12 +150,6 @@ func TestCommandSide_AddProject(t *testing.T) { "project", true, true, true, domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, ), - project.NewProjectMemberAddedEvent( - context.Background(), - &project.NewAggregate("project1", "org1").Aggregate, - "user1", - []string{domain.RoleProjectOwner}..., - ), ), ), idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "project1"), @@ -169,7 +164,6 @@ func TestCommandSide_AddProject(t *testing.T) { PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, }, resourceOwner: "org1", - ownerID: "user1", }, res: res{ want: &domain.Project{ @@ -193,7 +187,7 @@ func TestCommandSide_AddProject(t *testing.T) { idGenerator: tt.fields.idGenerator, } c.setMilestonesCompletedForTest("instanceID") - got, err := c.AddProject(tt.args.ctx, tt.args.project, tt.args.resourceOwner, tt.args.ownerID) + got, err := c.AddProject(tt.args.ctx, tt.args.project, tt.args.resourceOwner) if tt.res.err == nil { assert.NoError(t, err) } @@ -1207,9 +1201,6 @@ func TestAddProject(t *testing.T) { false, domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy, ), - project.NewProjectMemberAddedEvent(ctx, &agg.Aggregate, - "CAOS AG", - domain.RoleProjectOwner), }, }, },