From ca4b141217a1177b9aae122a0131320bb9514a00 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 26 Sep 2023 19:13:14 +0200 Subject: [PATCH] support user domain claimed --- .../handlers/user_notifier_test.go | 273 ++++++++++++------ internal/repository/user/user.go | 5 + 2 files changed, 185 insertions(+), 93 deletions(-) diff --git a/internal/notification/handlers/user_notifier_test.go b/internal/notification/handlers/user_notifier_test.go index 6bbb009e33..3a5e067146 100644 --- a/internal/notification/handlers/user_notifier_test.go +++ b/internal/notification/handlers/user_notifier_test.go @@ -430,99 +430,6 @@ func Test_userNotifier_reduceEmailCodeAdded(t *testing.T) { } } -func Test_userNotifier_reducePasswordChanged(t *testing.T) { - expectMailSubject := "Password of user has changed" - tests := []struct { - name string - test func(*gomock.Controller, *mock.MockQueries, *mock.MockCommands) (fields, args, want) - }{{ - name: "asset url with event trigger url", - test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { - givenTemplate := "{{.LogoURL}}" - expectContent := fmt.Sprintf("%s%s/%s/%s", eventOrigin, assetsPath, policyID, logoURL) - w.message = messages.Email{ - Recipients: []string{lastEmail}, - Subject: expectMailSubject, - Content: expectContent, - } - queries.EXPECT().NotificationPolicyByOrg(gomock.Any(), gomock.Any(), orgID, gomock.Any()).Return(&query.NotificationPolicy{ - PasswordChange: true, - }, nil) - expectTemplateQueries(queries, givenTemplate) - commands.EXPECT().PasswordChangeSent(gomock.Any(), orgID, userID).Return(nil) - return fields{ - queries: queries, - commands: commands, - es: eventstore.NewEventstore(eventstore.TestConfig( - es_repo_mock.NewRepo(t).ExpectFilterEvents(), - )), - }, args{ - event: &user.HumanPasswordChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ - AggregateID: userID, - ResourceOwner: sql.NullString{String: orgID}, - CreationDate: time.Now().UTC(), - }), - TriggeredAtOrigin: eventOrigin, - }, - }, w - }, - }, { - name: "asset url without event trigger url", - test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { - givenTemplate := "{{.LogoURL}}" - expectContent := fmt.Sprintf("%s://%s:%d%s/%s/%s", externalProtocol, instancePrimaryDomain, externalPort, assetsPath, policyID, logoURL) - w.message = messages.Email{ - Recipients: []string{lastEmail}, - Subject: expectMailSubject, - Content: expectContent, - } - queries.EXPECT().NotificationPolicyByOrg(gomock.Any(), gomock.Any(), orgID, gomock.Any()).Return(&query.NotificationPolicy{ - PasswordChange: true, - }, nil) - queries.EXPECT().SearchInstanceDomains(gomock.Any(), gomock.Any()).Return(&query.InstanceDomains{ - Domains: []*query.InstanceDomain{{ - Domain: instancePrimaryDomain, - IsPrimary: true, - }}, - }, nil) - expectTemplateQueries(queries, givenTemplate) - commands.EXPECT().PasswordChangeSent(gomock.Any(), orgID, userID).Return(nil) - return fields{ - queries: queries, - commands: commands, - es: eventstore.NewEventstore(eventstore.TestConfig( - es_repo_mock.NewRepo(t).ExpectFilterEvents(), - )), - }, args{ - event: &user.HumanPasswordChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ - AggregateID: userID, - ResourceOwner: sql.NullString{String: orgID}, - CreationDate: time.Now().UTC(), - }), - }, - }, w - }, - }} - fs, err := statik_fs.NewWithNamespace("notification") - assert.NoError(t, err) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - queries := mock.NewMockQueries(ctrl) - commands := mock.NewMockCommands(ctrl) - f, a, w := tt.test(ctrl, queries, commands) - _, err = newUserNotifier(t, ctrl, queries, fs, f, a, w).reducePasswordChanged(a.event) - if w.err != nil { - w.err(t, err) - } else { - assert.NoError(t, err) - } - }) - } -} - func Test_userNotifier_reducePasswordCodeAdded(t *testing.T) { expectMailSubject := "Reset password" tests := []struct { @@ -738,6 +645,186 @@ func Test_userNotifier_reducePasswordCodeAdded(t *testing.T) { } } +func Test_userNotifier_reducePasswordChanged(t *testing.T) { + expectMailSubject := "Password of user has changed" + tests := []struct { + name string + test func(*gomock.Controller, *mock.MockQueries, *mock.MockCommands) (fields, args, want) + }{{ + name: "asset url with event trigger url", + test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { + givenTemplate := "{{.LogoURL}}" + expectContent := fmt.Sprintf("%s%s/%s/%s", eventOrigin, assetsPath, policyID, logoURL) + w.message = messages.Email{ + Recipients: []string{lastEmail}, + Subject: expectMailSubject, + Content: expectContent, + } + queries.EXPECT().NotificationPolicyByOrg(gomock.Any(), gomock.Any(), orgID, gomock.Any()).Return(&query.NotificationPolicy{ + PasswordChange: true, + }, nil) + expectTemplateQueries(queries, givenTemplate) + commands.EXPECT().PasswordChangeSent(gomock.Any(), orgID, userID).Return(nil) + return fields{ + queries: queries, + commands: commands, + es: eventstore.NewEventstore(eventstore.TestConfig( + es_repo_mock.NewRepo(t).ExpectFilterEvents(), + )), + }, args{ + event: &user.HumanPasswordChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ + AggregateID: userID, + ResourceOwner: sql.NullString{String: orgID}, + CreationDate: time.Now().UTC(), + }), + TriggeredAtOrigin: eventOrigin, + }, + }, w + }, + }, { + name: "asset url without event trigger url", + test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { + givenTemplate := "{{.LogoURL}}" + expectContent := fmt.Sprintf("%s://%s:%d%s/%s/%s", externalProtocol, instancePrimaryDomain, externalPort, assetsPath, policyID, logoURL) + w.message = messages.Email{ + Recipients: []string{lastEmail}, + Subject: expectMailSubject, + Content: expectContent, + } + queries.EXPECT().NotificationPolicyByOrg(gomock.Any(), gomock.Any(), orgID, gomock.Any()).Return(&query.NotificationPolicy{ + PasswordChange: true, + }, nil) + queries.EXPECT().SearchInstanceDomains(gomock.Any(), gomock.Any()).Return(&query.InstanceDomains{ + Domains: []*query.InstanceDomain{{ + Domain: instancePrimaryDomain, + IsPrimary: true, + }}, + }, nil) + expectTemplateQueries(queries, givenTemplate) + commands.EXPECT().PasswordChangeSent(gomock.Any(), orgID, userID).Return(nil) + return fields{ + queries: queries, + commands: commands, + es: eventstore.NewEventstore(eventstore.TestConfig( + es_repo_mock.NewRepo(t).ExpectFilterEvents(), + )), + }, args{ + event: &user.HumanPasswordChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ + AggregateID: userID, + ResourceOwner: sql.NullString{String: orgID}, + CreationDate: time.Now().UTC(), + }), + }, + }, w + }, + }} + fs, err := statik_fs.NewWithNamespace("notification") + assert.NoError(t, err) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + queries := mock.NewMockQueries(ctrl) + commands := mock.NewMockCommands(ctrl) + f, a, w := tt.test(ctrl, queries, commands) + _, err = newUserNotifier(t, ctrl, queries, fs, f, a, w).reducePasswordChanged(a.event) + if w.err != nil { + w.err(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_userNotifier_reduceDomainClaimed(t *testing.T) { + expectMailSubject := "Domain has been claimed" + tests := []struct { + name string + test func(*gomock.Controller, *mock.MockQueries, *mock.MockCommands) (fields, args, want) + }{{ + name: "asset url with event trigger url", + test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { + givenTemplate := "{{.LogoURL}}" + expectContent := fmt.Sprintf("%s%s/%s/%s", eventOrigin, assetsPath, policyID, logoURL) + w.message = messages.Email{ + Recipients: []string{lastEmail}, + Subject: expectMailSubject, + Content: expectContent, + } + expectTemplateQueries(queries, givenTemplate) + commands.EXPECT().UserDomainClaimedSent(gomock.Any(), orgID, userID).Return(nil) + return fields{ + queries: queries, + commands: commands, + es: eventstore.NewEventstore(eventstore.TestConfig( + es_repo_mock.NewRepo(t).ExpectFilterEvents(), + )), + }, args{ + event: &user.DomainClaimedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ + AggregateID: userID, + ResourceOwner: sql.NullString{String: orgID}, + CreationDate: time.Now().UTC(), + }), + TriggeredAtOrigin: eventOrigin, + }, + }, w + }, + }, { + name: "asset url without event trigger url", + test: func(ctrl *gomock.Controller, queries *mock.MockQueries, commands *mock.MockCommands) (f fields, a args, w want) { + givenTemplate := "{{.LogoURL}}" + expectContent := fmt.Sprintf("%s://%s:%d%s/%s/%s", externalProtocol, instancePrimaryDomain, externalPort, assetsPath, policyID, logoURL) + w.message = messages.Email{ + Recipients: []string{lastEmail}, + Subject: expectMailSubject, + Content: expectContent, + } + queries.EXPECT().SearchInstanceDomains(gomock.Any(), gomock.Any()).Return(&query.InstanceDomains{ + Domains: []*query.InstanceDomain{{ + Domain: instancePrimaryDomain, + IsPrimary: true, + }}, + }, nil) + expectTemplateQueries(queries, givenTemplate) + commands.EXPECT().UserDomainClaimedSent(gomock.Any(), orgID, userID).Return(nil) + return fields{ + queries: queries, + commands: commands, + es: eventstore.NewEventstore(eventstore.TestConfig( + es_repo_mock.NewRepo(t).ExpectFilterEvents(), + )), + }, args{ + event: &user.DomainClaimedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(&repository.Event{ + AggregateID: userID, + ResourceOwner: sql.NullString{String: orgID}, + CreationDate: time.Now().UTC(), + }), + }, + }, w + }, + }} + fs, err := statik_fs.NewWithNamespace("notification") + assert.NoError(t, err) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + queries := mock.NewMockQueries(ctrl) + commands := mock.NewMockCommands(ctrl) + f, a, w := tt.test(ctrl, queries, commands) + _, err = newUserNotifier(t, ctrl, queries, fs, f, a, w).reduceDomainClaimed(a.event) + if w.err != nil { + w.err(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + type fields struct { queries *mock.MockQueries commands *mock.MockCommands diff --git a/internal/repository/user/user.go b/internal/repository/user/user.go index a35ebe8095..7c990cdc4c 100644 --- a/internal/repository/user/user.go +++ b/internal/repository/user/user.go @@ -315,6 +315,7 @@ type DomainClaimedEvent struct { eventstore.BaseEvent `json:"-"` UserName string `json:"userName"` + TriggeredAtOrigin string `json:"base_url,omitempty"` oldUserName string userLoginMustBeDomain bool } @@ -330,6 +331,10 @@ func (e *DomainClaimedEvent) UniqueConstraints() []*eventstore.EventUniqueConstr } } +func (e *DomainClaimedEvent) TriggerOrigin() string { + return e.TriggeredAtOrigin +} + func NewDomainClaimedEvent( ctx context.Context, aggregate *eventstore.Aggregate,