fix(coderd): use service account wording in account notifications (#27536)

This commit is contained in:
Atif Ali
2026-08-11 13:16:25 +00:00
committed by GitHub
parent 75e0790cd7
commit d7953bd046
23 changed files with 881 additions and 13 deletions
@@ -0,0 +1,35 @@
-- User account created
UPDATE notification_templates
SET
title_template = E'User account "{{.Labels.created_account_name}}" created',
body_template = E'New user account **{{.Labels.created_account_name}}** has been created.\n\n' ||
E'This new user account was created {{if .Labels.created_account_user_name}}for **{{.Labels.created_account_user_name}}** {{end}}by **{{.Labels.initiator}}**.'
WHERE
id = '4e19c0ac-94e1-4532-9515-d1801aa283b2';
-- User account deleted
UPDATE notification_templates
SET
title_template = E'User account "{{.Labels.deleted_account_name}}" deleted',
body_template = E'User account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' ||
E'The deleted account {{if .Labels.deleted_account_user_name}}belonged to **{{.Labels.deleted_account_user_name}}** and {{end}}was deleted by **{{.Labels.initiator}}**.'
WHERE
id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6';
-- User account suspended
UPDATE notification_templates
SET
title_template = E'User account "{{.Labels.suspended_account_name}}" suspended',
body_template = E'User account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' ||
E'The account {{if .Labels.suspended_account_user_name}}belongs to **{{.Labels.suspended_account_user_name}}** and it {{end}}was suspended by **{{.Labels.initiator}}**.'
WHERE
id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d';
-- User account activated
UPDATE notification_templates
SET
title_template = E'User account "{{.Labels.activated_account_name}}" activated',
body_template = E'User account **{{.Labels.activated_account_name}}** has been activated.\n\n' ||
E'The account {{if .Labels.activated_account_user_name}}belongs to **{{.Labels.activated_account_user_name}}** and it {{ end }}was activated by **{{.Labels.initiator}}**.'
WHERE
id = '9f5af851-8408-4e73-a7a1-c6502ba46689';
@@ -0,0 +1,40 @@
-- The account lifecycle notifications also fire for service accounts, so the
-- copy branches on an account type label. Messages enqueued before this
-- migration carry no such label and render the user wording.
-- User account created
UPDATE notification_templates
SET
title_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account "{{.Labels.created_account_name}}" created',
body_template = E'{{ $account := "user" }}{{ if eq .Labels.account_type "service" }}{{ $account = "service" }}{{ end }}' ||
E'New {{ $account }} account **{{.Labels.created_account_name}}** has been created.\n\n' ||
E'This new {{ $account }} account was created {{if .Labels.created_account_user_name}}for **{{.Labels.created_account_user_name}}** {{end}}by **{{.Labels.initiator}}**.'
WHERE
id = '4e19c0ac-94e1-4532-9515-d1801aa283b2';
-- User account deleted
UPDATE notification_templates
SET
title_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account "{{.Labels.deleted_account_name}}" deleted',
body_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' ||
E'The deleted account {{if .Labels.deleted_account_user_name}}belonged to **{{.Labels.deleted_account_user_name}}** and {{end}}was deleted by **{{.Labels.initiator}}**.'
WHERE
id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6';
-- User account suspended
UPDATE notification_templates
SET
title_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account "{{.Labels.suspended_account_name}}" suspended',
body_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' ||
E'The account {{if .Labels.suspended_account_user_name}}belongs to **{{.Labels.suspended_account_user_name}}** and it {{end}}was suspended by **{{.Labels.initiator}}**.'
WHERE
id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d';
-- User account activated
UPDATE notification_templates
SET
title_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account "{{.Labels.activated_account_name}}" activated',
body_template = E'{{ if eq .Labels.account_type "service" }}Service{{ else }}User{{ end }} account **{{.Labels.activated_account_name}}** has been activated.\n\n' ||
E'The account {{if .Labels.activated_account_user_name}}belongs to **{{.Labels.activated_account_user_name}}** and it {{ end }}was activated by **{{.Labels.initiator}}**.'
WHERE
id = '9f5af851-8408-4e73-a7a1-c6502ba46689';
@@ -859,6 +859,38 @@ func TestNotificationTemplates_Golden(t *testing.T) {
{
name: "TemplateUserAccountCreated",
id: notifications.TemplateUserAccountCreated,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"created_account_name": "bobby",
"created_account_user_name": "William Tables",
"initiator": "rob",
"account_type": "user",
},
},
},
{
name: "TemplateUserAccountCreatedServiceAccount",
id: notifications.TemplateUserAccountCreated,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"created_account_name": "ci-bot",
"created_account_user_name": "CI Bot",
"initiator": "rob",
"account_type": "service",
},
},
},
{
// Messages enqueued before the account_type label existed
// must still render the user wording.
name: "TemplateUserAccountCreatedWithoutAccountType",
id: notifications.TemplateUserAccountCreated,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
@@ -881,6 +913,22 @@ func TestNotificationTemplates_Golden(t *testing.T) {
"deleted_account_name": "bobby",
"deleted_account_user_name": "William Tables",
"initiator": "rob",
"account_type": "user",
},
},
},
{
name: "TemplateUserAccountDeletedServiceAccount",
id: notifications.TemplateUserAccountDeleted,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"deleted_account_name": "ci-bot",
"deleted_account_user_name": "CI Bot",
"initiator": "rob",
"account_type": "service",
},
},
},
@@ -895,6 +943,22 @@ func TestNotificationTemplates_Golden(t *testing.T) {
"suspended_account_name": "bobby",
"suspended_account_user_name": "William Tables",
"initiator": "rob",
"account_type": "user",
},
},
},
{
name: "TemplateUserAccountSuspendedServiceAccount",
id: notifications.TemplateUserAccountSuspended,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"suspended_account_name": "ci-bot",
"suspended_account_user_name": "CI Bot",
"initiator": "rob",
"account_type": "service",
},
},
},
@@ -909,6 +973,22 @@ func TestNotificationTemplates_Golden(t *testing.T) {
"activated_account_name": "bobby",
"activated_account_user_name": "William Tables",
"initiator": "rob",
"account_type": "user",
},
},
},
{
name: "TemplateUserAccountActivatedServiceAccount",
id: notifications.TemplateUserAccountActivated,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"activated_account_name": "ci-bot",
"activated_account_user_name": "CI Bot",
"initiator": "rob",
"account_type": "service",
},
},
},
@@ -0,0 +1,82 @@
From: system@coder.com
To: bobby@coder.com
Subject: Service account "ci-bot" activated
Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48
Date: Fri, 11 Oct 2024 09:03:06 +0000
Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
MIME-Version: 1.0
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Hi Bobby,
Service account ci-bot has been activated.
The account belongs to CI Bot and it was activated by rob.
View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<!doctype html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=
=3D1.0" />
<title>Service account "ci-bot" activated</title>
</head>
<body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-=
ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel=
l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617=
; background: #f8fafc;">
<div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde=
r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig=
n: left; font-size: 14px; line-height: 1.5;">
<div style=3D"text-align: center;">
<img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod=
er Logo" style=3D"height: 40px;" />
</div>
<h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m=
argin: 8px 0 32px; line-height: 1.5;">
Service account "ci-bot" activated
</h1>
<div style=3D"line-height: 1.5;">
<p>Hi Bobby,</p>
<p>Service account <strong>ci-bot</strong> has been activated.</p>
<p>The account belongs to <strong>CI Bot</strong> and it was activated by <=
strong>rob</strong>.</p>
</div>
<div style=3D"text-align: center; margin-top: 32px;">
=20
<a href=3D"http://test.com/deployment/users?filter=3Dstatus%3Aactiv=
e" style=3D"display: inline-block; padding: 13px 24px; background-color: #0=
20617; color: #f8fafc; text-decoration: none; border-radius: 8px; margin: 0=
4px;">
View accounts
</a>
=20
</div>
<div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz=
e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
<p>&copy;&nbsp;2024&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a =
href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h=
ttp://test.com</a></p>
<p><a href=3D"http://test.com/settings/notifications" style=3D"colo=
r: #2563eb; text-decoration: none;">Click here to manage your notification =
settings</a></p>
<p><a href=3D"http://test.com/settings/notifications?disabled=3D9f5=
af851-8408-4e73-a7a1-c6502ba46689" style=3D"color: #2563eb; text-decoration=
: none;">Stop receiving emails like this</a></p>
</div>
</div>
</body>
</html>
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4--
@@ -0,0 +1,83 @@
From: system@coder.com
To: bobby@coder.com
Subject: Service account "ci-bot" created
Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48
Date: Fri, 11 Oct 2024 09:03:06 +0000
Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
MIME-Version: 1.0
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Hi Bobby,
New service account ci-bot has been created.
This new service account was created for CI Bot by rob.
View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<!doctype html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=
=3D1.0" />
<title>Service account "ci-bot" created</title>
</head>
<body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-=
ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel=
l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617=
; background: #f8fafc;">
<div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde=
r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig=
n: left; font-size: 14px; line-height: 1.5;">
<div style=3D"text-align: center;">
<img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod=
er Logo" style=3D"height: 40px;" />
</div>
<h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m=
argin: 8px 0 32px; line-height: 1.5;">
Service account "ci-bot" created
</h1>
<div style=3D"line-height: 1.5;">
<p>Hi Bobby,</p>
<p>New service account <strong>ci-bot</strong> has been created.</p=
>
<p>This new service account was created for <strong>CI Bot</strong> by <str=
ong>rob</strong>.</p>
</div>
<div style=3D"text-align: center; margin-top: 32px;">
=20
<a href=3D"http://test.com/deployment/users?filter=3Dstatus%3Aactiv=
e" style=3D"display: inline-block; padding: 13px 24px; background-color: #0=
20617; color: #f8fafc; text-decoration: none; border-radius: 8px; margin: 0=
4px;">
View accounts
</a>
=20
</div>
<div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz=
e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
<p>&copy;&nbsp;2024&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a =
href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h=
ttp://test.com</a></p>
<p><a href=3D"http://test.com/settings/notifications" style=3D"colo=
r: #2563eb; text-decoration: none;">Click here to manage your notification =
settings</a></p>
<p><a href=3D"http://test.com/settings/notifications?disabled=3D4e1=
9c0ac-94e1-4532-9515-d1801aa283b2" style=3D"color: #2563eb; text-decoration=
: none;">Stop receiving emails like this</a></p>
</div>
</div>
</body>
</html>
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4--
@@ -0,0 +1,82 @@
From: system@coder.com
To: bobby@coder.com
Subject: User account "bobby" created
Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48
Date: Fri, 11 Oct 2024 09:03:06 +0000
Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
MIME-Version: 1.0
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Hi Bobby,
New user account bobby has been created.
This new user account was created for William Tables by rob.
View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<!doctype html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=
=3D1.0" />
<title>User account "bobby" created</title>
</head>
<body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-=
ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel=
l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617=
; background: #f8fafc;">
<div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde=
r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig=
n: left; font-size: 14px; line-height: 1.5;">
<div style=3D"text-align: center;">
<img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod=
er Logo" style=3D"height: 40px;" />
</div>
<h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m=
argin: 8px 0 32px; line-height: 1.5;">
User account "bobby" created
</h1>
<div style=3D"line-height: 1.5;">
<p>Hi Bobby,</p>
<p>New user account <strong>bobby</strong> has been created.</p>
<p>This new user account was created for <strong>William Tables</strong> by=
<strong>rob</strong>.</p>
</div>
<div style=3D"text-align: center; margin-top: 32px;">
=20
<a href=3D"http://test.com/deployment/users?filter=3Dstatus%3Aactiv=
e" style=3D"display: inline-block; padding: 13px 24px; background-color: #0=
20617; color: #f8fafc; text-decoration: none; border-radius: 8px; margin: 0=
4px;">
View accounts
</a>
=20
</div>
<div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz=
e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
<p>&copy;&nbsp;2024&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a =
href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h=
ttp://test.com</a></p>
<p><a href=3D"http://test.com/settings/notifications" style=3D"colo=
r: #2563eb; text-decoration: none;">Click here to manage your notification =
settings</a></p>
<p><a href=3D"http://test.com/settings/notifications?disabled=3D4e1=
9c0ac-94e1-4532-9515-d1801aa283b2" style=3D"color: #2563eb; text-decoration=
: none;">Stop receiving emails like this</a></p>
</div>
</div>
</body>
</html>
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4--
@@ -0,0 +1,82 @@
From: system@coder.com
To: bobby@coder.com
Subject: Service account "ci-bot" deleted
Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48
Date: Fri, 11 Oct 2024 09:03:06 +0000
Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
MIME-Version: 1.0
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Hi Bobby,
Service account ci-bot has been deleted.
The deleted account belonged to CI Bot and was deleted by rob.
View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<!doctype html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=
=3D1.0" />
<title>Service account "ci-bot" deleted</title>
</head>
<body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-=
ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel=
l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617=
; background: #f8fafc;">
<div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde=
r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig=
n: left; font-size: 14px; line-height: 1.5;">
<div style=3D"text-align: center;">
<img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod=
er Logo" style=3D"height: 40px;" />
</div>
<h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m=
argin: 8px 0 32px; line-height: 1.5;">
Service account "ci-bot" deleted
</h1>
<div style=3D"line-height: 1.5;">
<p>Hi Bobby,</p>
<p>Service account <strong>ci-bot</strong> has been deleted.</p>
<p>The deleted account belonged to <strong>CI Bot</strong> and was deleted =
by <strong>rob</strong>.</p>
</div>
<div style=3D"text-align: center; margin-top: 32px;">
=20
<a href=3D"http://test.com/deployment/users?filter=3Dstatus%3Aactiv=
e" style=3D"display: inline-block; padding: 13px 24px; background-color: #0=
20617; color: #f8fafc; text-decoration: none; border-radius: 8px; margin: 0=
4px;">
View accounts
</a>
=20
</div>
<div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz=
e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
<p>&copy;&nbsp;2024&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a =
href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h=
ttp://test.com</a></p>
<p><a href=3D"http://test.com/settings/notifications" style=3D"colo=
r: #2563eb; text-decoration: none;">Click here to manage your notification =
settings</a></p>
<p><a href=3D"http://test.com/settings/notifications?disabled=3Df44=
d9314-ad03-4bc8-95d0-5cad491da6b6" style=3D"color: #2563eb; text-decoration=
: none;">Stop receiving emails like this</a></p>
</div>
</div>
</body>
</html>
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4--
@@ -0,0 +1,83 @@
From: system@coder.com
To: bobby@coder.com
Subject: Service account "ci-bot" suspended
Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48
Date: Fri, 11 Oct 2024 09:03:06 +0000
Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
MIME-Version: 1.0
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Hi Bobby,
Service account ci-bot has been suspended.
The account belongs to CI Bot and it was suspended by rob.
View suspended accounts: http://test.com/deployment/users?filter=3Dstatus%3=
Asuspended
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<!doctype html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=
=3D1.0" />
<title>Service account "ci-bot" suspended</title>
</head>
<body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-=
ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel=
l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617=
; background: #f8fafc;">
<div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde=
r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig=
n: left; font-size: 14px; line-height: 1.5;">
<div style=3D"text-align: center;">
<img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod=
er Logo" style=3D"height: 40px;" />
</div>
<h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m=
argin: 8px 0 32px; line-height: 1.5;">
Service account "ci-bot" suspended
</h1>
<div style=3D"line-height: 1.5;">
<p>Hi Bobby,</p>
<p>Service account <strong>ci-bot</strong> has been suspended.</p>
<p>The account belongs to <strong>CI Bot</strong> and it was suspended by <=
strong>rob</strong>.</p>
</div>
<div style=3D"text-align: center; margin-top: 32px;">
=20
<a href=3D"http://test.com/deployment/users?filter=3Dstatus%3Asuspe=
nded" style=3D"display: inline-block; padding: 13px 24px; background-color:=
#020617; color: #f8fafc; text-decoration: none; border-radius: 8px; margin=
: 0 4px;">
View suspended accounts
</a>
=20
</div>
<div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz=
e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;">
<p>&copy;&nbsp;2024&nbsp;Coder. All rights reserved&nbsp;-&nbsp;<a =
href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h=
ttp://test.com</a></p>
<p><a href=3D"http://test.com/settings/notifications" style=3D"colo=
r: #2563eb; text-decoration: none;">Click here to manage your notification =
settings</a></p>
<p><a href=3D"http://test.com/settings/notifications?disabled=3Db02=
ddd82-4733-4d02-a2d7-c36f3598997d" style=3D"color: #2563eb; text-decoration=
: none;">Stop receiving emails like this</a></p>
</div>
</div>
</body>
</html>
--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4--
@@ -16,6 +16,7 @@
}
],
"labels": {
"account_type": "user",
"activated_account_name": "bobby",
"activated_account_user_name": "William Tables",
"initiator": "rob"
@@ -0,0 +1,31 @@
{
"_version": "1.1",
"msg_id": "00000000-0000-0000-0000-000000000000",
"payload": {
"_version": "1.2",
"notification_name": "User account activated",
"notification_template_id": "00000000-0000-0000-0000-000000000000",
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "bobby@coder.com",
"user_name": "Bobby",
"user_username": "bobby",
"actions": [
{
"label": "View accounts",
"url": "http://test.com/deployment/users?filter=status%3Aactive"
}
],
"labels": {
"account_type": "service",
"activated_account_name": "ci-bot",
"activated_account_user_name": "CI Bot",
"initiator": "rob"
},
"data": null,
"targets": null
},
"title": "Service account \"ci-bot\" activated",
"title_markdown": "Service account \"ci-bot\" activated",
"body": "Service account ci-bot has been activated.\n\nThe account belongs to CI Bot and it was activated by rob.",
"body_markdown": "Service account **ci-bot** has been activated.\n\nThe account belongs to **CI Bot** and it was activated by **rob**."
}
@@ -16,6 +16,7 @@
}
],
"labels": {
"account_type": "user",
"created_account_name": "bobby",
"created_account_user_name": "William Tables",
"initiator": "rob"
@@ -0,0 +1,31 @@
{
"_version": "1.1",
"msg_id": "00000000-0000-0000-0000-000000000000",
"payload": {
"_version": "1.2",
"notification_name": "User account created",
"notification_template_id": "00000000-0000-0000-0000-000000000000",
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "bobby@coder.com",
"user_name": "Bobby",
"user_username": "bobby",
"actions": [
{
"label": "View accounts",
"url": "http://test.com/deployment/users?filter=status%3Aactive"
}
],
"labels": {
"account_type": "service",
"created_account_name": "ci-bot",
"created_account_user_name": "CI Bot",
"initiator": "rob"
},
"data": null,
"targets": null
},
"title": "Service account \"ci-bot\" created",
"title_markdown": "Service account \"ci-bot\" created",
"body": "New service account ci-bot has been created.\n\nThis new service account was created for CI Bot by rob.",
"body_markdown": "New service account **ci-bot** has been created.\n\nThis new service account was created for **CI Bot** by **rob**."
}
@@ -0,0 +1,30 @@
{
"_version": "1.1",
"msg_id": "00000000-0000-0000-0000-000000000000",
"payload": {
"_version": "1.2",
"notification_name": "User account created",
"notification_template_id": "00000000-0000-0000-0000-000000000000",
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "bobby@coder.com",
"user_name": "Bobby",
"user_username": "bobby",
"actions": [
{
"label": "View accounts",
"url": "http://test.com/deployment/users?filter=status%3Aactive"
}
],
"labels": {
"created_account_name": "bobby",
"created_account_user_name": "William Tables",
"initiator": "rob"
},
"data": null,
"targets": null
},
"title": "User account \"bobby\" created",
"title_markdown": "User account \"bobby\" created",
"body": "New user account bobby has been created.\n\nThis new user account was created for William Tables by rob.",
"body_markdown": "New user account **bobby** has been created.\n\nThis new user account was created for **William Tables** by **rob**."
}
@@ -16,6 +16,7 @@
}
],
"labels": {
"account_type": "user",
"deleted_account_name": "bobby",
"deleted_account_user_name": "William Tables",
"initiator": "rob"
@@ -0,0 +1,31 @@
{
"_version": "1.1",
"msg_id": "00000000-0000-0000-0000-000000000000",
"payload": {
"_version": "1.2",
"notification_name": "User account deleted",
"notification_template_id": "00000000-0000-0000-0000-000000000000",
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "bobby@coder.com",
"user_name": "Bobby",
"user_username": "bobby",
"actions": [
{
"label": "View accounts",
"url": "http://test.com/deployment/users?filter=status%3Aactive"
}
],
"labels": {
"account_type": "service",
"deleted_account_name": "ci-bot",
"deleted_account_user_name": "CI Bot",
"initiator": "rob"
},
"data": null,
"targets": null
},
"title": "Service account \"ci-bot\" deleted",
"title_markdown": "Service account \"ci-bot\" deleted",
"body": "Service account ci-bot has been deleted.\n\nThe deleted account belonged to CI Bot and was deleted by rob.",
"body_markdown": "Service account **ci-bot** has been deleted.\n\nThe deleted account belonged to **CI Bot** and was deleted by **rob**."
}
@@ -16,6 +16,7 @@
}
],
"labels": {
"account_type": "user",
"initiator": "rob",
"suspended_account_name": "bobby",
"suspended_account_user_name": "William Tables"
@@ -0,0 +1,31 @@
{
"_version": "1.1",
"msg_id": "00000000-0000-0000-0000-000000000000",
"payload": {
"_version": "1.2",
"notification_name": "User account suspended",
"notification_template_id": "00000000-0000-0000-0000-000000000000",
"user_id": "00000000-0000-0000-0000-000000000000",
"user_email": "bobby@coder.com",
"user_name": "Bobby",
"user_username": "bobby",
"actions": [
{
"label": "View suspended accounts",
"url": "http://test.com/deployment/users?filter=status%3Asuspended"
}
],
"labels": {
"account_type": "service",
"initiator": "rob",
"suspended_account_name": "ci-bot",
"suspended_account_user_name": "CI Bot"
},
"data": null,
"targets": null
},
"title": "Service account \"ci-bot\" suspended",
"title_markdown": "Service account \"ci-bot\" suspended",
"body": "Service account ci-bot has been suspended.\n\nThe account belongs to CI Bot and it was suspended by rob.",
"body_markdown": "Service account **ci-bot** has been suspended.\n\nThe account belongs to **CI Bot** and it was suspended by **rob**."
}
+15
View File
@@ -740,6 +740,7 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) {
"deleted_account_name": user.Username,
"deleted_account_user_name": user.Name,
"initiator": accountDeleter.Name,
"account_type": accountTypeLabel(user),
},
"api-users-delete",
user.ID,
@@ -1078,6 +1079,7 @@ func (api *API) notifyUserStatusChanged(ctx context.Context, actingUserName stri
"suspended_account_name": targetUser.Username,
"suspended_account_user_name": targetUser.Name,
"initiator": actingUserName,
"account_type": accountTypeLabel(targetUser),
}
data = map[string]any{
"user": map[string]any{"id": targetUser.ID, "name": targetUser.Name, "email": targetUser.Email},
@@ -1089,6 +1091,7 @@ func (api *API) notifyUserStatusChanged(ctx context.Context, actingUserName stri
"activated_account_name": targetUser.Username,
"activated_account_user_name": targetUser.Name,
"initiator": actingUserName,
"account_type": accountTypeLabel(targetUser),
}
data = map[string]any{
"user": map[string]any{"id": targetUser.ID, "name": targetUser.Name, "email": targetUser.Email},
@@ -2038,6 +2041,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
return user, xerrors.Errorf("find user admins: %w", err)
}
accountType := accountTypeLabel(user)
for _, u := range userAdmins {
if u.ID == user.ID {
// If the new user is an admin, don't notify them about themselves.
@@ -2052,6 +2057,7 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
"created_account_name": user.Username,
"created_account_user_name": user.Name,
"initiator": req.accountCreatorName,
"account_type": accountType,
},
map[string]any{
"user": map[string]any{"id": user.ID, "name": user.Name, "email": user.Email},
@@ -2066,6 +2072,15 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
return user, err
}
// accountTypeLabel returns the notification label value that account lifecycle
// templates branch on to describe the account as a user or a service account.
func accountTypeLabel(u database.User) string {
if u.IsServiceAccount {
return "service"
}
return "user"
}
// findUserAdmins fetches all users with user admin permission including owners.
func findUserAdmins(ctx context.Context, store database.Store) ([]database.GetUsersRow, error) {
userAdmins, err := store.GetUsers(ctx, database.GetUsersParams{
+2
View File
@@ -743,6 +743,7 @@ func TestNotifyDeletedUser(t *testing.T) {
require.Equal(t, user.Username, notifyEnq.Sent()[1].Labels["deleted_account_name"])
require.Equal(t, user.Name, notifyEnq.Sent()[1].Labels["deleted_account_user_name"])
require.Equal(t, firstUser.Name, notifyEnq.Sent()[1].Labels["initiator"])
require.Equal(t, "user", notifyEnq.Sent()[1].Labels["account_type"])
})
t.Run("UserAdminNotified", func(t *testing.T) {
@@ -1131,6 +1132,7 @@ func TestNotifyCreatedUser(t *testing.T) {
require.Equal(t, firstUser.UserID, sent[0].UserID)
require.Contains(t, sent[0].Targets, user.ID)
require.Equal(t, user.Username, sent[0].Labels["created_account_name"])
require.Equal(t, "user", sent[0].Labels["account_type"])
require.IsType(t, map[string]any{}, sent[0].Data["user"])
userData := sent[0].Data["user"].(map[string]any)