Merge pull request #162 from simple-login/fido-beta
Add Fido as a beta feature
This commit is contained in:
commit
f5efab940c
13
README.md
13
README.md
|
@ -1160,18 +1160,7 @@ Whenever the model changes, a new migration has to be created.
|
||||||
If you have Docker installed, you can create the migration by the following script:
|
If you have Docker installed, you can create the migration by the following script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# create a postgres database for SimpleLogin
|
sh new_migration.sh
|
||||||
docker rm -f sl-db
|
|
||||||
docker run -p 5432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres
|
|
||||||
|
|
||||||
# run run `flask db upgrade` to upgrade the DB to the latest stage and
|
|
||||||
env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db upgrade
|
|
||||||
|
|
||||||
# finally `flask db migrate` to generate the migration script.
|
|
||||||
env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db migrate
|
|
||||||
|
|
||||||
# remove the db
|
|
||||||
docker rm -f sl-db
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure to review the migration script before committing it.
|
Make sure to review the migration script before committing it.
|
||||||
|
|
|
@ -31,7 +31,7 @@ def fido():
|
||||||
|
|
||||||
user = User.get(user_id)
|
user = User.get(user_id)
|
||||||
|
|
||||||
if not (user and (user.fido_enabled())):
|
if not (user and user.fido_enabled()):
|
||||||
flash("Only user with security key linked should go to this page", "warning")
|
flash("Only user with security key linked should go to this page", "warning")
|
||||||
return redirect(url_for("auth.login"))
|
return redirect(url_for("auth.login"))
|
||||||
|
|
||||||
|
|
|
@ -85,22 +85,25 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- END change name & profile picture -->
|
<!-- END change name & profile picture -->
|
||||||
|
|
||||||
<div class="card">
|
{% if current_user.can_use_fido %}
|
||||||
<div class="card-body">
|
<div class="card">
|
||||||
<div class="card-title">Security Key (WebAuthn)</div>
|
<div class="card-body">
|
||||||
<div class="mb-3">
|
<div class="card-title">Security Key (WebAuthn)</div>
|
||||||
You can secure your account by linking either your FIDO-supported physical key such as Yubikey, Google Titan,
|
<div class="mb-3">
|
||||||
or a device with appropriate hardware to your account.
|
You can secure your account by linking either your FIDO-supported physical key such as Yubikey, Google
|
||||||
|
Titan,
|
||||||
|
or a device with appropriate hardware to your account.
|
||||||
|
</div>
|
||||||
|
{% if current_user.fido_uuid is none %}
|
||||||
|
<a href="{{ url_for('dashboard.fido_setup') }}" class="btn btn-outline-primary">Setup WebAuthn</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('dashboard.fido_cancel') }}" class="btn btn-outline-danger">Disable WebAuthn</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if current_user.fido_uuid is none %}
|
|
||||||
<a href="{{ url_for('dashboard.fido_setup') }}" class="btn btn-outline-primary">Setup WebAuthn</a>
|
|
||||||
{% else %}
|
|
||||||
<a href="{{ url_for('dashboard.fido_cancel') }}" class="btn btn-outline-danger">Disable WebAuthn</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
<div class="card">
|
<div class="card" id="totp">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="card-title">One-Time Password (TOTP)</div>
|
<div class="card-title">One-Time Password (TOTP)</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
|
|
@ -25,6 +25,13 @@ def fido_setup():
|
||||||
flash("You have already registered your security key", "warning")
|
flash("You have already registered your security key", "warning")
|
||||||
return redirect(url_for("dashboard.index"))
|
return redirect(url_for("dashboard.index"))
|
||||||
|
|
||||||
|
if not current_user.can_use_fido:
|
||||||
|
flash(
|
||||||
|
"This feature is currently in invitation-only beta. Please send us an email if you want to try",
|
||||||
|
"warning",
|
||||||
|
)
|
||||||
|
return redirect(url_for("dashboard.index"))
|
||||||
|
|
||||||
fido_token_form = FidoTokenForm()
|
fido_token_form = FidoTokenForm()
|
||||||
|
|
||||||
# Handling POST requests
|
# Handling POST requests
|
||||||
|
|
|
@ -140,8 +140,13 @@ class User(db.Model, ModelMixin, UserMixin):
|
||||||
fido_pk = db.Column(db.String(), nullable=True, unique=True)
|
fido_pk = db.Column(db.String(), nullable=True, unique=True)
|
||||||
fido_sign_count = db.Column(db.Integer(), nullable=True)
|
fido_sign_count = db.Column(db.Integer(), nullable=True)
|
||||||
|
|
||||||
|
# whether user can use Fido
|
||||||
|
can_use_fido = db.Column(
|
||||||
|
db.Boolean, default=False, nullable=False, server_default="0"
|
||||||
|
)
|
||||||
|
|
||||||
def fido_enabled(self) -> bool:
|
def fido_enabled(self) -> bool:
|
||||||
if self.fido_uuid is not None:
|
if self.can_use_fido and self.fido_uuid is not None:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,13 @@ import collections
|
||||||
import phpserialize
|
import phpserialize
|
||||||
import requests
|
import requests
|
||||||
from Crypto.Hash import SHA1
|
from Crypto.Hash import SHA1
|
||||||
|
|
||||||
# Crypto can be found at https://pypi.org/project/pycryptodome/
|
# Crypto can be found at https://pypi.org/project/pycryptodome/
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
from Crypto.Signature import PKCS1_v1_5
|
from Crypto.Signature import PKCS1_v1_5
|
||||||
|
|
||||||
from app.config import PADDLE_PUBLIC_KEY_PATH, PADDLE_VENDOR_ID, PADDLE_AUTH_CODE
|
from app.config import PADDLE_PUBLIC_KEY_PATH, PADDLE_VENDOR_ID, PADDLE_AUTH_CODE
|
||||||
|
|
||||||
# Your Paddle public key.
|
# Your Paddle public key.
|
||||||
from app.log import LOG
|
from app.log import LOG
|
||||||
|
|
||||||
|
|
43
migrations/versions/2020_050717_026e7a782ed6_.py
Normal file
43
migrations/versions/2020_050717_026e7a782ed6_.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 026e7a782ed6
|
||||||
|
Revises: ae94fe5c4e9f
|
||||||
|
Create Date: 2020-05-07 17:51:48.440962
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy_utils
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '026e7a782ed6'
|
||||||
|
down_revision = 'ae94fe5c4e9f'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('users', sa.Column('can_use_fido', sa.Boolean(), server_default='0', nullable=False))
|
||||||
|
op.add_column('users', sa.Column('fido_credential_id', sa.String(), nullable=True))
|
||||||
|
op.add_column('users', sa.Column('fido_pk', sa.String(), nullable=True))
|
||||||
|
op.add_column('users', sa.Column('fido_sign_count', sa.Integer(), nullable=True))
|
||||||
|
op.add_column('users', sa.Column('fido_uuid', sa.String(), nullable=True))
|
||||||
|
op.create_unique_constraint(None, 'users', ['fido_credential_id'])
|
||||||
|
op.create_unique_constraint(None, 'users', ['fido_pk'])
|
||||||
|
op.create_unique_constraint(None, 'users', ['fido_uuid'])
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_constraint(None, 'users', type_='unique')
|
||||||
|
op.drop_constraint(None, 'users', type_='unique')
|
||||||
|
op.drop_constraint(None, 'users', type_='unique')
|
||||||
|
op.drop_column('users', 'fido_uuid')
|
||||||
|
op.drop_column('users', 'fido_sign_count')
|
||||||
|
op.drop_column('users', 'fido_pk')
|
||||||
|
op.drop_column('users', 'fido_credential_id')
|
||||||
|
op.drop_column('users', 'can_use_fido')
|
||||||
|
# ### end Alembic commands ###
|
16
new_migration.sh
Normal file
16
new_migration.sh
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Generate a new migration script using Docker
|
||||||
|
# To run it:
|
||||||
|
# sh new_migration.sh
|
||||||
|
|
||||||
|
# create a postgres database for SimpleLogin
|
||||||
|
docker rm -f sl-db
|
||||||
|
docker run -p 5432:5432 --name sl-db -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=sl -d postgres
|
||||||
|
|
||||||
|
# run run `flask db upgrade` to upgrade the DB to the latest stage and
|
||||||
|
env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db upgrade
|
||||||
|
|
||||||
|
# finally `flask db migrate` to generate the migration script.
|
||||||
|
env DB_URI=postgresql://postgres:postgres@127.0.0.1:5432/sl flask db migrate
|
||||||
|
|
||||||
|
# remove the db
|
||||||
|
docker rm -f sl-db
|
|
@ -13,7 +13,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ render_text("My name is Son. I’m the founder of SimpleLogin and I wanted to be the first to welcome you on board.") }}
|
{{ render_text("My name is Son. I’m the founder of SimpleLogin and I wanted to be the first to welcome you on board.") }}
|
||||||
|
|
||||||
{{ render_text('To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your <a href="https://app.simplelogin.io/dashboard/setting">Setting page</a>.') }}
|
{{ render_text('To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your <a href="https://app.simplelogin.io/dashboard/setting/#totp">Setting page</a>.') }}
|
||||||
|
|
||||||
{{ render_text('If you have any feedback or improvement ideas please let me know by simply replying to this email. Yes, this email is not sent from a no-reply address.
|
{{ render_text('If you have any feedback or improvement ideas please let me know by simply replying to this email. Yes, this email is not sent from a no-reply address.
|
||||||
') }}
|
') }}
|
||||||
|
|
Loading…
Reference in a new issue