-
Notifications
You must be signed in to change notification settings - Fork 875
feat: notify when a user account is deleted #14113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
42f4bd7
9c47637
4e787ec
15fec2b
37bbb41
96fa649
ac5a3e6
085c5bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DELETE FROM notification_templates WHERE id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
INSERT INTO notification_templates (id, name, title_template, body_template, "group", actions) | ||
VALUES ('f44d9314-ad03-4bc8-95d0-5cad491da6b6', 'User account deleted', E'User account "{{.Labels.deleted_account_name}}" deleted', | ||
E'Hi {{.UserName}},\n\nUser account **{{.Labels.deleted_account_name}}** has been deleted.', | ||
'User Events', '[ | ||
{ | ||
"label": "View accounts", | ||
"url": "{{ base_url }}/deployment/users?filter=status%3Aactive" | ||
} | ||
]'::jsonb); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -374,6 +374,90 @@ func TestDeleteUser(t *testing.T) { | |
}) | ||
} | ||
|
||
func TestNotifyDeletedUser(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("OwnerNotified", func(t *testing.T) { | ||
t.Parallel() | ||
|
||
// given | ||
notifyEnq := &testutil.FakeNotificationsEnqueuer{} | ||
adminClient := coderdtest.New(t, &coderdtest.Options{ | ||
NotificationsEnqueuer: notifyEnq, | ||
}) | ||
firstUser := coderdtest.CreateFirstUser(t, adminClient) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) | ||
defer cancel() | ||
|
||
user, err := adminClient.CreateUser(ctx, codersdk.CreateUserRequest{ | ||
OrganizationID: firstUser.OrganizationID, | ||
Email: "another@user.org", | ||
Username: "someone-else", | ||
Password: "SomeSecurePassword!", | ||
}) | ||
require.NoError(t, err) | ||
|
||
// when | ||
err = adminClient.DeleteUser(context.Background(), user.ID) | ||
require.NoError(t, err) | ||
|
||
// then | ||
require.Len(t, notifyEnq.Sent, 2) | ||
// notifyEnq.Sent[0] is create account event | ||
require.Equal(t, notifications.TemplateUserAccountDeleted, notifyEnq.Sent[1].TemplateID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the owner receive an email for their own action? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can't delete your own account, so I believe there is no need to filter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What i mean is: if an owner initiated an event - they should probably not receive a notification about it because it's redundant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that they won't receive as the API method will fail faster? see code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh.. you mean the owner of the action.. not the owner of the account. Interesting case, on the other hand, if somebody took over the account, notifications would work like auditing. |
||
require.Equal(t, firstUser.UserID, notifyEnq.Sent[1].UserID) | ||
require.Contains(t, notifyEnq.Sent[1].Targets, user.ID) | ||
require.Equal(t, user.Username, notifyEnq.Sent[1].Labels["deleted_account_name"]) | ||
}) | ||
|
||
t.Run("UserAdminNotified", func(t *testing.T) { | ||
t.Parallel() | ||
|
||
// given | ||
notifyEnq := &testutil.FakeNotificationsEnqueuer{} | ||
adminClient := coderdtest.New(t, &coderdtest.Options{ | ||
NotificationsEnqueuer: notifyEnq, | ||
}) | ||
firstUser := coderdtest.CreateFirstUser(t, adminClient) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) | ||
defer cancel() | ||
|
||
_, userAdmin := coderdtest.CreateAnotherUser(t, adminClient, firstUser.OrganizationID, rbac.RoleUserAdmin()) | ||
|
||
member, err := adminClient.CreateUser(ctx, codersdk.CreateUserRequest{ | ||
OrganizationID: firstUser.OrganizationID, | ||
Email: "another@user.org", | ||
Username: "someone-else", | ||
Password: "SomeSecurePassword!", | ||
}) | ||
require.NoError(t, err) | ||
|
||
// when | ||
err = adminClient.DeleteUser(context.Background(), member.ID) | ||
require.NoError(t, err) | ||
|
||
// then | ||
require.Len(t, notifyEnq.Sent, 5) | ||
// notifyEnq.Sent[0]: "User admin" account created, "owner" notified | ||
// notifyEnq.Sent[1]: "Member" account created, "owner" notified | ||
// notifyEnq.Sent[2]: "Member" account created, "user admin" notified | ||
|
||
// "Member" account deleted, "owner" notified | ||
require.Equal(t, notifications.TemplateUserAccountDeleted, notifyEnq.Sent[3].TemplateID) | ||
require.Equal(t, firstUser.UserID, notifyEnq.Sent[3].UserID) | ||
require.Contains(t, notifyEnq.Sent[3].Targets, member.ID) | ||
require.Equal(t, member.Username, notifyEnq.Sent[3].Labels["deleted_account_name"]) | ||
|
||
// "Member" account deleted, "user admin" notified | ||
require.Equal(t, notifications.TemplateUserAccountDeleted, notifyEnq.Sent[4].TemplateID) | ||
require.Equal(t, userAdmin.ID, notifyEnq.Sent[4].UserID) | ||
require.Contains(t, notifyEnq.Sent[4].Targets, member.ID) | ||
require.Equal(t, member.Username, notifyEnq.Sent[4].Labels["deleted_account_name"]) | ||
}) | ||
} | ||
|
||
func TestPostLogout(t *testing.T) { | ||
t.Parallel() | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need to include org user admins here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably, I will leave it as a follow-up once the org part is final. Most likely we need to adjust create account logic too.