forked from GithubBackups/healthchecks
Rate limit team invites to 20/day
This commit is contained in:
parent
d299feb420
commit
beae8e62b4
@ -1,8 +1,10 @@
|
||||
from django.core import mail
|
||||
|
||||
from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from hc.test import BaseTestCase
|
||||
from hc.accounts.models import Member
|
||||
from hc.api.models import TokenBucket
|
||||
|
||||
|
||||
class ProjectTestCase(BaseTestCase):
|
||||
@ -83,6 +85,20 @@ class ProjectTestCase(BaseTestCase):
|
||||
" Alice's Project on %s" % settings.SITE_NAME)
|
||||
self.assertEqual(mail.outbox[0].subject, subj)
|
||||
|
||||
@override_settings(SECRET_KEY="test-secret")
|
||||
def test_it_rate_limits_invites(self):
|
||||
obj = TokenBucket(value="invite-%d" % self.alice.id)
|
||||
obj.tokens = 0
|
||||
obj.save()
|
||||
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
|
||||
form = {"invite_team_member": "1", "email": "frank@example.org"}
|
||||
r = self.client.post(self.url, form)
|
||||
self.assertContains(r, "Too Many Requests")
|
||||
|
||||
self.assertEqual(len(mail.outbox), 0)
|
||||
|
||||
def test_it_requires_owner_to_add_team_member(self):
|
||||
self.client.login(username="bob@example.org", password="password")
|
||||
|
||||
|
@ -285,6 +285,8 @@ def project(request, code):
|
||||
|
||||
form = InviteTeamMemberForm(request.POST)
|
||||
if form.is_valid():
|
||||
if not TokenBucket.authorize_invite(request.user):
|
||||
return render(request, "try_later.html")
|
||||
|
||||
email = form.cleaned_data["email"]
|
||||
try:
|
||||
|
@ -632,7 +632,7 @@ class TokenBucket(models.Model):
|
||||
salted_encoded = (email + settings.SECRET_KEY).encode()
|
||||
value = "em-%s" % hashlib.sha1(salted_encoded).hexdigest()
|
||||
|
||||
# 20 emails per 3600 seconds (1 hour):
|
||||
# 20 login attempts for a single email per hour:
|
||||
return TokenBucket.authorize(value, 20, 3600)
|
||||
|
||||
@staticmethod
|
||||
@ -643,5 +643,12 @@ class TokenBucket(models.Model):
|
||||
salted_encoded = (ip + settings.SECRET_KEY).encode()
|
||||
value = "ip-%s" % hashlib.sha1(salted_encoded).hexdigest()
|
||||
|
||||
# 20 login attempts from a single IP per 3600 seconds (1 hour):
|
||||
# 20 login attempts from a single IP per hour:
|
||||
return TokenBucket.authorize(value, 20, 3600)
|
||||
|
||||
@staticmethod
|
||||
def authorize_invite(user):
|
||||
value = "invite-%d" % user.id
|
||||
|
||||
# 20 invites per day
|
||||
return TokenBucket.authorize(value, 20, 3600 * 24)
|
||||
|
Loading…
x
Reference in New Issue
Block a user