Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

automatically clear after a while (bug 827580)

  • Loading branch information...
commit 292027e03b932c0023aaab232db341bd87de31dd 1 parent f1569c4
Andy McKay andymckay authored wraithan committed
10 lib/buyers/models.py
@@ -24,7 +24,15 @@ class Meta(Model.Meta):
24 24
25 25 @property
26 26 def locked_out(self):
27   - return bool(self.pin_locked_out)
  27 + if not self.pin_locked_out:
  28 + return False
  29 +
  30 + if ((datetime.now() - self.pin_locked_out).seconds >
  31 + settings.PIN_FAILURE_LENGTH):
  32 + self.clear_lockout()
  33 + return False
  34 +
  35 + return True
28 36
29 37 def clear_lockout(self):
30 38 self.pin_failures = 0
13 lib/buyers/tests/test_api.py
... ... @@ -1,4 +1,4 @@
1   -from datetime import datetime
  1 +from datetime import datetime, timedelta
2 2 import json
3 3
4 4 from django.conf import settings
@@ -282,6 +282,17 @@ def test_good_pin_but_locked_out(self, log_cef):
282 282 assert log_cef.called
283 283 eq_(res.status_code, 403)
284 284
  285 + def test_locked_out_over_time(self):
  286 + self.buyer.pin_locked_out = (datetime.now() -
  287 + timedelta(seconds=settings.PIN_FAILURE_LENGTH + 60))
  288 + self.buyer.save()
  289 +
  290 + res = self.client.post(self.list_url, data={'uuid': self.uuid,
  291 + 'pin': self.pin})
  292 + eq_(res.status_code, 201)
  293 + data = json.loads(res.content)
  294 + assert data['valid']
  295 +
285 296 def test_good_reset_failures(self):
286 297 self.buyer.pin_failures = 1
287 298 self.buyer.save()
22 lib/buyers/tests/test_models.py
... ... @@ -1,4 +1,4 @@
1   -from datetime import datetime
  1 +from datetime import datetime, timedelta
2 2
3 3 from aesfield.field import EncryptedField
4 4 from nose.tools import eq_
@@ -41,6 +41,13 @@ def test_filter(self):
41 41 with self.assertRaises(EncryptedField):
42 42 BuyerPaypal.objects.filter(key='bar')
43 43
  44 +
  45 +class TestLockout(TestCase):
  46 +
  47 + def setUp(self):
  48 + self.uid = 'test:uid'
  49 + self.buyer = Buyer.objects.create(uuid=self.uid)
  50 +
44 51 def test_locked_out(self):
45 52 assert not self.buyer.locked_out
46 53 self.buyer.pin_locked_out = datetime.now()
@@ -67,3 +74,16 @@ def test_clear(self):
67 74 self.buyer.clear_lockout()
68 75 eq_(self.buyer.pin_failures, 0)
69 76 eq_(self.buyer.pin_locked_out, None)
  77 +
  78 + def test_under_timeout(self):
  79 + self.buyer.pin_locked_out = (datetime.now() -
  80 + timedelta(seconds=settings.PIN_FAILURE_LENGTH - 60))
  81 + self.buyer.save()
  82 + assert self.buyer.locked_out
  83 +
  84 + def test_over_timeout(self):
  85 + self.buyer.pin_locked_out = (datetime.now() -
  86 + timedelta(seconds=settings.PIN_FAILURE_LENGTH + 60))
  87 + self.buyer.save()
  88 + assert not self.buyer.locked_out
  89 + eq_(self.buyer.reget().pin_locked_out, None)
2  solitude/settings/base.py
@@ -189,3 +189,5 @@
189 189
190 190 # The number of PIN failures before we lock them out.
191 191 PIN_FAILURES = 5
  192 +# The amount of time before you can try it again in seconds.
  193 +PIN_FAILURE_LENGTH = 600

0 comments on commit 292027e

Please sign in to comment.
Something went wrong with that request. Please try again.