Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Support queueing emails without participants #4548

Merged
merged 2 commits into from
Sep 8, 2017

Conversation

rohitpaulk
Copy link
Contributor

@rohitpaulk rohitpaulk commented Jul 15, 2017

← "Ready to verify" (#4584)


#4547

  • Extracted out a few tests from test_email.py into test_participant_emails.py. Now, the tests in test_email.py only test stuff in gratipay/email.pyFactor out email tests #4570
  • Moved email from within context to a new field in the DB. This helps in visibility + simplifies DB queries and constraints
  • Added support for queuing emails without participants

Todo

  • handle unsubscribes

@rohitpaulk rohitpaulk changed the title Support queueing emails without participants (WIP) Support queueing emails without participants Jul 15, 2017
@chadwhitacre
Copy link
Contributor

Rebased, was 3d2430c.

@chadwhitacre chadwhitacre force-pushed the queue-email-without-participant branch from 3d2430c to b80f821 Compare August 14, 2017 13:55
@chadwhitacre chadwhitacre changed the base branch from master to refactor-email-tests August 14, 2017 15:53
@chadwhitacre
Copy link
Contributor

chadwhitacre commented Aug 14, 2017

Brainstorm: can we decouple participant entirely from the email queue? Is that a cleaner architecture?
I'm also put in mind of a couple other related potential improvements:

@chadwhitacre chadwhitacre changed the base branch from refactor-email-tests to master August 14, 2017 16:01
@chadwhitacre chadwhitacre force-pushed the queue-email-without-participant branch from b80f821 to 4bc67bc Compare August 14, 2017 16:05
@chadwhitacre
Copy link
Contributor

We need this for #4569 in addition to #4539.

@chadwhitacre
Copy link
Contributor

Participant is related to throttling. I think we might be able to simplify throttling to only be about verified emails, rather than the generic user_initiated strategy we currently employ. Right?

@chadwhitacre
Copy link
Contributor

Yeah, from a review of ack queue\.put the only place we call put without passing in _user_initiated=False (thereby bypassing throttling) is during verification.

@chadwhitacre
Copy link
Contributor

That means we can resolve #4545, too!

@chadwhitacre chadwhitacre mentioned this pull request Aug 14, 2017
15 tasks
@chadwhitacre
Copy link
Contributor

Alright, let's try to keep this PR focused though ...

@chadwhitacre
Copy link
Contributor

chadwhitacre commented Aug 14, 2017

Refactoring throttling will make it easier to extricate participant from gratipay.email.

@chadwhitacre
Copy link
Contributor

I've almost got a throttling rewrite done, which I plan to make as a separate PR ahead of this one. But now I think that we actually want both: throttling based on "N per time", and only allowing one open verification at a time. The reason is that we still need to allow resending verification messages, and you can be sure we'll get turkies flooding some poor maintainer with N00 verification resends if we don't throttle that. I guess we could also do that as N resends per address? Anyway, the point is that to implement (some variant) of both protections we'll need to upgrade email_queue to an email_messages table where we store email messages in perpetuity, so that we can query on recent past. I guess that's a third PR ahead of both of these.

@chadwhitacre
Copy link
Contributor

Throttling redo started in #4571. Turning to permanentizing email messages table ...

@chadwhitacre
Copy link
Contributor

Email saving in #4572.

@chadwhitacre
Copy link
Contributor

Throttling redo redone in #4579.

In addition to better protection against verification spam/phishing, the other abuse protection we need before we can start mailing just any ol' email address is a blacklist/unsubscribe.

@chadwhitacre
Copy link
Contributor

We should probably treat unsubscribes as locks against claims via that email address across all packages.

@chadwhitacre
Copy link
Contributor

Moving out of review, we need unsubscribe as part of this. We can't start sending messages to random email addresses without an unsubscribe/blacklist mechanism.

@chadwhitacre chadwhitacre changed the base branch from master to ready-to-verify August 28, 2017 14:08
@chadwhitacre
Copy link
Contributor

Rebased on #4584, was 4bc67bc.

@chadwhitacre chadwhitacre force-pushed the queue-email-without-participant branch from 4bc67bc to 27d4c8f Compare August 28, 2017 14:13
@chadwhitacre
Copy link
Contributor

chadwhitacre commented Aug 28, 2017

I'm seeing confusion in the email_messages.participant field. It conflates the sender and the recipient of messages. It's the recipient in cases where no email address is specified in the context, and it's also treated as the recipient for purposes of templating (language, username, etc.[?]). We treat participant as the sender for purposes of throttling.

So far in 27d4c8f on this PR we are bumping context.email up to email_messages.email_address, but the conflation of sender and receiver remains: the put API accepts either a participant (to) or an email address (email). This sort of works on the recipient side because we can just fall back to sane-ish defaults for templating context, but when we get to the sender side we fall into a bit of an absurdity, possibly throttling on what can only be the recipient (email).

I think we need to update the put API to clearly distinguish the sender and the recipient of messages:

  • Replace the email_messages.user_initiated boolean with a sender field referencing participants. NULL means it's a system-initiated message.
  • Add a required to field to email_messages that holds the recipient email address. Make it the caller's responsibility to provide all context variables required by the template rather than assuming participant and attempting defaults.

I'm not sure yet how to think about unsubscribe/blacklisting, but the above should be cleaned up one way or another, maybe in its own PR.

@chadwhitacre chadwhitacre force-pushed the queue-email-without-participant branch from 84350d6 to c61f4d7 Compare August 31, 2017 20:32
@chadwhitacre
Copy link
Contributor

Interesting! I want to set up fixture using the old API, meaning old code old slug. But no before.py!

@chadwhitacre
Copy link
Contributor

chadwhitacre commented Sep 1, 2017

Note to self: account for the case where we want to send payday charge notifications but the participant doesn't have an email address on file (cf. gratipay/inside.gratipay.com#1149 (comment))

@chadwhitacre
Copy link
Contributor

Rebased, was c61f4d7.

@chadwhitacre
Copy link
Contributor

Alright, upon closer inspection, email_messages.participant is actually the recipient, and so by also using that for throttling we are assuming that the recipient is always also the sender. Hmm ... 🤔

@chadwhitacre
Copy link
Contributor

And user_initiated is how we mark when the receiver is also the sender.

@chadwhitacre
Copy link
Contributor

We have two presenting use cases for sending email messages to addresses unassociated with a participant:

  1. email sign-up (Add support for queuing emails without a participant linked #4547), and
  2. pledging (Pay for package.json in aggregate #4569).

Under (2) these are going to be system-generated messages, so we don't need to worry about throttling (well, we need to worry a lot about it, but it's on us to throttle ourselves! :D).

Under (1) we do want to throttle on the receiver (mailbombing is annoying) but even moreso on the sender (mass-mailbombing is worse, and mass-phishing is worser). That'll probably require logging IPs, out of scope on this PR.

@chadwhitacre
Copy link
Contributor

Rebased yet again to go back to @rohitpaulk's original 4bc67bc w/ updates for #4590 #4579 #4584. Was 83bacdf.

@chadwhitacre
Copy link
Contributor

Half-baked notes on my desktop from when I was offline:

The only place where we include the email address in the context (overriding any participant.email_address) is verification.

Hah! Pass in recipient_address and dereference a participant based on that (select * from email_addresses where address=%s and verified;). If null then double-check that we're sending a verification message, we shouldn't need username, etc. at that point and we can default to eng.

Dang, no. Email lang should come from the participant that initiated the message.

Pass in lang to put.

sender receiver e.g. lang
auth auth user messaging receiver
anon auth n/a
sys auth
sys
  • for sender:auth sender-receiver (charged) it should
  • for anon sender-receiver (sign-in) it should come from http lang
  • for sys sender/anon receiver (pledging) it should be en
  • for auth sender-receiver (charged) it should

@chadwhitacre
Copy link
Contributor

chadwhitacre commented Sep 8, 2017

We need this for #4598. slack

@chadwhitacre chadwhitacre merged commit 3490d48 into ready-to-verify Sep 8, 2017
@chadwhitacre
Copy link
Contributor

Crap. Wrong base. :-/

@chadwhitacre
Copy link
Contributor

So now my options are:

@chadwhitacre
Copy link
Contributor

I meant @kaguillera, not @dowski. Honest! 🐭

@rohitpaulk
Copy link
Contributor Author

Yh umm.. I'm confused - what did you intend to merge this into? master?

@chadwhitacre
Copy link
Contributor

Yes.

@chadwhitacre
Copy link
Contributor

slack

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants