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

Limit pending verifications in emails UI #4579

Merged
merged 8 commits into from
Sep 17, 2017
Merged

Conversation

chadwhitacre
Copy link
Contributor

@chadwhitacre chadwhitacre commented Aug 22, 2017

← Implement deploy hooks (#4590) — Redux of #4571 — "Ready to verify" (#4584) →


We want to limit pending email address verification attempts to one, to prevent abuse (#4557). We need to do this both in the UI and in the API/db. The former is in some ways easier than the latter so let's try starting with that?

Todo

  • style listing
    • figure out what to do with action buttons
    • bring in status icons
  • constrain to available actions only
  • get all action buttons working again
  • bring back add email (as button next to header?)
  • confirm on removeConfirm some things #4581
  • change base back to master after Implement deploy hooks #4590

@chadwhitacre
Copy link
Contributor Author

screen shot 2017-08-22 at 5 37 57 pm

@chadwhitacre
Copy link
Contributor Author

Whoa! Monster mouse! 🐭 👹

y7qk328paa

@chadwhitacre chadwhitacre changed the title Limit verifications in UI Limit pending verifications Aug 23, 2017
@chadwhitacre chadwhitacre mentioned this pull request Aug 23, 2017
3 tasks
@chadwhitacre
Copy link
Contributor Author

I realized at #4571 (comment) that we can implement verification throttling with no additional schema changes by protecting against removal in the app layer. That's enough for here, though handling unsubscribes will still be a chore ...

@chadwhitacre
Copy link
Contributor Author

Squashed and rebased, was 1b1ee1e.

@chadwhitacre chadwhitacre force-pushed the limit-verifications-in-ui branch from 1b1ee1e to a6fae92 Compare August 23, 2017 12:02
@rohitpaulk
Copy link
Contributor

@whit537: Comments added at #4571 (comment)

@chadwhitacre chadwhitacre force-pushed the limit-verifications-in-ui branch from a6fae92 to 153469b Compare August 23, 2017 16:32
@chadwhitacre
Copy link
Contributor Author

chadwhitacre commented Aug 23, 2017

Okay! First chunk of work done in 153469b. Since we're already at 370 ∆ lines I will probably scope this just to the email listing, and implement the package page and API changes on other PRs.


zlgmqwct3p

@chadwhitacre
Copy link
Contributor Author

Picking up from #4571 (comment) ...

Umm, what if a person mistakenly enters a wrong email address?

Then they have to contact support. And that raises a good point: admins should be able to remove pending email verifications. If we get enough pressure on support then we consider re-enabling this as self-serve.

This is also a security risk, as far as I can tell. If we don't allow canceling verification requests - a mistake in entering a user's email could result in a malicious user taking over their account.

Sorry ... how so?

For example, github:

screen shot 2017-08-23 at 7 49 26 pm

👍

@rohitpaulk
Copy link
Contributor

rohitpaulk commented Aug 23, 2017

Sorry ... how so?

I enter a wrong email address. Person verifies the email, uses it (forgot password + reset password using email) to sign-in?

@chadwhitacre
Copy link
Contributor Author

I enter a wrong email address. Person verifies the email, uses it to sign-in?

Okay, but how do we mitigate that? That's the achilles heel of email for auth, isn't it? :-/

@rohitpaulk
Copy link
Contributor

rohitpaulk commented Aug 23, 2017

Okay, but how do we mitigate that?

Allow the user to remove the email immediately, by themselves. (We should also remove the verification token internally, when they do that)

@chadwhitacre
Copy link
Contributor Author

Allow the user to remove the email immediately, by themselves.

Okay, but then how do we protect against the other security risk: remove-and-add to work around verification throttling?

@chadwhitacre
Copy link
Contributor Author

Remember that verification links expire after 24 h anyway. We could tighten that to five minutes once we have instant send (#4545).

@rohitpaulk
Copy link
Contributor

rohitpaulk commented Aug 23, 2017

Okay, but then how do we protect against the other security risk: remove-and-add to work around verification throttling?

Can't we maintain persistent history of sent emails separately, and use that info to throttle? Canceling of an email verification link doesn't have to necessary delete ALL history of an email ever being sent.

@chadwhitacre
Copy link
Contributor Author

Sorry, throttling isn't the best word. The way we're headed here is to do both:

@chadwhitacre
Copy link
Contributor Author

I think we should tighten the verification window to five minutes: that will protect against "honest mistakes" turning into inadvertent phishing.

I think we should only allow one pending verification at a time with no option to remove. Our use case is different than GitHub's because we have all npm maintainer emails in our system. We're playing with fire. 😳 🔥

@rohitpaulk
Copy link
Contributor

Hmm, I see what you're getting at.

@rohitpaulk
Copy link
Contributor

Our use case is different than GitHub's because we have all npm maintainer emails in our system

I understand the 'limit pending verifications' concern. However, what does 'having all npm maintainer emails in our system' have to do with user email verification? Is this because it is tied to claiming packages?

@chadwhitacre
Copy link
Contributor Author

Is this because it is tied to claiming packages?

Yes. On my next PR I'll be modifying the UI on pages like https://gratipay.com/on/npm/express to limit the ability to initiate package claims when there are existing verifications (~= package claims) outstanding.

@chadwhitacre
Copy link
Contributor Author

We've had three users already report spam/phishing to us (#4557), so this isn't theoretical.

@rohitpaulk
Copy link
Contributor

rohitpaulk commented Aug 23, 2017

I still think that we should decouple email verification and linking packages. What I propose is:

  • Only allow users that have verified an email corresponding to a npm package to 'claim' it.
  • Once we do have a verified email that corresponds to an npm package, allow user to claim the package directly, and send a notice (not verification, just a notice) out to all maintainers. The email body should clearly mention that the Gratipay user is a verified owner of that specific email address.

Now that the email only says 'link [email protected] to the abcd account on Gratipay' - it is (perceived as?) less dangerous. As all services do, we'll just add a note saying 'If this wasn't you, no action is required' at the bottom. Generic sign-up email spam is understandable, and won't startle users like an email saying 'May we receive money on your behalf'.

@chadwhitacre
Copy link
Contributor Author

Okay, so can we hash out the user flow on https://gratipay.com/on/npm/express, then? Do we display all maintainer emails and only allow the user to initiate a message to addresses they've already verified? Do we only display email addresses they've already verified? Do we offer to send an email verification right from the package page? Do we make them click over to the Emails page to add the address there?

@rohitpaulk
Copy link
Contributor

Okay, so can we hash out the user flow on https://gratipay.com/on/npm/express, then? Do we display all maintainer emails and only allow the user to initiate a message to addresses they've already verified? Do we only display email addresses they've already verified? Do we offer to send an email verification right from the package page? Do we make them click over to the Emails page to add the address there?

Basics, just to get things working:

  • If user is a maintainer, show 'Claim' button directly. Make it clear that the user is allowed to claim this package because they own that specific address, and also show the list of maintainers that we'll send emails to if they claim the package.
  • If the user is not a maintainer, show all emails, say that you have to add one of these (link to emails page) as a verified email address on Gratipay. Once verified, come back to this page and you'll be able to claim a package.

Streamlining (building upon the above):

  • When an email is verified, automatically fish out unclaimed packages related to that address, and take them to the claim page? (or a bulk claim page?)
  • Add 'link/verify' buttons to the emails on the 'claim' page, without requiring the user to go to the emails page and come back.

@chadwhitacre
Copy link
Contributor Author

send a notice (not verification, just a notice) out to all maintainers.

That's #4425.

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

Rebased onto #4590, was 4f33932.

@chadwhitacre chadwhitacre force-pushed the limit-verifications-in-ui branch from 4f33932 to 64b3555 Compare August 31, 2017 19:18
@chadwhitacre chadwhitacre changed the base branch from master to deploy++ August 31, 2017 19:19
@chadwhitacre chadwhitacre force-pushed the limit-verifications-in-ui branch 2 times, most recently from dfa177e to a6b4315 Compare September 1, 2017 19:18
@rohitpaulk rohitpaulk changed the base branch from deploy++ to master September 8, 2017 13:47
@chadwhitacre chadwhitacre force-pushed the limit-verifications-in-ui branch from a6b4315 to dd375b8 Compare September 8, 2017 13:48
@chadwhitacre
Copy link
Contributor Author

Rebased back onto master, was a6b4315.

for email in emails:
i = 0 if email.address == participant.email_address else 1 if email.verified else 2
groups[i].append(email)
emails = sum(groups, [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😃 Is this common usage?

Perils of not having flatten in the std lib? :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's how to spell flatten in Python. 🐭


emails = participant.get_emails()
groups = [[], [], []] # primary, verified, unverified
for email in emails:
i = 0 if email.address == participant.email_address else 1 if email.verified else 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're essentially doing a sort_by(func) action here, can't we use https://docs.python.org/3/library/functions.html#sorted with the key param?

i.e. something like:

def get_sort_key(email):
  if email.address == participant.email_address:
    return 0
  elif email.verified:
     return 1
  else:
    return 2

sorted_emails = sorted(emails, key=get_sort_key)

Copy link
Contributor

@rohitpaulk rohitpaulk Sep 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks less cryptic to me than the awkward spelling of flatten, and the inlined inline if 😛

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 11a93a4

from gratipay.testing import BrowserHarness, QueuedEmailHarness


class Row(object):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat!

@rohitpaulk rohitpaulk force-pushed the limit-verifications-in-ui branch from dd375b8 to c3452ab Compare September 8, 2017 14:37
@rohitpaulk rohitpaulk closed this Sep 8, 2017
@rohitpaulk rohitpaulk reopened this Sep 8, 2017
- don't want before.py (see deploy/README)
- run after.py directly on dyno vs. redirect
- dodge race condition around clicks and page reloading
- factor out helpers into proper classes
- simplify remove action to maintain proper state (presence of add form)
- minor formatting tweak in sptfile
@rohitpaulk
Copy link
Contributor

Rebased, previous head was @c3452ab8472658a42f2acdefa5cd865bbb645f33.

@rohitpaulk rohitpaulk force-pushed the limit-verifications-in-ui branch from c3452ab to 8eb5d0e Compare September 16, 2017 14:14
@rohitpaulk
Copy link
Contributor

@whit537 This looks good to me. Ready to merge?

@chadwhitacre
Copy link
Contributor Author

@rohitpaulk Yes!

@rohitpaulk rohitpaulk merged commit 048099f into master Sep 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants