forked from GithubBackups/healthchecks
Add rate-limiting for Signal messages
This commit is contained in:
parent
d4aac691ce
commit
a80b831eea
@ -902,6 +902,14 @@ class TokenBucket(models.Model):
|
|||||||
# 6 messages for a single chat per minute:
|
# 6 messages for a single chat per minute:
|
||||||
return TokenBucket.authorize(value, 6, 60)
|
return TokenBucket.authorize(value, 6, 60)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def authorize_signal(phone):
|
||||||
|
salted_encoded = (phone + settings.SECRET_KEY).encode()
|
||||||
|
value = "signal-%s" % hashlib.sha1(salted_encoded).hexdigest()
|
||||||
|
|
||||||
|
# 6 messages for a single recipient per minute:
|
||||||
|
return TokenBucket.authorize(value, 6, 60)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def authorize_sudo_code(user):
|
def authorize_sudo_code(user):
|
||||||
value = "sudo-%d" % user.id
|
value = "sudo-%d" % user.id
|
||||||
|
@ -6,7 +6,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from hc.api.models import Channel, Check, Notification
|
from hc.api.models import Channel, Check, Notification, TokenBucket
|
||||||
from hc.test import BaseTestCase
|
from hc.test import BaseTestCase
|
||||||
|
|
||||||
|
|
||||||
@ -80,3 +80,14 @@ class NotifySignalTestCase(BaseTestCase):
|
|||||||
cmd = " ".join(args[0])
|
cmd = " ".join(args[0])
|
||||||
|
|
||||||
self.assertIn("Foo & Bar", cmd)
|
self.assertIn("Foo & Bar", cmd)
|
||||||
|
|
||||||
|
@override_settings(SECRET_KEY="test-secret")
|
||||||
|
def test_it_obeys_rate_limit(self):
|
||||||
|
# "2862..." is sha1("+123456789test-secret")
|
||||||
|
obj = TokenBucket(value="signal-2862991ccaa15c8856e7ee0abaf3448fb3c292e0")
|
||||||
|
obj.tokens = 0
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
self.channel.notify(self.check)
|
||||||
|
n = Notification.objects.first()
|
||||||
|
self.assertEqual(n.error, "Rate limit exceeded")
|
||||||
|
@ -673,6 +673,11 @@ class Signal(Transport):
|
|||||||
if not settings.SIGNAL_CLI_USERNAME:
|
if not settings.SIGNAL_CLI_USERNAME:
|
||||||
return "Signal notifications are not enabled"
|
return "Signal notifications are not enabled"
|
||||||
|
|
||||||
|
from hc.api.models import TokenBucket
|
||||||
|
|
||||||
|
if not TokenBucket.authorize_signal(self.channel.phone_number):
|
||||||
|
return "Rate limit exceeded"
|
||||||
|
|
||||||
text = tmpl("signal_message.html", check=check, site_name=settings.SITE_NAME)
|
text = tmpl("signal_message.html", check=check, site_name=settings.SITE_NAME)
|
||||||
|
|
||||||
args = settings.SIGNAL_CLI_CMD.split()
|
args = settings.SIGNAL_CLI_CMD.split()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user