Pēteris Caune
5 years ago
No known key found for this signature in database
GPG Key ID: E28D7679E9A9EDE2
7 changed files with 179 additions and 8 deletions
-
2CHANGELOG.md
-
33hc/accounts/tests/test_login.py
-
16hc/accounts/views.py
-
22hc/api/migrations/0060_tokenbucket.py
-
53hc/api/models.py
-
47hc/api/tests/test_tokenbucket.py
-
14templates/try_later.html
@ -0,0 +1,22 @@ |
|||||
|
# Generated by Django 2.2 on 2019-04-25 12:46 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('api', '0059_auto_20190314_1744'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='TokenBucket', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('value', models.CharField(max_length=80, unique=True)), |
||||
|
('tokens', models.FloatField(default=1.0)), |
||||
|
('updated', models.DateTimeField(auto_now_add=True)), |
||||
|
], |
||||
|
), |
||||
|
] |
@ -0,0 +1,47 @@ |
|||||
|
from datetime import timedelta as td |
||||
|
|
||||
|
from django.test.utils import override_settings |
||||
|
from django.utils.timezone import now |
||||
|
from hc.api.models import TokenBucket |
||||
|
from hc.test import BaseTestCase |
||||
|
|
||||
|
# This is sha1("alice@example.org" + "test-secred") |
||||
|
ALICE_HASH = "d60db3b2343e713a4de3e92d4eb417e4f05f06ab" |
||||
|
|
||||
|
|
||||
|
@override_settings(SECRET_KEY="test-secret") |
||||
|
class TokenBucketTestCase(BaseTestCase): |
||||
|
|
||||
|
def test_it_works(self): |
||||
|
r = TokenBucket.authorize_login_email("alice@example.org") |
||||
|
self.assertTrue(r) |
||||
|
|
||||
|
obj = TokenBucket.objects.get() |
||||
|
self.assertEqual(obj.tokens, 0.95) |
||||
|
self.assertEqual(obj.value, "em-" + ALICE_HASH) |
||||
|
|
||||
|
def test_it_handles_insufficient_tokens(self): |
||||
|
TokenBucket.objects.create(value="em-" + ALICE_HASH, tokens=0.04) |
||||
|
|
||||
|
r = TokenBucket.authorize_login_email("alice@example.org") |
||||
|
self.assertFalse(r) |
||||
|
|
||||
|
def test_it_tops_up(self): |
||||
|
obj = TokenBucket(value="em-" + ALICE_HASH) |
||||
|
obj.tokens = 0 |
||||
|
obj.updated = now() - td(minutes=30) |
||||
|
obj.save() |
||||
|
|
||||
|
r = TokenBucket.authorize_login_email("alice@example.org") |
||||
|
self.assertTrue(r) |
||||
|
|
||||
|
obj.refresh_from_db() |
||||
|
self.assertAlmostEqual(obj.tokens, 0.45, places=5) |
||||
|
|
||||
|
def test_it_normalizes_email(self): |
||||
|
emails = ("alice+alias@example.org", "a.li.ce@example.org") |
||||
|
|
||||
|
for email in emails: |
||||
|
TokenBucket.authorize_login_email(email) |
||||
|
|
||||
|
self.assertEqual(TokenBucket.objects.count(), 1) |
@ -0,0 +1,14 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
|
||||
|
{% block content %} |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-6 col-sm-offset-3"> |
||||
|
<div class="hc-dialog text-center"> |
||||
|
<h1>Too Many Requests</h1> |
||||
|
<div class="dialog-body"> |
||||
|
<p>Please try again later.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue