From 60b2092d2cef49ddd96cb6fa2447d24651cb20ec Mon Sep 17 00:00:00 2001 From: Silvan Date: Mon, 29 Aug 2022 17:09:07 +0200 Subject: [PATCH] fix(import): check exists (#4268) * fix(import): check if org exists and user * refactor: imports * fix(user): ignore malformed events * refactor: method naming * fix: test * refactor: correct errors.Is call --- internal/api/grpc/admin/import.go | 122 ++++++++++-------- internal/command/instance_idp_config.go | 12 +- internal/command/project_grant_member.go | 17 ++- internal/command/project_member.go | 18 ++- internal/command/user_human_otp.go | 4 + internal/command/user_idp_link.go | 4 + internal/command/user_idp_link_test.go | 51 ++++++++ .../handler/crdb/handler_stmt_test.go | 2 +- internal/eventstore/handler/crdb/lock_test.go | 2 +- internal/user/repository/view/model/user.go | 8 ++ 10 files changed, 156 insertions(+), 84 deletions(-) diff --git a/internal/api/grpc/admin/import.go b/internal/api/grpc/admin/import.go index 66765bf6f4..f57a21bd74 100644 --- a/internal/api/grpc/admin/import.go +++ b/internal/api/grpc/admin/import.go @@ -1,29 +1,30 @@ package admin import ( - "cloud.google.com/go/storage" "context" "encoding/base64" "encoding/json" "fmt" + "io/ioutil" + "strconv" + "time" + + "cloud.google.com/go/storage" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" + "google.golang.org/api/option" + "google.golang.org/protobuf/types/known/durationpb" + "github.com/zitadel/logging" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/management" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore/v1/models" - es_models "github.com/zitadel/zitadel/internal/eventstore/v1/models" "github.com/zitadel/zitadel/internal/telemetry/tracing" admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin" management_pb "github.com/zitadel/zitadel/pkg/grpc/management" "github.com/zitadel/zitadel/pkg/grpc/policy" v1_pb "github.com/zitadel/zitadel/pkg/grpc/v1" - "google.golang.org/api/option" - "google.golang.org/protobuf/types/known/durationpb" - "io/ioutil" - "strconv" - "time" ) type importResponse struct { @@ -335,6 +336,10 @@ func (s *Server) importData(ctx context.Context, orgs []*admin_pb.DataOrg) (*adm _, err := s.command.AddOrgWithID(ctx, org.GetOrg().GetName(), ctxData.UserID, ctxData.ResourceOwner, org.GetOrgId(), []string{}) if err != nil { errors = append(errors, &admin_pb.ImportDataError{Type: "org", Id: org.GetOrgId(), Message: err.Error()}) + + if _, err := s.query.OrgByID(ctx, true, org.OrgId); err != nil { + continue + } } successOrg := &admin_pb.ImportDataSuccessOrg{ OrgId: org.GetOrgId(), @@ -576,7 +581,7 @@ func (s *Server) importData(ctx context.Context, orgs []*admin_pb.DataOrg) (*adm for _, userLinks := range org.GetUserLinks() { logging.Debugf("import userlink: %s", userLinks.GetUserId()+"_"+userLinks.GetIdpId()+"_"+userLinks.GetProvidedUserId()+"_"+userLinks.GetProvidedUserName()) externalIDP := &domain.UserIDPLink{ - ObjectRoot: es_models.ObjectRoot{AggregateID: userLinks.UserId}, + ObjectRoot: models.ObjectRoot{AggregateID: userLinks.UserId}, IDPConfigID: userLinks.IdpId, ExternalUserID: userLinks.ProvidedUserId, DisplayName: userLinks.ProvidedUserName, @@ -682,6 +687,10 @@ func (s *Server) importData(ctx context.Context, orgs []*admin_pb.DataOrg) (*adm successOrg = oldOrd } } + if successOrg == nil { + continue + } + if org.TriggerActions != nil { for _, triggerAction := range org.GetTriggerActions() { _, err := s.command.SetTriggerActions(ctx, domain.FlowType(triggerAction.FlowType), domain.TriggerType(triggerAction.TriggerType), triggerAction.ActionIds, org.GetOrgId()) @@ -726,68 +735,67 @@ func (s *Server) importData(ctx context.Context, orgs []*admin_pb.DataOrg) (*adm } } - if success != nil && success.Orgs != nil { - for _, org := range orgs { - var successOrg *admin_pb.ImportDataSuccessOrg - for _, oldOrd := range success.Orgs { - if org.OrgId == oldOrd.OrgId { - successOrg = oldOrd - } - } - if successOrg == nil { - continue + for _, org := range orgs { + var successOrg *admin_pb.ImportDataSuccessOrg + for _, oldOrd := range success.Orgs { + if org.OrgId == oldOrd.OrgId { + successOrg = oldOrd } + } + if successOrg == nil { + continue + } - if org.OrgMembers != nil { - for _, member := range org.GetOrgMembers() { - logging.Debugf("import orgmember: %s", member.GetUserId()) - _, err := s.command.AddOrgMember(ctx, org.GetOrgId(), member.GetUserId(), member.GetRoles()...) - if err != nil { - errors = append(errors, &admin_pb.ImportDataError{Type: "org_member", Id: org.GetOrgId() + "_" + member.GetUserId(), Message: err.Error()}) - if isCtxTimeout(ctx) { - return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err - } - continue + if org.OrgMembers != nil { + for _, member := range org.GetOrgMembers() { + logging.Debugf("import orgmember: %s", member.GetUserId()) + _, err := s.command.AddOrgMember(ctx, org.GetOrgId(), member.GetUserId(), member.GetRoles()...) + if err != nil { + errors = append(errors, &admin_pb.ImportDataError{Type: "org_member", Id: org.GetOrgId() + "_" + member.GetUserId(), Message: err.Error()}) + if isCtxTimeout(ctx) { + return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err } - count.orgMemberCount += 1 - logging.Debugf("successful orgmember %d: %s", count.orgMemberCount, member.GetUserId()) - successOrg.OrgMembers = append(successOrg.OrgMembers, member.GetUserId()) + continue } + count.orgMemberCount += 1 + logging.Debugf("successful orgmember %d: %s", count.orgMemberCount, member.GetUserId()) + successOrg.OrgMembers = append(successOrg.OrgMembers, member.GetUserId()) } - if org.ProjectGrantMembers != nil { - for _, member := range org.GetProjectGrantMembers() { - logging.Debugf("import projectgrantmember: %s", member.GetProjectId()+"_"+member.GetGrantId()+"_"+member.GetUserId()) - _, err := s.command.AddProjectGrantMember(ctx, management.AddProjectGrantMemberRequestToDomain(member)) - if err != nil { - errors = append(errors, &admin_pb.ImportDataError{Type: "project_grant_member", Id: org.GetOrgId() + "_" + member.GetProjectId() + "_" + member.GetGrantId() + "_" + member.GetUserId(), Message: err.Error()}) - if isCtxTimeout(ctx) { - return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err - } - continue + } + if org.ProjectGrantMembers != nil { + for _, member := range org.GetProjectGrantMembers() { + logging.Debugf("import projectgrantmember: %s", member.GetProjectId()+"_"+member.GetGrantId()+"_"+member.GetUserId()) + _, err := s.command.AddProjectGrantMember(ctx, management.AddProjectGrantMemberRequestToDomain(member)) + if err != nil { + errors = append(errors, &admin_pb.ImportDataError{Type: "project_grant_member", Id: org.GetOrgId() + "_" + member.GetProjectId() + "_" + member.GetGrantId() + "_" + member.GetUserId(), Message: err.Error()}) + if isCtxTimeout(ctx) { + return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err } - count.projectGrantMemberCount += 1 - logging.Debugf("successful projectgrantmember %d: %s", count.projectGrantMemberCount, member.GetProjectId()+"_"+member.GetGrantId()+"_"+member.GetUserId()) - successOrg.ProjectGrantMembers = append(successOrg.ProjectGrantMembers, &admin_pb.ImportDataSuccessProjectGrantMember{ProjectId: member.GetProjectId(), GrantId: member.GetGrantId(), UserId: member.GetUserId()}) + continue } + count.projectGrantMemberCount += 1 + logging.Debugf("successful projectgrantmember %d: %s", count.projectGrantMemberCount, member.GetProjectId()+"_"+member.GetGrantId()+"_"+member.GetUserId()) + successOrg.ProjectGrantMembers = append(successOrg.ProjectGrantMembers, &admin_pb.ImportDataSuccessProjectGrantMember{ProjectId: member.GetProjectId(), GrantId: member.GetGrantId(), UserId: member.GetUserId()}) } - if org.ProjectMembers != nil { - for _, member := range org.GetProjectMembers() { - logging.Debugf("import orgmember: %s", member.GetProjectId()+"_"+member.GetUserId()) - _, err := s.command.AddProjectMember(ctx, management.AddProjectMemberRequestToDomain(member), org.GetOrgId()) - if err != nil { - errors = append(errors, &admin_pb.ImportDataError{Type: "project_member", Id: org.GetOrgId() + "_" + member.GetProjectId() + "_" + member.GetUserId(), Message: err.Error()}) - if isCtxTimeout(ctx) { - return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err - } - continue + } + if org.ProjectMembers != nil { + for _, member := range org.GetProjectMembers() { + logging.Debugf("import orgmember: %s", member.GetProjectId()+"_"+member.GetUserId()) + _, err := s.command.AddProjectMember(ctx, management.AddProjectMemberRequestToDomain(member), org.GetOrgId()) + if err != nil { + errors = append(errors, &admin_pb.ImportDataError{Type: "project_member", Id: org.GetOrgId() + "_" + member.GetProjectId() + "_" + member.GetUserId(), Message: err.Error()}) + if isCtxTimeout(ctx) { + return &admin_pb.ImportDataResponse{Errors: errors, Success: success}, count, err } - count.projectMembersCount += 1 - logging.Debugf("successful orgmember %d: %s", count.projectMembersCount, member.GetProjectId()+"_"+member.GetUserId()) - successOrg.ProjectMembers = append(successOrg.ProjectMembers, &admin_pb.ImportDataSuccessProjectMember{ProjectId: member.GetProjectId(), UserId: member.GetUserId()}) + continue } + count.projectMembersCount += 1 + logging.Debugf("successful orgmember %d: %s", count.projectMembersCount, member.GetProjectId()+"_"+member.GetUserId()) + successOrg.ProjectMembers = append(successOrg.ProjectMembers, &admin_pb.ImportDataSuccessProjectMember{ProjectId: member.GetProjectId(), UserId: member.GetUserId()}) } } } + return &admin_pb.ImportDataResponse{ Errors: errors, Success: success, diff --git a/internal/command/instance_idp_config.go b/internal/command/instance_idp_config.go index 684acb0a3b..a61cdcaf03 100644 --- a/internal/command/instance_idp_config.go +++ b/internal/command/instance_idp_config.go @@ -81,7 +81,7 @@ func (c *Commands) ChangeDefaultIDPConfig(ctx context.Context, config *domain.ID if config.IDPConfigID == "" { return nil, errors.ThrowInvalidArgument(nil, "INSTANCE-4m9gs", "Errors.IDMissing") } - existingIDP, err := c.isntanceIDPConfigWriteModelByID(ctx, config.IDPConfigID) + existingIDP, err := c.instanceIDPConfigWriteModelByID(ctx, config.IDPConfigID) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (c *Commands) ChangeDefaultIDPConfig(ctx context.Context, config *domain.ID } func (c *Commands) DeactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.ObjectDetails, error) { - existingIDP, err := c.isntanceIDPConfigWriteModelByID(ctx, idpID) + existingIDP, err := c.instanceIDPConfigWriteModelByID(ctx, idpID) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func (c *Commands) DeactivateDefaultIDPConfig(ctx context.Context, idpID string) } func (c *Commands) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.ObjectDetails, error) { - existingIDP, err := c.isntanceIDPConfigWriteModelByID(ctx, idpID) + existingIDP, err := c.instanceIDPConfigWriteModelByID(ctx, idpID) if err != nil { return nil, err } @@ -146,7 +146,7 @@ func (c *Commands) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) } func (c *Commands) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idpProviders []*domain.IDPProvider, externalIDPs ...*domain.UserIDPLink) (*domain.ObjectDetails, error) { - existingIDP, err := c.isntanceIDPConfigWriteModelByID(ctx, idpID) + existingIDP, err := c.instanceIDPConfigWriteModelByID(ctx, idpID) if err != nil { return nil, err } @@ -181,7 +181,7 @@ func (c *Commands) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idp } func (c *Commands) getInstanceIDPConfigByID(ctx context.Context, idpID string) (*domain.IDPConfig, error) { - config, err := c.isntanceIDPConfigWriteModelByID(ctx, idpID) + config, err := c.instanceIDPConfigWriteModelByID(ctx, idpID) if err != nil { return nil, err } @@ -191,7 +191,7 @@ func (c *Commands) getInstanceIDPConfigByID(ctx context.Context, idpID string) ( return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil } -func (c *Commands) isntanceIDPConfigWriteModelByID(ctx context.Context, idpID string) (policy *InstanceIDPConfigWriteModel, err error) { +func (c *Commands) instanceIDPConfigWriteModelByID(ctx context.Context, idpID string) (policy *InstanceIDPConfigWriteModel, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() diff --git a/internal/command/project_grant_member.go b/internal/command/project_grant_member.go index 44d47ef8f1..ad43f81f18 100644 --- a/internal/command/project_grant_member.go +++ b/internal/command/project_grant_member.go @@ -6,7 +6,6 @@ import ( "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" - caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/telemetry/tracing" @@ -14,10 +13,10 @@ import ( func (c *Commands) AddProjectGrantMember(ctx context.Context, member *domain.ProjectGrantMember) (*domain.ProjectGrantMember, error) { if !member.IsValid() { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-8fi7G", "Errors.Project.Grant.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-8fi7G", "Errors.Project.Grant.Member.Invalid") } if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectGrantRolePrefix, c.zitadelRoles)) > 0 { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-m9gKK", "Errors.Project.Grant.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-m9gKK", "Errors.Project.Grant.Member.Invalid") } err := c.checkUserExists(ctx, member.UserID, "") if err != nil { @@ -29,7 +28,7 @@ func (c *Commands) AddProjectGrantMember(ctx context.Context, member *domain.Pro return nil, err } if addedMember.State == domain.MemberStateActive { - return nil, caos_errs.ThrowAlreadyExists(nil, "PROJECT-16dVN", "Errors.Project.Member.AlreadyExists") + return nil, errors.ThrowAlreadyExists(nil, "PROJECT-16dVN", "Errors.Project.Member.AlreadyExists") } projectAgg := ProjectAggregateFromWriteModel(&addedMember.WriteModel) pushedEvents, err := c.eventstore.Push( @@ -46,13 +45,13 @@ func (c *Commands) AddProjectGrantMember(ctx context.Context, member *domain.Pro return memberWriteModelToProjectGrantMember(addedMember), nil } -//ChangeProjectGrantMember updates an existing member +// ChangeProjectGrantMember updates an existing member func (c *Commands) ChangeProjectGrantMember(ctx context.Context, member *domain.ProjectGrantMember) (*domain.ProjectGrantMember, error) { if !member.IsValid() { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-109fs", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-109fs", "Errors.Project.Member.Invalid") } if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectGrantRolePrefix, c.zitadelRoles)) > 0 { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-m0sDf", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-m0sDf", "Errors.Project.Member.Invalid") } existingMember, err := c.projectGrantMemberWriteModelByID(ctx, member.AggregateID, member.UserID, member.GrantID) @@ -61,7 +60,7 @@ func (c *Commands) ChangeProjectGrantMember(ctx context.Context, member *domain. } if reflect.DeepEqual(existingMember.Roles, member.Roles) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-2n8vx", "Errors.Project.Member.RolesNotChanged") + return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-2n8vx", "Errors.Project.Member.RolesNotChanged") } projectAgg := ProjectAggregateFromWriteModel(&existingMember.WriteModel) pushedEvents, err := c.eventstore.Push( @@ -80,7 +79,7 @@ func (c *Commands) ChangeProjectGrantMember(ctx context.Context, member *domain. func (c *Commands) RemoveProjectGrantMember(ctx context.Context, projectID, userID, grantID string) (*domain.ObjectDetails, error) { if projectID == "" || userID == "" || grantID == "" { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-66mHd", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-66mHd", "Errors.Project.Member.Invalid") } m, err := c.projectGrantMemberWriteModelByID(ctx, projectID, userID, grantID) if err != nil { diff --git a/internal/command/project_member.go b/internal/command/project_member.go index d690563924..4bed40030c 100644 --- a/internal/command/project_member.go +++ b/internal/command/project_member.go @@ -4,11 +4,9 @@ import ( "context" "reflect" - "github.com/zitadel/zitadel/internal/eventstore" - "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" - caos_errs "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/project" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) @@ -35,10 +33,10 @@ func (c *Commands) AddProjectMember(ctx context.Context, member *domain.Member, func (c *Commands) addProjectMember(ctx context.Context, projectAgg *eventstore.Aggregate, addedMember *ProjectMemberWriteModel, member *domain.Member) (eventstore.Command, error) { if !member.IsValid() { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid") } if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectRolePrefix, c.zitadelRoles)) > 0 { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-3m9ds", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-3m9ds", "Errors.Project.Member.Invalid") } err := c.checkUserExists(ctx, addedMember.UserID, "") @@ -56,13 +54,13 @@ func (c *Commands) addProjectMember(ctx context.Context, projectAgg *eventstore. return project.NewProjectMemberAddedEvent(ctx, projectAgg, member.UserID, member.Roles...), nil } -//ChangeProjectMember updates an existing member +// ChangeProjectMember updates an existing member func (c *Commands) ChangeProjectMember(ctx context.Context, member *domain.Member, resourceOwner string) (*domain.Member, error) { if !member.IsValid() { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-LiaZi", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-LiaZi", "Errors.Project.Member.Invalid") } if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectRolePrefix, c.zitadelRoles)) > 0 { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-3m9d", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-3m9d", "Errors.Project.Member.Invalid") } existingMember, err := c.projectMemberWriteModelByID(ctx, member.AggregateID, member.UserID, resourceOwner) @@ -71,7 +69,7 @@ func (c *Commands) ChangeProjectMember(ctx context.Context, member *domain.Membe } if reflect.DeepEqual(existingMember.Roles, member.Roles) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged") + return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged") } projectAgg := ProjectAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) pushedEvents, err := c.eventstore.Push(ctx, project.NewProjectMemberChangedEvent(ctx, projectAgg, member.UserID, member.Roles...)) @@ -89,7 +87,7 @@ func (c *Commands) ChangeProjectMember(ctx context.Context, member *domain.Membe func (c *Commands) RemoveProjectMember(ctx context.Context, projectID, userID, resourceOwner string) (*domain.ObjectDetails, error) { if projectID == "" || userID == "" { - return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-66mHd", "Errors.Project.Member.Invalid") + return nil, errors.ThrowInvalidArgument(nil, "PROJECT-66mHd", "Errors.Project.Member.Invalid") } m, err := c.projectMemberWriteModelByID(ctx, projectID, userID, resourceOwner) if err != nil && !errors.IsNotFound(err) { diff --git a/internal/command/user_human_otp.go b/internal/command/user_human_otp.go index 725a0b10e7..7970aa130e 100644 --- a/internal/command/user_human_otp.go +++ b/internal/command/user_human_otp.go @@ -2,6 +2,7 @@ package command import ( "context" + "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/logging" @@ -17,6 +18,9 @@ func (c *Commands) ImportHumanOTP(ctx context.Context, userID, userAgentID, reso if err != nil { return err } + if err = c.checkUserExists(ctx, userID, resourceowner); err != nil { + return err + } otpWriteModel, err := c.otpWriteModelByID(ctx, userID, resourceowner) if err != nil { diff --git a/internal/command/user_idp_link.go b/internal/command/user_idp_link.go index 4440b64927..fe00476235 100644 --- a/internal/command/user_idp_link.go +++ b/internal/command/user_idp_link.go @@ -58,6 +58,10 @@ func (c *Commands) addUserIDPLink(ctx context.Context, human *eventstore.Aggrega if !link.IsValid() { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid") } + if err := c.checkUserExists(ctx, human.ID, human.ResourceOwner); err != nil { + return nil, err + } + _, err := c.getOrgIDPConfigByID(ctx, link.IDPConfigID, human.ResourceOwner) if caos_errs.IsNotFound(err) { _, err = c.getInstanceIDPConfigByID(ctx, link.IDPConfigID) diff --git a/internal/command/user_idp_link_test.go b/internal/command/user_idp_link_test.go index cefd32ad3f..27229a1ef5 100644 --- a/internal/command/user_idp_link_test.go +++ b/internal/command/user_idp_link_test.go @@ -129,6 +129,23 @@ func TestCommandSide_BulkAddUserIDPLinks(t *testing.T) { fields: fields{ eventstore: eventstoreExpect( t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent( + context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "userName", + "firstName", + "lastName", + "nickName", + "displayName", + language.German, + domain.GenderFemale, + "email@Address.ch", + false, + ), + ), + ), expectFilter(), expectFilter(), ), @@ -156,6 +173,23 @@ func TestCommandSide_BulkAddUserIDPLinks(t *testing.T) { fields: fields{ eventstore: eventstoreExpect( t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent( + context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "userName", + "firstName", + "lastName", + "nickName", + "displayName", + language.German, + domain.GenderFemale, + "email@Address.ch", + false, + ), + ), + ), expectFilter( eventFromEventPusher( org.NewIDPConfigAddedEvent(context.Background(), @@ -205,6 +239,23 @@ func TestCommandSide_BulkAddUserIDPLinks(t *testing.T) { fields: fields{ eventstore: eventstoreExpect( t, + expectFilter( + eventFromEventPusher( + user.NewHumanAddedEvent( + context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "userName", + "firstName", + "lastName", + "nickName", + "displayName", + language.German, + domain.GenderFemale, + "email@Address.ch", + false, + ), + ), + ), expectFilter(), expectFilter( eventFromEventPusher( diff --git a/internal/eventstore/handler/crdb/handler_stmt_test.go b/internal/eventstore/handler/crdb/handler_stmt_test.go index 125bb77ddd..fa245c8eb1 100644 --- a/internal/eventstore/handler/crdb/handler_stmt_test.go +++ b/internal/eventstore/handler/crdb/handler_stmt_test.go @@ -1602,7 +1602,7 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) { }, want: want{ isErr: func(err error) bool { - return errors.As(err, &errSeqNotUpdated) + return errors.Is(err, errSeqNotUpdated) }, expectations: []mockExpectation{ expectUpdateCurrentSequenceNoRows("my_table", "my_projection", 5, "agg", "instanceID"), diff --git a/internal/eventstore/handler/crdb/lock_test.go b/internal/eventstore/handler/crdb/lock_test.go index 24ce3a8aa4..9280e430b6 100644 --- a/internal/eventstore/handler/crdb/lock_test.go +++ b/internal/eventstore/handler/crdb/lock_test.go @@ -167,7 +167,7 @@ func TestStatementHandler_renewLock(t *testing.T) { expectLockNoRows(lockTable, workerName, 2, "instanceID"), }, isErr: func(err error) bool { - return errors.As(err, &renewNoRowsAffectedErr) + return errors.Is(err, renewNoRowsAffectedErr) }, }, args: args{ diff --git a/internal/user/repository/view/model/user.go b/internal/user/repository/view/model/user.go index f8ac3a9260..26122d4e2b 100644 --- a/internal/user/repository/view/model/user.go +++ b/internal/user/repository/view/model/user.go @@ -310,9 +310,17 @@ func (u *UserView) AppendEvent(event *models.Event) (err error) { u.State = int32(model.UserStateLocked) case user.UserV1MFAOTPAddedType, user.HumanMFAOTPAddedType: + if u.HumanView == nil { + logging.WithFields("sequence", event.Sequence, "instance", event.InstanceID).Warn("event is ignored because human not exists") + break + } u.OTPState = int32(model.MFAStateNotReady) case user.UserV1MFAOTPVerifiedType, user.HumanMFAOTPVerifiedType: + if u.HumanView == nil { + logging.WithFields("sequence", event.Sequence, "instance", event.InstanceID).Warn("event is ignored because human not exists") + break + } u.OTPState = int32(model.MFAStateReady) u.MFAInitSkipped = time.Time{} case user.UserV1MFAOTPRemovedType,