mirror of https://gitlab.com/tildes/tildes.git
Browse Source
Add two-factor authentication
Add two-factor authentication
Adds optional two-factor authentication support using TOTP, and including backup codes in case of a lost 2FA device.merge-requests/29/head
Oden
6 years ago
committed by
Deimos
15 changed files with 317 additions and 16 deletions
-
38tildes/alembic/versions/67e332481a6e_add_two_factor_authentication.py
-
3tildes/requirements-to-freeze.txt
-
3tildes/requirements.txt
-
1tildes/tildes/lib/ratelimit.py
-
24tildes/tildes/models/user/user.py
-
9tildes/tildes/routes.py
-
17tildes/tildes/templates/intercooler/login_two_factor.jinja2
-
3tildes/tildes/templates/intercooler/two_factor_disabled.jinja2
-
10tildes/tildes/templates/intercooler/two_factor_enabled.jinja2
-
2tildes/tildes/templates/login.jinja2
-
4tildes/tildes/templates/settings.jinja2
-
53tildes/tildes/templates/settings_two_factor.jinja2
-
66tildes/tildes/views/api/web/user.py
-
67tildes/tildes/views/login.py
-
33tildes/tildes/views/settings.py
@ -0,0 +1,38 @@ |
|||
"""Add two-factor authentication |
|||
|
|||
Revision ID: 67e332481a6e |
|||
Revises: fab922a8bb04 |
|||
Create Date: 2018-07-31 02:53:50.182862 |
|||
|
|||
""" |
|||
from alembic import op |
|||
import sqlalchemy as sa |
|||
from sqlalchemy.dialects import postgresql |
|||
|
|||
# revision identifiers, used by Alembic. |
|||
revision = "67e332481a6e" |
|||
down_revision = "fab922a8bb04" |
|||
branch_labels = None |
|||
depends_on = None |
|||
|
|||
|
|||
def upgrade(): |
|||
op.add_column( |
|||
"users", |
|||
sa.Column( |
|||
"two_factor_backup_codes", postgresql.ARRAY(sa.Text()), nullable=True |
|||
), |
|||
) |
|||
op.add_column( |
|||
"users", |
|||
sa.Column( |
|||
"two_factor_enabled", sa.Boolean(), server_default="false", nullable=False |
|||
), |
|||
) |
|||
op.add_column("users", sa.Column("two_factor_secret", sa.Text(), nullable=True)) |
|||
|
|||
|
|||
def downgrade(): |
|||
op.drop_column("users", "two_factor_secret") |
|||
op.drop_column("users", "two_factor_enabled") |
|||
op.drop_column("users", "two_factor_backup_codes") |
@ -0,0 +1,17 @@ |
|||
<p>Two-factor authentication is enabled on this account. Please enter the code from your authenticator app below. If you do not have access to your authenticator device, enter a backup code.</p> |
|||
|
|||
<form class="form-narrow" method="post" action="/login_two_factor" data-ic-post-to="/login_two_factor"> |
|||
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}"> |
|||
{% if keep %} |
|||
<input type="hidden" name="keep" value="on"> |
|||
{% endif %} |
|||
|
|||
<div class="form-group"> |
|||
<label class="form-label col-4" for="code">Code</label> |
|||
<input class="form-input" id="code" name="code" type="text" placeholder="Code" data-js-auto-focus> |
|||
</div> |
|||
|
|||
<div class="form-buttons"> |
|||
<button class="btn btn-primary" type="submit">Continue</button> |
|||
</div> |
|||
</form> |
@ -0,0 +1,3 @@ |
|||
<p>Two-factor authentication has been disabled. You will no longer need a code when logging in.</p> |
|||
|
|||
<p>Keep in mind: if you ever reenable two-factor authentication, your previous backup codes will not be valid.</p> |
@ -0,0 +1,10 @@ |
|||
<p>Congratulations! Two-factor authentication has been enabled.</p> |
|||
|
|||
<p>These are your backup codes. <strong class="text-warning">Make sure to write them down and store them in a safe place.</strong> |
|||
In the event that you lose access to your authenticator device, you will need these to regain access to your account. Each code can only be used once.</p> |
|||
|
|||
<code> |
|||
{% for code in backup_codes %} |
|||
- {{ code }}<br /> |
|||
{% endfor %} |
|||
</code> |
@ -0,0 +1,53 @@ |
|||
{% extends 'base_no_sidebar.jinja2' %} |
|||
|
|||
{% block title %}Set up two-factor authentication{% endblock %} |
|||
|
|||
{% block main_heading %}Set up two-factor authentication{% endblock %} |
|||
|
|||
{% block content %} |
|||
{% if request.user.two_factor_enabled %} |
|||
<p>You already have two-factor authentication enabled. To disable it, enter a code from your authenticator device below and click the button. If you do not have access to your authenticator device, enter a backup code.</p> |
|||
|
|||
<form |
|||
name="disable-two-factor" |
|||
autocomplete="off" |
|||
data-ic-post-to="{{ request.route_url('ic_user', username=request.user.username) }}" |
|||
data-ic-target="closest main" |
|||
> |
|||
<div class="form-group"> |
|||
<label class="form-label" for="code">TOTP or backup code</label> |
|||
<input class="form-input" id="code" name="code" type="text" placeholder="Code" required> |
|||
</div> |
|||
|
|||
<div class="form-buttons"> |
|||
<button class="btn btn-error" type="submit">Disable two-factor authentication</button> |
|||
</div> |
|||
</form> |
|||
{% else %} |
|||
<p>To get started, you'll need to install an app such as <a href="https://support.google.com/accounts/answer/1066447">Google Authenticator</a>, <a href="https://authy.com/download">Authy</a>, <a href="https://freeotp.github.io">FreeOTP</a>, or any app that supports TOTP.</p> |
|||
|
|||
<p>Next, scan the below QR code with the app of your choice.</p> |
|||
|
|||
<img src="/settings/two_factor/qr_code" alt="" /> |
|||
|
|||
<p>Lastly, enter the 6-digit code displayed in the app.</p> |
|||
|
|||
<div class="divider"></div> |
|||
|
|||
<form |
|||
name="enable-two-factor" |
|||
autocomplete="off" |
|||
data-ic-post-to="{{ request.route_url('ic_user', username=request.user.username) }}" |
|||
data-ic-target="closest main" |
|||
> |
|||
<div class="form-group"> |
|||
<label class="form-label" for="code">Code</label> |
|||
<input class="form-input" id="code" name="code" type="text" placeholder="Code" maxlength="6" pattern="[0-9]{6}"> |
|||
</div> |
|||
|
|||
<div class="form-buttons"> |
|||
<button class="btn btn-primary" type="submit">Enable two-factor authentication</button> |
|||
</div> |
|||
</form> |
|||
{% endif %} |
|||
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue