Skip to content

Commit

Permalink
Add Channel.email property
Browse files Browse the repository at this point in the history
It replaces:

* Channel.email_value
* Channel.email_notify_up
* Channel.email_notify_down
  • Loading branch information
cuu508 committed Sep 11, 2023
1 parent ccc8faa commit dcf9f32
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 49 deletions.
2 changes: 1 addition & 1 deletion hc/accounts/management/commands/senddeletionscheduled.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def send_channel_notifications(self, profile, skip_emails):
f"please contact {settings.SUPPORT_EMAIL} ASAP."
)
for channel in Channel.objects.filter(project__owner_id=profile.user_id):
if channel.kind == "email" and channel.email_value in skip_emails:
if channel.kind == "email" and channel.email.value in skip_emails:
continue

dummy = Check(name=name, desc=desc, status="down", project=channel.project)
Expand Down
4 changes: 2 additions & 2 deletions hc/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def created_(self, obj):
def project_(self, obj):
url = self.view_on_site(obj)
name = escape(obj.project_name or "Default")
email = escape(obj.email)
email = escape(obj.owner_email)
return f"{email} &rsaquo; <a href='{url}'>{name}</a>"

def time(self, obj):
Expand All @@ -230,7 +230,7 @@ def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(project_code=F("project__code"))
qs = qs.annotate(project_name=F("project__name"))
qs = qs.annotate(email=F("project__owner__email"))
qs = qs.annotate(owner_email=F("project__owner__email"))
return qs

def view_on_site(self, obj):
Expand Down
42 changes: 18 additions & 24 deletions hc/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,20 @@ class PhoneConf(BaseModel):
notify_down: bool | None = Field(None, alias="down")


class EmailConf(BaseModel):
value: str
notify_up: bool = Field(alias="up")
notify_down: bool = Field(alias="down")

@classmethod
def load(cls, data: Any) -> EmailConf:
# Is it a plain email address?
if not data.startswith("{"):
return cls.model_validate({"value": data, "up": True, "down": True})

return super().model_validate_json(data)


class Channel(models.Model):
name = models.CharField(max_length=100, blank=True)
code = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
Expand All @@ -745,7 +759,7 @@ def __str__(self) -> str:
if self.name:
return self.name
if self.kind == "email":
return "Email to %s" % self.email_value
return "Email to %s" % self.email.value
elif self.kind == "sms":
return "SMS to %s" % self.phone.value
elif self.kind == "slack":
Expand Down Expand Up @@ -779,7 +793,7 @@ def send_verify_link(self) -> None:
args = [self.code, self.make_token()]
verify_link = reverse("hc-verify-email", args=args)
verify_link = settings.SITE_ROOT + verify_link
emails.verify_email(self.email_value, {"verify_link": verify_link})
emails.verify_email(self.email.value, {"verify_link": verify_link})

def get_unsub_link(self) -> str:
signer = TimestampSigner(salt="alerts")
Expand Down Expand Up @@ -977,28 +991,8 @@ def trello_board_list(self) -> tuple[str, str]:
return doc["board_name"], doc["list_name"]

@property
def email_value(self) -> str:
assert self.kind == "email"
if not self.value.startswith("{"):
return self.value

return self.json["value"]

@property
def email_notify_up(self) -> bool:
assert self.kind == "email"
if not self.value.startswith("{"):
return True

return self.json.get("up")

@property
def email_notify_down(self) -> bool:
assert self.kind == "email"
if not self.value.startswith("{"):
return True

return self.json.get("down")
def email(self) -> EmailConf:
return EmailConf.load(self.value)

@property
def opsgenie_key(self) -> str:
Expand Down
4 changes: 3 additions & 1 deletion hc/api/tests/test_flip_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ def test_select_channels_works(self) -> None:
self.assertEqual(channels, [self.channel])

def test_select_channels_handles_noop(self) -> None:
self.channel.value = json.dumps({"down": False})
self.channel.value = json.dumps(
{"value": "alice@example.org", "up": False, "down": False}
)
self.channel.save()

channels = self.flip.select_channels()
Expand Down
8 changes: 4 additions & 4 deletions hc/api/transports.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def notify(self, check: Check, notification: Notification | None = None) -> None
# If this email address has an associated account, include
# a summary of projects the account has access to
try:
profile = Profile.objects.get(user__email=self.channel.email_value)
profile = Profile.objects.get(user__email=self.channel.email.value)
projects = list(profile.projects())
except Profile.DoesNotExist:
projects = None
Expand All @@ -170,13 +170,13 @@ def notify(self, check: Check, notification: Notification | None = None) -> None
"unsub_link": unsub_link,
}

emails.alert(self.channel.email_value, ctx, headers)
emails.alert(self.channel.email.value, ctx, headers)

def is_noop(self, check: Check) -> bool:
if check.status == "down":
return not self.channel.email_notify_down
return not self.channel.email.notify_down
else:
return not self.channel.email_notify_up
return not self.channel.email.notify_up


class Shell(Transport):
Expand Down
18 changes: 9 additions & 9 deletions hc/front/tests/test_edit_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def test_it_saves_changes(self) -> None:
self.assertRedirects(r, self.channels_url)

self.channel.refresh_from_db()
self.assertEqual(self.channel.email_value, "new@example.org")
self.assertTrue(self.channel.email_notify_down)
self.assertFalse(self.channel.email_notify_up)
self.assertEqual(self.channel.email.value, "new@example.org")
self.assertTrue(self.channel.email.notify_down)
self.assertFalse(self.channel.email.notify_up)

# It should send a verification link
email = mail.outbox[0]
Expand All @@ -58,9 +58,9 @@ def test_it_skips_verification_if_email_unchanged(self) -> None:
self.client.post(self.url, form)

self.channel.refresh_from_db()
self.assertEqual(self.channel.email_value, "alerts@example.org")
self.assertFalse(self.channel.email_notify_down)
self.assertTrue(self.channel.email_notify_up)
self.assertEqual(self.channel.email.value, "alerts@example.org")
self.assertFalse(self.channel.email.notify_down)
self.assertTrue(self.channel.email.notify_up)
self.assertTrue(self.channel.email_verified)

# The email address did not change, so we should skip verification
Expand All @@ -73,7 +73,7 @@ def test_team_access_works(self) -> None:
self.client.post(self.url, form)

self.channel.refresh_from_db()
self.assertEqual(self.channel.email_value, "new@example.org")
self.assertEqual(self.channel.email.value, "new@example.org")

@override_settings(EMAIL_USE_VERIFICATION=False)
def test_it_hides_confirmation_needed_notice(self) -> None:
Expand All @@ -90,7 +90,7 @@ def test_it_auto_verifies_email(self) -> None:
self.assertRedirects(r, self.channels_url)

self.channel.refresh_from_db()
self.assertEqual(self.channel.email_value, "dan@example.org")
self.assertEqual(self.channel.email.value, "dan@example.org")

# Email should *not* have been sent
self.assertEqual(len(mail.outbox), 0)
Expand All @@ -103,7 +103,7 @@ def test_it_auto_verifies_own_email(self) -> None:
self.assertRedirects(r, self.channels_url)

self.channel.refresh_from_db()
self.assertEqual(self.channel.email_value, "alice@example.org")
self.assertEqual(self.channel.email.value, "alice@example.org")

# Email should *not* have been sent
self.assertEqual(len(mail.outbox), 0)
Expand Down
8 changes: 4 additions & 4 deletions hc/front/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,7 @@ def email_form(request: HttpRequest, channel: Channel) -> HttpResponse:
if request.method == "POST":
form = forms.EmailForm(request.POST)
if form.is_valid():
if channel.disabled or form.cleaned_data["value"] != channel.email_value:
if channel.disabled or form.cleaned_data["value"] != channel.email.value:
channel.disabled = False

if not settings.EMAIL_USE_VERIFICATION:
Expand Down Expand Up @@ -1284,9 +1284,9 @@ def email_form(request: HttpRequest, channel: Channel) -> HttpResponse:
else:
form = forms.EmailForm(
{
"value": channel.email_value,
"up": channel.email_notify_up,
"down": channel.email_notify_down,
"value": channel.email.value,
"up": channel.email.notify_up,
"down": channel.email.notify_down,
}
)

Expand Down
6 changes: 3 additions & 3 deletions templates/front/channels.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
{% endif %}
<div class="channel-details-mini">
{% if ch.kind == "email" %}
Email to <span>{{ ch.email_value }}</span>
{% if ch.email_notify_down and not ch.email_notify_up %}
Email to <span>{{ ch.email.value }}</span>
{% if ch.email.notify_down and not ch.email.notify_up %}
(down only)
{% endif %}
{% if ch.email_notify_up and not ch.email_notify_down %}
{% if ch.email.notify_up and not ch.email.notify_down %}
(up only)
{% endif %}
{% elif ch.kind == "pd" %}
Expand Down
2 changes: 1 addition & 1 deletion templates/front/event_summary.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% if event.channel.kind == "email" %}
Sent email to {{ event.channel.email_value }}
Sent email to {{ event.channel.email.value }}
{% elif event.channel.kind == "slack" %}
Sent Slack alert
{% if event.channel.slack_channel %}
Expand Down

0 comments on commit dcf9f32

Please sign in to comment.