forked from GithubBackups/healthchecks
Removing unused /api/v1/notifications/{uuid}/bounce endpoint
This commit is contained in:
parent
a29b82a0ed
commit
8ea510cda6
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
## Improvements
|
## Improvements
|
||||||
- Django 3.1
|
- Django 3.1
|
||||||
- Handle status callbacks from Twilio, show delivery failures in Integrations
|
- Handle status callbacks from Twilio, show delivery failures in Integrations
|
||||||
|
- Removing unused /api/v1/notifications/{uuid}/bounce endpoint
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
- Handle excessively long email addresses in the signup form.
|
- Handle excessively long email addresses in the signup form.
|
||||||
|
@ -484,7 +484,6 @@ class Channel(models.Model):
|
|||||||
|
|
||||||
# These are not database fields. It is just a convenient way to pass
|
# These are not database fields. It is just a convenient way to pass
|
||||||
# status_url to transport classes.
|
# status_url to transport classes.
|
||||||
check.bounce_url = n.bounce_url()
|
|
||||||
check.status_url = n.status_url()
|
check.status_url = n.status_url()
|
||||||
|
|
||||||
error = self.transport.notify(check) or ""
|
error = self.transport.notify(check) or ""
|
||||||
@ -760,9 +759,6 @@ class Notification(models.Model):
|
|||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
error = models.CharField(max_length=200, blank=True)
|
error = models.CharField(max_length=200, blank=True)
|
||||||
|
|
||||||
def bounce_url(self):
|
|
||||||
return settings.SITE_ROOT + reverse("hc-api-bounce", args=[self.code])
|
|
||||||
|
|
||||||
def status_url(self):
|
def status_url(self):
|
||||||
path = reverse("hc-api-notification-status", args=[self.code])
|
path = reverse("hc-api-notification-status", args=[self.code])
|
||||||
return settings.SITE_ROOT + path
|
return settings.SITE_ROOT + path
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
from hc.api.models import Channel, Check, Notification
|
|
||||||
from hc.test import BaseTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class BounceTestCase(BaseTestCase):
|
|
||||||
def setUp(self):
|
|
||||||
super(BounceTestCase, self).setUp()
|
|
||||||
|
|
||||||
self.check = Check(project=self.project, status="up")
|
|
||||||
self.check.save()
|
|
||||||
|
|
||||||
self.channel = Channel(project=self.project, kind="email")
|
|
||||||
self.channel.value = "alice@example.org"
|
|
||||||
self.channel.email_verified = True
|
|
||||||
self.channel.save()
|
|
||||||
|
|
||||||
self.n = Notification(owner=self.check, channel=self.channel)
|
|
||||||
self.n.save()
|
|
||||||
|
|
||||||
def test_it_works(self):
|
|
||||||
url = "/api/v1/notifications/%s/bounce" % self.n.code
|
|
||||||
r = self.client.post(url, "foo", content_type="text/plain")
|
|
||||||
self.assertEqual(r.status_code, 200)
|
|
||||||
|
|
||||||
self.n.refresh_from_db()
|
|
||||||
self.assertEqual(self.n.error, "foo")
|
|
||||||
|
|
||||||
self.channel.refresh_from_db()
|
|
||||||
self.assertFalse(self.channel.email_verified)
|
|
||||||
self.assertEqual(self.channel.last_error, "foo")
|
|
||||||
|
|
||||||
def test_it_checks_ttl(self):
|
|
||||||
self.n.created = self.n.created - timedelta(minutes=60)
|
|
||||||
self.n.save()
|
|
||||||
|
|
||||||
url = "/api/v1/notifications/%s/bounce" % self.n.code
|
|
||||||
r = self.client.post(url, "foo", content_type="text/plain")
|
|
||||||
self.assertEqual(r.status_code, 403)
|
|
||||||
|
|
||||||
def test_it_handles_long_payload(self):
|
|
||||||
url = "/api/v1/notifications/%s/bounce" % self.n.code
|
|
||||||
payload = "A" * 500
|
|
||||||
r = self.client.post(url, payload, content_type="text/plain")
|
|
||||||
self.assertEqual(r.status_code, 200)
|
|
||||||
|
|
||||||
def test_it_handles_missing_notification(self):
|
|
||||||
fake_code = "07c2f548-9850-4b27-af5d-6c9dc157ec02"
|
|
||||||
url = "/api/v1/notifications/%s/bounce" % fake_code
|
|
||||||
r = self.client.post(url, "", content_type="text/plain")
|
|
||||||
self.assertEqual(r.status_code, 404)
|
|
||||||
|
|
||||||
def test_it_requires_post(self):
|
|
||||||
url = "/api/v1/notifications/%s/bounce" % self.n.code
|
|
||||||
r = self.client.get(url)
|
|
||||||
self.assertEqual(r.status_code, 405)
|
|
||||||
|
|
||||||
def test_does_not_unsubscribe_transient_bounces(self):
|
|
||||||
url = "/api/v1/notifications/%s/bounce?type=Transient" % self.n.code
|
|
||||||
self.client.post(url, "foo", content_type="text/plain")
|
|
||||||
|
|
||||||
self.n.refresh_from_db()
|
|
||||||
self.assertEqual(self.n.error, "foo")
|
|
||||||
|
|
||||||
self.channel.refresh_from_db()
|
|
||||||
self.assertTrue(self.channel.email_verified)
|
|
@ -314,7 +314,6 @@ class NotifyTestCase(BaseTestCase):
|
|||||||
|
|
||||||
email = mail.outbox[0]
|
email = mail.outbox[0]
|
||||||
self.assertEqual(email.to[0], "alice@example.org")
|
self.assertEqual(email.to[0], "alice@example.org")
|
||||||
self.assertTrue("X-Bounce-Url" in email.extra_headers)
|
|
||||||
self.assertTrue("X-Status-Url" in email.extra_headers)
|
self.assertTrue("X-Status-Url" in email.extra_headers)
|
||||||
self.assertTrue("List-Unsubscribe" in email.extra_headers)
|
self.assertTrue("List-Unsubscribe" in email.extra_headers)
|
||||||
self.assertTrue("List-Unsubscribe-Post" in email.extra_headers)
|
self.assertTrue("List-Unsubscribe-Post" in email.extra_headers)
|
||||||
|
@ -62,7 +62,6 @@ class Email(Transport):
|
|||||||
unsub_link = self.channel.get_unsub_link()
|
unsub_link = self.channel.get_unsub_link()
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"X-Bounce-Url": check.bounce_url,
|
|
||||||
"X-Status-Url": check.status_url,
|
"X-Status-Url": check.status_url,
|
||||||
"List-Unsubscribe": "<%s>" % unsub_link,
|
"List-Unsubscribe": "<%s>" % unsub_link,
|
||||||
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
|
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
|
||||||
|
@ -36,7 +36,6 @@ urlpatterns = [
|
|||||||
path("api/v1/checks/<uuid:code>", views.single, name="hc-api-single"),
|
path("api/v1/checks/<uuid:code>", views.single, name="hc-api-single"),
|
||||||
path("api/v1/checks/<sha1:unique_key>", views.get_check_by_unique_key),
|
path("api/v1/checks/<sha1:unique_key>", views.get_check_by_unique_key),
|
||||||
path("api/v1/checks/<uuid:code>/pause", views.pause, name="hc-api-pause"),
|
path("api/v1/checks/<uuid:code>/pause", views.pause, name="hc-api-pause"),
|
||||||
path("api/v1/notifications/<uuid:code>/bounce", views.bounce, name="hc-api-bounce"),
|
|
||||||
path(
|
path(
|
||||||
"api/v1/notifications/<uuid:code>/status",
|
"api/v1/notifications/<uuid:code>/status",
|
||||||
views.notification_status,
|
views.notification_status,
|
||||||
|
@ -391,30 +391,6 @@ def badge(request, badge_key, signature, tag, fmt="svg"):
|
|||||||
return HttpResponse(svg, content_type="image/svg+xml")
|
return HttpResponse(svg, content_type="image/svg+xml")
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
|
||||||
@require_POST
|
|
||||||
def bounce(request, code):
|
|
||||||
notification = get_object_or_404(Notification, code=code)
|
|
||||||
|
|
||||||
# If webhook is more than 10 minutes late, don't accept it:
|
|
||||||
td = timezone.now() - notification.created
|
|
||||||
if td.total_seconds() > 600:
|
|
||||||
return HttpResponseForbidden()
|
|
||||||
|
|
||||||
notification.error = request.body.decode()[:200]
|
|
||||||
notification.save()
|
|
||||||
|
|
||||||
notification.channel.last_error = notification.error
|
|
||||||
if request.GET.get("type") in (None, "Permanent"):
|
|
||||||
# For permanent bounces, mark the channel as not verified, so we
|
|
||||||
# will not try to deliver to it again.
|
|
||||||
notification.channel.email_verified = False
|
|
||||||
|
|
||||||
notification.channel.save()
|
|
||||||
|
|
||||||
return HttpResponse()
|
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
@require_POST
|
@require_POST
|
||||||
def notification_status(request, code):
|
def notification_status(request, code):
|
||||||
|
@ -28,7 +28,7 @@ class SendTestNotificationTestCase(BaseTestCase):
|
|||||||
|
|
||||||
email = mail.outbox[0]
|
email = mail.outbox[0]
|
||||||
self.assertEqual(email.to[0], "alice@example.org")
|
self.assertEqual(email.to[0], "alice@example.org")
|
||||||
self.assertTrue("X-Bounce-Url" in email.extra_headers)
|
self.assertTrue("X-Status-Url" in email.extra_headers)
|
||||||
self.assertTrue("List-Unsubscribe" in email.extra_headers)
|
self.assertTrue("List-Unsubscribe" in email.extra_headers)
|
||||||
|
|
||||||
# It should create a notification
|
# It should create a notification
|
||||||
|
Loading…
x
Reference in New Issue
Block a user