This repository has been archived by the owner on Feb 8, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 308
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace throttling with verification limitation
- Loading branch information
1 parent
4d50c3f
commit 11be3e0
Showing
15 changed files
with
71 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ALTER TABLE email_queue DROP COLUMN user_initiated; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ | |
import mock | ||
from pytest import raises | ||
|
||
from gratipay.exceptions import Throttled | ||
from gratipay.testing import Harness | ||
from gratipay.testing.email import SentEmailHarness | ||
|
||
|
@@ -14,36 +13,24 @@ class TestPut(SentEmailHarness): | |
|
||
def setUp(self): | ||
SentEmailHarness.setUp(self) | ||
self.alice = self.make_participant('alice', claimed_time='now', email_address='[email protected]') | ||
self.alice = self.make_participant( 'alice' | ||
, claimed_time='now' | ||
, email_address='[email protected]' | ||
) | ||
|
||
def test_queueing_email_is_throttled(self): | ||
def test_put_puts(self): | ||
assert self.app.email_queue.flush() == 0 | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base") | ||
raises(Throttled, self.app.email_queue.put, self.alice, "base") | ||
assert self.app.email_queue.flush() == 3 | ||
|
||
def test_queueing_email_writes_timestamp(self): | ||
self.app.email_queue.put(self.alice, "base") | ||
|
||
ctime = self.db.one("SELECT EXTRACT(epoch FROM ctime) FROM email_queue") | ||
assert abs(ctime - time.time()) < 300 | ||
|
||
def test_only_user_initiated_messages_count_towards_throttling(self): | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base", _user_initiated=False) | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base", _user_initiated=False) | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base", _user_initiated=False) | ||
raises(Throttled, self.app.email_queue.put, self.alice, "branch") | ||
|
||
def test_flushing_queue_resets_throttling(self): | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base") | ||
self.app.email_queue.put(self.alice, "base") | ||
assert self.app.email_queue.flush() == 3 | ||
self.app.email_queue.put(self.alice, "base") | ||
|
||
|
||
class TestFlush(SentEmailHarness): | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
from pytest import raises | ||
|
||
from gratipay.exceptions import CannotRemovePrimaryEmail, EmailTaken, EmailNotVerified | ||
from gratipay.exceptions import TooManyEmailAddresses, Throttled, EmailAlreadyVerified | ||
from gratipay.exceptions import TooManyEmailAddresses, TooManyVerifications, EmailAlreadyVerified | ||
from gratipay.exceptions import EmailNotOnFile, ProblemChangingEmail | ||
from gratipay.testing import P, Harness | ||
from gratipay.testing.email import QueuedEmailHarness | ||
|
@@ -57,7 +57,7 @@ def hit_email_spt(self, action, address, user='alice', package_ids=[], should_fa | |
, auth_as=user | ||
, HTTP_ACCEPT_LANGUAGE=b'en' | ||
) | ||
if issubclass(response.__class__, (ProblemChangingEmail, Throttled)): | ||
if issubclass(response.__class__, (ProblemChangingEmail, TooManyVerifications)): | ||
response.render_body({'_': lambda a: a}) | ||
return response | ||
|
||
|
@@ -109,6 +109,24 @@ def test_verifying_second_email_sends_verification_notice(self): | |
expected = "We are connecting [email protected] to the alice account on Gratipay" | ||
assert expected in last_email['body_text'] | ||
|
||
def test_can_only_have_one_verification_outstanding_at_a_time(self): | ||
response = self.hit_email_spt('add-email', '[email protected]') | ||
assert response.code == 200 | ||
response = self.hit_email_spt('add-email', '[email protected]', should_fail=True) | ||
assert response.code == 400 | ||
assert response.__class__ is TooManyVerifications | ||
assert response.body == 'You have an outstanding verification request that must be ' \ | ||
'completed before you can verify a different email address.' | ||
|
||
def test_can_resend_verification_message_for_same_email(self): | ||
response = self.hit_email_spt('add-email', '[email protected]') | ||
assert response.code == 200 | ||
response = self.hit_email_spt('add-email', '[email protected]', should_fail=True) | ||
assert response.code == 400 | ||
assert response.__class__ is TooManyVerifications | ||
assert response.body == 'You have an outstanding verification request that must be ' \ | ||
'completed before you can verify a different email address.' | ||
|
||
def test_post_anon_returns_401(self): | ||
response = self.hit_email_spt('add-email', '[email protected]', user=None, should_fail=True) | ||
assert response.code == 401 | ||
|
@@ -129,14 +147,6 @@ def test_post_with_looooong_address_is_400(self): | |
response = self.hit_email_spt('add-email', ('a'*243) + '@example.com', should_fail=True) | ||
assert response.code == 400 | ||
|
||
def test_post_too_quickly_is_400(self): | ||
self.hit_email_spt('add-email', '[email protected]') | ||
self.hit_email_spt('add-email', '[email protected]') | ||
self.hit_email_spt('add-email', '[email protected]') | ||
response = self.hit_email_spt('add-email', '[email protected]', should_fail=True) | ||
assert response.code == 400 | ||
assert 'too quickly' in response.body | ||
|
||
def test_verify_email_without_adding_email(self): | ||
response = self.hit_verify_spt('', 'sample-nonce') | ||
assert 'Bad Info' in response.body | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,41 +184,37 @@ def test_idempotent(self): | |
self.db.self_check() | ||
|
||
def test_email_addresses_merging(self): | ||
# person starts a bunch of email verifications as alice | ||
# person verifies an email as alice | ||
alice = self.make_participant('alice') | ||
alice.start_email_verification('[email protected]') | ||
alice.start_email_verification('alice@example.net') | ||
alice.start_email_verification('alice@example.org') | ||
nonce = alice.get_email('alice@example.com').nonce | ||
alice.finish_email_verification('alice@example.com', nonce) | ||
|
||
# person finishes one of them, as alice | ||
nonce = alice.get_email('[email protected]').nonce | ||
alice.finish_email_verification('[email protected]', nonce) | ||
# person starts another verification as alice | ||
alice.start_email_verification('[email protected]') | ||
|
||
# person signs up as bob | ||
bob_github = self.make_elsewhere('github', 2, 'bob') | ||
bob = bob_github.opt_in('bob')[0].participant | ||
|
||
# person verifies one of the same emails as alice, using bob | ||
bob.start_email_verification('[email protected]') | ||
nonce = bob.get_email('[email protected]').nonce | ||
bob.finish_email_verification('[email protected]', nonce) | ||
|
||
# ... starts verification for another of the same | ||
bob.start_email_verification('[email protected]') | ||
|
||
# ... and for a new email | ||
# verifies an email | ||
bob.start_email_verification('[email protected]') | ||
nonce = bob.get_email('[email protected]').nonce | ||
bob.finish_email_verification('[email protected]', nonce) | ||
|
||
# and starts verification for alice's unverified email | ||
bob.start_email_verification('[email protected]') | ||
|
||
# Now: alice takes over bob! | ||
alice.take_over(bob_github, have_confirmation=True) | ||
|
||
# alice gets all the addresses, verified or not | ||
alice_emails = {e.address: e for e in alice.get_emails()} | ||
assert len(alice_emails) == 4 | ||
assert len(alice_emails) == 3 | ||
assert alice_emails['[email protected]'].verified | ||
assert alice_emails['alice@example.org'].verified | ||
assert not alice_emails['alice@example.net'].verified | ||
assert not alice_emails['bob@example.net'].verified | ||
assert alice_emails['bob@example.net'].verified | ||
assert not alice_emails['alice@example.org'].verified | ||
assert alice.email_address == 'alice@example.com' | ||
|
||
# bob has no email addresses | ||
assert not Participant.from_id(bob.id).get_emails() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters