Skip to content

Commit

Permalink
Simplify email verification to a single address and add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
barche committed Oct 7, 2016
1 parent 656c9c5 commit d2a172d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 28 deletions.
4 changes: 2 additions & 2 deletions engine/src/juliabox/plugins/email_whitelist/email_verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def get(self):
return

if verification_code == None:
record = EmailVerifyDB(user_id, "pending_email_form_response", create=False)
record = EmailVerifyDB(user_id)
record.set_email(email)

base_uri = self.request.protocol + "://" + self.request.host + self.request.uri.split('?')[0]
Expand All @@ -64,7 +64,7 @@ def get(self):

self.render(os.path.join(EmailWhitelistHandler.TEMPLATE_PATH, "message.tpl"), cfg=JBoxCfg.nv, message="Email sent. Please click the link in the mail.")
else:
record = EmailVerifyDB(user_id, email, create=False)
record = EmailVerifyDB(user_id)
if record.verify(verification_code):
s = dict(error="", success="Verification OK, please log in again", info="", pending_activation=False, user_id="")
self.rendertpl("index.tpl", cfg=JBoxCfg.nv, state=s)
Expand Down
22 changes: 5 additions & 17 deletions engine/src/juliabox/plugins/email_whitelist/email_verify_tbl.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,22 @@ class EmailVerifyDB(JBPluginDB):
KEYS_TYPES = [JBPluginDB.VCHAR]
TYPES = [JBPluginDB.VCHAR, JBPluginDB.VCHAR, JBPluginDB.INT]

def __init__(self, user_id, email, create=False):
count = self.query_count(user_id__eq=user_id, email__eq=email)
if count > 0 and create:
raise RuntimeError("Email verify record exists, but create was requested")
if count == 0 and (not create):
raise RuntimeError("Email verify record does not exist")
def __init__(self, user_id):
count = self.query_count(user_id__eq=user_id)
create = (count == 0)

if create:
data = {
'user_id': user_id,
'email': email,
'email': '',
'verification_code': gen_random_secret(),
'is_verified': 0
}
self.create(data)

self.item = self.fetch(user_id=user_id, email=email)
self.item = self.fetch(user_id=user_id)
self.is_new = create

@classmethod
def get_verified_emails(cls, user_id):
records = cls.query(user_id__eq=user_id, is_verified__eq=1)
verified_email_list = []
for rec in records:
verified_email_list.append(rec['email'])
return verified_email_list


def set_email(self, email):
self.set_attrib('email', email)
self.save()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,10 @@ def process_user_id(handler, user_id):
if EmailWhitelistHandler.is_whitelisted(user_id):
return True

# Check if any of the users verified email addresses match
verified_emails = EmailVerifyDB.get_verified_emails(user_id)
for allowed_mail in EmailWhitelistHandler.WHITELIST:
for verified_email in verified_emails:
if EmailWhitelistHandler.is_whitelisted(verified_email):
return True

# No match, create a pending email verify request
EmailVerifyDB(user_id, "pending_email_form_response", create=True)
# No match on user_id, create a pending email verify request if needed
verify_record = EmailVerifyDB(user_id)
if verify_record.is_verified():
return True

handler.render(os.path.join(EmailWhitelistHandler.TEMPLATE_PATH, "email_whitelist.tpl"), cfg=JBoxCfg.nv, user_id=user_id, message="Please enter white-listed email as per tutor instructions:")

Expand Down
39 changes: 39 additions & 0 deletions engine/src/juliabox/plugins/email_whitelist/info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Email whitelist plugin

Post-auth plugin to check if an email address used by the user matches a whitelisted pattern. The procedure is as follows:

1. Verify the `user_id` against the whitelist and allow the user if it matches
2. Check if the user has a verified alternate email, and if so allow access
2. If not, ask the user for an additional email address
3. Generate a random secret and email it to this address, embedded in a weblink
4. Upon clicking the link in the email, the address is verified and the user is directed to the login page
5. From now step 2 will succeed automatically upon successful authentication

The plugin creates a new database table `jbox_email_verify` to store the verified email addresses. It also requires a configured plugin for sending email, and a config entry `email_whitelist` with a list of domains or email addresses in `allowed_addresses`. It checks that the given email address ends with the given pattern, ignoring case. This allows whitelisting either domains or individual addresses.

Example config:

```
{
#... other config as needed ...
"email_whitelist": {
"allowed_addresses": [
"julia.org",
"[email protected]"
]
},
"user_activation": {
"sender": "[email protected]",
"sender_password": "",
"smtp_url": "smtp.mydomain.com",
"smtp_port_no": 587,
"max_24hrs": 100,
"max_rate_per_sec": 1
},
"plugins": [
#... other plugins as necessary ...
"juliabox.plugins.email_whitelist",
"juliabox.plugins.sendmail_smtp"
]
}
```

0 comments on commit d2a172d

Please sign in to comment.