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.
Merge pull request #2752 from gratipay/email-step-1
Email - Part 1
- Loading branch information
Showing
30 changed files
with
936 additions
and
225 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
This is a one-off script to populate the new `emails` table using the addresses | ||
we have in `participants`. | ||
""" | ||
from __future__ import division, print_function, unicode_literals | ||
|
||
from urllib import quote | ||
import uuid | ||
|
||
import gratipay | ||
from aspen.utils import utcnow | ||
from postgres.orm import Model | ||
|
||
import gratipay.wireup | ||
|
||
env = gratipay.wireup.env() | ||
tell_sentry = gratipay.wireup.make_sentry_teller(env) | ||
db = gratipay.wireup.db(env) | ||
gratipay.wireup.mail(env) | ||
gratipay.wireup.load_i18n('.', tell_sentry) | ||
gratipay.wireup.canonical(env) | ||
|
||
|
||
class EmailAddressWithConfirmation(Model): | ||
typname = "email_address_with_confirmation" | ||
|
||
db.register_model(EmailAddressWithConfirmation) | ||
|
||
|
||
def add_email(self, email): | ||
nonce = str(uuid.uuid4()) | ||
verification_start = utcnow() | ||
|
||
scheme = gratipay.canonical_scheme | ||
host = gratipay.canonical_host | ||
username = self.username_lower | ||
quoted_email = quote(email) | ||
link = "{scheme}://{host}/{username}/emails/verify.html?email={quoted_email}&nonce={nonce}" | ||
self.send_email('initial', | ||
email=email, | ||
link=link.format(**locals()), | ||
username=self.username, | ||
include_unsubscribe=False) | ||
|
||
db.run(""" | ||
INSERT INTO emails | ||
(address, nonce, verification_start, participant) | ||
VALUES (%s, %s, %s, %s) | ||
""", (email, nonce, verification_start, self.username)) | ||
|
||
|
||
participants = db.all(""" | ||
SELECT p.*::participants | ||
FROM participants p | ||
WHERE email IS NOT NULL | ||
AND NOT is_closed | ||
AND is_suspicious IS NOT true | ||
AND claimed_time IS NOT NULL; | ||
""") | ||
total = len(participants) | ||
for i, p in enumerate(participants, 1): | ||
print('sending email to %s (%i/%i)' % (p.username, i, total)) | ||
add_email(p, p.email.address) |
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,46 @@ | ||
BEGIN; | ||
CREATE TABLE emails | ||
( id serial PRIMARY KEY | ||
, address text NOT NULL | ||
, verified boolean DEFAULT NULL | ||
CONSTRAINT verified_cant_be_false | ||
-- Only use TRUE and NULL, so that the | ||
-- unique constraint below functions | ||
-- properly. | ||
CHECK (verified IS NOT FALSE) | ||
, nonce text | ||
, verification_start timestamp with time zone NOT NULL | ||
DEFAULT CURRENT_TIMESTAMP | ||
, verification_end timestamp with time zone | ||
, participant text NOT NULL | ||
REFERENCES participants | ||
ON UPDATE CASCADE | ||
ON DELETE RESTRICT | ||
|
||
, UNIQUE (address, verified) -- A verified email address can't be linked to multiple | ||
-- participants. However, an *un*verified address *can* | ||
-- be linked to multiple participants. We implement this | ||
-- by using NULL instead of FALSE for the unverified | ||
-- state, hence the check constraint on verified. | ||
, UNIQUE (participant, address) | ||
); | ||
|
||
-- The participants table currently has an `email` attribute of type | ||
-- email_address_with confirmation. This should be deleted in the future, | ||
-- once the emails are migrated. The column we're going to replace it with | ||
-- is named `email_address`. This is only for **verified** emails. All | ||
-- unverified email stuff happens in the emails table and won't touch this | ||
-- attribute. | ||
|
||
ALTER TABLE participants ADD COLUMN email_address text UNIQUE, | ||
ADD COLUMN email_lang text; | ||
|
||
UPDATE events | ||
SET payload = replace(replace( payload::text, '"set"', '"add"') | ||
, '"current_email"' | ||
, '"email"' | ||
)::json | ||
WHERE payload->>'action' = 'set' | ||
AND (payload->'values'->'current_email') IS NOT NULL; | ||
|
||
END; |
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,29 @@ | ||
[---] text/html | ||
<div style="text-align: center; padding: 20px 0; margin: 0;"> | ||
<img src="https://downloads.gratipay.com/email/gratipay.png" alt="Gratipay"> | ||
</div> | ||
|
||
<div style="text-align: center; font: normal 14px/21px Arial, sans-serif; color: #333; padding: 0 20%;"> | ||
$body | ||
</div> | ||
|
||
<div style="text-align: center; color: #999; padding: 21px 0 0;"> | ||
<div style="font: normal 14px/21px Arial, sans-serif;"> | ||
{{ _("Something not right? Reply to this email for help.") }} | ||
</div> | ||
<div style="font: normal 10px/21px Arial, sans-serif;"> | ||
Sent by <a href="https://gratipay.com/" style="color: #999; text-decoration: underline;">Gratipay, LLC</a> | 716 Park Road, Ambridge, PA, 15003, USA | ||
</div> | ||
</div> | ||
|
||
[---] text/plain | ||
{{ _("Greetings, program!") }} | ||
|
||
$body | ||
|
||
{{ _("Something not right? Reply to this email for help.") }} | ||
|
||
---- | ||
|
||
Sent by Gratipay, LLC, https://gratipay.com/ | ||
716 Park Road, Ambridge, PA, 15003, USA |
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,21 @@ | ||
{{ _("Connect to {0} on Gratipay?", username) }} | ||
|
||
[---] text/html | ||
A while ago we received a request to connect <b>{{ escape(email) }}</b> to the | ||
{{ '<b><a href="https://gratipay.com/{0}/">{0}</a></b>'.format(username) }} | ||
account on Gratipay (<a | ||
href="https://medium.com/gratipay-blog/gratitude-gratipay-ef24ad5e41f9">formerly</a> | ||
Gittip). Now we're finally sending a verification email! Ring a bell? | ||
<br> | ||
<br> | ||
<a href="{{ link }}" style="color: #fff; text-decoration:none; display:inline-block; padding: 0 15px; background: #396; font: normal 14px/40px Arial, sans-serif; white-space: nowrap; border-radius: 3px">Yes, proceed!</a> | ||
|
||
[---] text/plain | ||
|
||
A while ago we received a request to connect `{{ email }}` | ||
to the `{{ username }}` account on Gratipay (formerly Gittip). | ||
Now we're finally sending a verification email! | ||
|
||
Ring a bell? Follow this link to finish connecting your email: | ||
|
||
{{ link }} |
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,17 @@ | ||
{{ _("Connect to {0} on Gratipay?", username) }} | ||
|
||
[---] text/html | ||
{{ _("We've received a request to connect {0} to the {1} account on Gratipay. Sound familiar?", | ||
'<b>%s</b>' % escape(email), | ||
'<b><a href="https://gratipay.com/{0}">{0}</a></b>'.format(username)) }} | ||
<br> | ||
<br> | ||
<a href="{{ link }}" style="color: #fff; text-decoration:none; display:inline-block; padding: 0 15px; background: #396; font: normal 14px/40px Arial, sans-serif; white-space: nowrap; border-radius: 3px">{{ _("Yes, proceed!") }}</a> | ||
|
||
[---] text/plain | ||
{{ _("We've received a request to connect {0} to the {1} account on Gratipay. Sound familiar?", | ||
email, username) }} | ||
|
||
{{ _("Follow this link to finish connecting your email:") }} | ||
|
||
{{ link }} |
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,13 @@ | ||
{{ _("Connecting {0} to {1} on Gratipay.", new_email, username) }} | ||
|
||
[---] text/html | ||
{{ _("We are connecting {0} to the {1} account on Gratipay. This is a notification " | ||
"sent to {2} because that is the primary email address we have on file.", | ||
'<b>%s</b>' % escape(new_email), | ||
'<b><a href="https://gratipay.com/{0}">{0}</a></b>'.format(username), | ||
'<b>%s</b>' % escape(email)) }} | ||
|
||
[---] text/plain | ||
{{ _("We are connecting {0} to the {1} account on Gratipay. This is a notification " | ||
"sent to {2} because that is the primary email address we have on file.", | ||
new_email, username, email) }} |
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 was deleted.
Oops, something went wrong.
Oops, something went wrong.