-
Notifications
You must be signed in to change notification settings - Fork 69
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
Add 2 factor authentication as optional feature #70
Conversation
@@ -69,6 +69,11 @@ class NativeAuthenticator(Authenticator): | |||
default_value=False, | |||
help="Deletes FirstUse Authenticator database after the import" | |||
) | |||
add_two_factor_authentication = Bool( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split this into two parts:
- Allow users to have 2FA
- Require users to have 2FA
In the former, some users might choose to protect their own accounts with 2FA, but isn't enforced. (2) is more complicated - what happens to people who already had created accounts without 2FA? How can they log in?
So I think one PR should be to allow_two_factor_authentication (or just allow_2fa), and it makes it optional for users to set up and use 2FA. There should probably also be a button in the admin screen that shows admins if this user has 2fa enabled, and optionally allows them to reset it.
After that, we can figure out how to make it required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed this makes sense. I'll refactor this PR to make the 2fa an optional character within user and then make another one to make it required and how to deal with people that signed in without 2fa, ok?
@@ -13,6 +16,12 @@ class UserInfo(Base): | |||
password = Column(LargeBinary, nullable=False) | |||
is_authorized = Column(Boolean, default=False) | |||
email = Column(String) | |||
otp_secret = Column(String(10)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the '10' refer to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the token is created with size 10, so I limited here
Instead of having two login pages, what do you think about the flow being:
This is similar to how other websites do it, and is least confusing (I think). |
@yuvipanda I tried to figured it out how to do this but couldn't. Any suggestions? |
@leportella hmm, we'd probably have to use a secure cookie, and split the login logic into two pages. I tried to write out how exactly we would do it, and realized to do so securely will be quite complicated - probably too complicated for what we wanna do with NativeAuthenticator. I definitely don't trust myself to figure out how to do that safely right now... 😄 For now, let's just have the additional textbox in the original page if 2FA is enabled? I think that was in your original design. I mostly don't want us to have two different login pages. Sorry for all the confusion. |
@yuvipanda I just removed the second page login and added a more detailed description with photos here :) |
@choldgraf if you want to take a look as well, feel free :) |
Don't have an user? <a href="/signup">Signup!</a> | ||
<p>Don't have an user? <a href="/signup">Signup!</a></p> | ||
{% if two_factor_auth %} | ||
<p>Have Two Factor Authentication configured? <a href="/2fa">Sign In here!</a></p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about just putting the 2FA text box here? Currently the entire sign-in page is duplicated, and changes to them will have to be done twice - people will always forget! Same for the two Login Handlers.
There can be text like 'Enter 2FA Code here if enabled' with this text box, and it can be left empty by the user if they don't have 2FA enabled. This way, we avoid lots of duplication, and provide a mostly sane experience without making our code super complex.
What do you think?
hiiii 👋 is there a place that I could demo what this looks like w/ images and such? I think I agree with @yuvipanda that in general it'd be good to avoid duplicating UI elements (if anything to keep things more maintainable, but also to avoid confusing users). One thing we should make clear is that by 2FA we specifically mean "we'll give users a code that they must have to log in". I think nowadays many people assume that 2FA means something fancy like "we'll send you a text message to click a link" etc. Maybe add some extra wording to |
9dce809
to
e8c47ed
Compare
@yuvipanda I had already removed the 2nd login page but I had forgot to upload it. Now it is fixed. @choldgraf I did two gifs showing how is the system working now: (Gifs are too large to post here, but I left the link for you to take a look :) ) |
Seems good to me! Thanks for the improvement @leportella :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor changes, otherwise LGTM!
@@ -69,6 +69,11 @@ class NativeAuthenticator(Authenticator): | |||
default_value=False, | |||
help="Deletes FirstUse Authenticator database after the import" | |||
) | |||
allow_2fa = Bool( | |||
True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's turn this off by default to begin with. We can turn it on later if we wish.
@@ -33,6 +33,7 @@ | |||
{% endif %} | |||
<label for="username_input">Username:</label> | |||
<input id="username_input" type="text" autocapitalize="off" autocorrect="off" class="form-control" name="username" val="{{username}}" tabindex="1" autofocus="autofocus" /> | |||
<p></p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the empty
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A hack in the design the give more space between things 😅 I can take it off
I like it! <3 |
wooo, way to go! |
SignIn with 2fa allowed:
Signup with 2fa allowed:
Authorization area:
Not included but wanna do in another pr: