Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] #996 Add two-factor authentication #4373

Closed
wants to merge 5 commits into from

Conversation

asfaltboy
Copy link
Contributor

@asfaltboy asfaltboy commented Jul 28, 2018

EuroPython 2018 collaborators working on #996

@di
Copy link
Member

di commented Jul 28, 2018

Thanks for the PR! I think we'll probably want to hold off on merging this until we have the rest of #996 implemented as well.

@Sparkycz
Copy link
Contributor

Printscreen of the verification page http://prntscr.com/kc4x8e

@Sparkycz
Copy link
Contributor

@asfaltboy Could you please edit the title of the PR? This one is a little bit confusing.. Maybe to #996 add two-factor authentication

@asfaltboy asfaltboy changed the title [WIP] Add pyotp requirement and secret field [WIP] #996 Add two-factor authentication Jul 28, 2018
@asfaltboy
Copy link
Contributor Author

Good point @Sparkycz done that!

@Sparkycz
Copy link
Contributor

I think we should add one column more into the table AccountUser to indicate that the user has enabled two-factor auth.

Something like..

op.add_column(
    "accounts_user", sa.Column("2fa_enable", sa.Boolean(), nullable=False, default=False)
)

However, i'm still working on the login presenters..

@sergeykolosov
Copy link

@Sparkycz I'd like to make a number of clean-ups, commit squashes, etc, which basically involves rewriting branch history. Please notify me when it's an appropriate moment to do so, so that it won't conflict with your work on presenters.

@sergeykolosov sergeykolosov force-pushed the 996-add-2fa-support branch 2 times, most recently from 63f1781 to 255f9a3 Compare July 29, 2018 14:34
@sergeykolosov
Copy link

Updated the branch as follows:

  • fixed requirements ordering;
  • renamed OTP secret to TOTP secret (to avoid collisions as soon as other OTP methods are added);
  • fixed migration not being regenerated after field length change;
  • reordered and squashed commits into logically consistent groups;
  • implemented TOTP primitives and documented design decisions around those (see docstings);
  • covered TOTP primitives with basic unit-tests.

@nlhkabu suggested teaming up with others involved in #996 to avoid putting effort into duplicate artifacts.

@sergeykolosov
Copy link

@Sparkycz please address unittest & linting issues.

@pradyunsg
Copy link
Contributor

Could someone add the EuroPython label on this? :)

@sergeykolosov
Copy link

Those who had already applied DB migrations, before pulling the updated branch, make sure to downgrade first:

docker-compose run web python -m warehouse db downgrade 263b37556f74-1

@dstufft
Copy link
Member

dstufft commented Jul 29, 2018

FWIW, we do git merge --squash, so you don't have to worry at all about keeping a clean history.

Copy link
Member

@dstufft dstufft left a comment

Choose a reason for hiding this comment

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

Make sure that Not only do we guard the web based login, but we also need to figure out a strategy for requiring 2fa through basic auth as well. The easiest is probably going to be that whenever a user has 2fa, they have to send a password like <password>:<otp>. Alternatively we could accept a header like Warehouse-OTP, but that would require changes in twine.

consider using os.urandom(); this, however, is likely to cause
compatibility issues unless base32 vocabulary is used.
"""
return pyotp.random_base32(length=32)
Copy link
Member

Choose a reason for hiding this comment

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

Looking at this function, it's not actually being base32 encoded, it's just generating a 16 length random string which just happens to also be valid base32. If this just needs a be a base32 encoded string, then I'd prefer to do something like:

import base64
import os

def generate_totp_secret():
    return base64.b32encode(os.urandom(32)).decode("ascii")

This matches how we've done things in warehouse/utils/crypto.py.

"""
Verifies a given TOTP-secret and value.

The *valid_window* argument value is intentionally chosen to be non-zero
Copy link
Member

Choose a reason for hiding this comment

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

Can we add a note here as to what exactly the valid window translate into? Is it an extra second? 6?, 30?

The presenter does not do anything.

Fixes: pypa#996
@Sparkycz
Copy link
Contributor

I amended fix of the routes test into the commit with template. However there is still output from black linter (would reformat .. ) but i wouldn't like to reformat before the end of the changes in acounts/views.py

Meanwhile i'm finishing first version of the presenters (1-2 unit-tests left) despite We'll have to discuss the behavior of sessions etc..

@Sparkycz
Copy link
Contributor

Sparkycz commented Jul 29, 2018

i guess you'll have a lot of requests for changes but somewhere we've gotta start ;-)

todo:

  1. add enable/disable option of 2FA to profile settings
  2. implement calling of utils/otp functions to user_service

@woodruffw
Copy link
Member

I've restarted work on this in master...trailofbits:tob/996-add-2fa-support. Will open a PR shortly so that others can review progress in real time.

@woodruffw woodruffw mentioned this pull request Mar 13, 2019
@di
Copy link
Member

di commented May 4, 2019

Closing in favor of #5567, but thank you for your contribution!

@di di closed this May 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants