key management page
This commit is contained in:
parent
6ea17b4feb
commit
b64ed7ad63
|
@ -13,7 +13,7 @@ from .views import (
|
|||
mfa_setup,
|
||||
mfa_cancel,
|
||||
fido_setup,
|
||||
fido_cancel,
|
||||
fido_manage,
|
||||
domain_detail,
|
||||
lifetime_licence,
|
||||
directory,
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
{% extends 'default.html' %}
|
||||
{% set active_page = "setting" %}
|
||||
{% block title %}
|
||||
Unlink Security Key
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block default_content %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h1 class="h2">Unlink Your Security Key</h1>
|
||||
<p>
|
||||
Please enter the password of your account so that we can ensure it's you.
|
||||
</p>
|
||||
|
||||
<form method="post">
|
||||
{{ password_check_form.csrf_token }}
|
||||
|
||||
<div class="font-weight-bold mt-5">Password</div>
|
||||
|
||||
{{ password_check_form.password(class="form-control", autofocus="true") }}
|
||||
{{ render_field_errors(password_check_form.password) }}
|
||||
<button class="btn btn-lg btn-danger mt-2">Unlink Key</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,53 @@
|
|||
{% extends 'default.html' %}
|
||||
{% set active_page = "setting" %}
|
||||
{% block title %}
|
||||
Security Key Manage
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<script src="{{ url_for('static', filename='node_modules/qrious/dist/qrious.min.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block default_content %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h1 class="h2">Manage Your Security Key</h1>
|
||||
<p>Delete all keys will also disable WebAuthn 2FA.</p>
|
||||
|
||||
<form id="formManageKey" method="post">
|
||||
{{ fido_manage_form.csrf_token }}
|
||||
{{ fido_manage_form.credential_id(class="form-control", placeholder="") }}
|
||||
</form>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Linked At</th>
|
||||
<th scope="col" class="text-center">Operation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for key in keys%}
|
||||
<tr>
|
||||
<th scope="row">{{ key.id }}</th>
|
||||
<td>{{ key.name }}</td>
|
||||
<td><script>document.write(new Date('{{ key.created_at }}').toLocaleString());</script></td>
|
||||
<td class="text-center"><button class="btn btn-outline-danger" onclick="$('#credential_id').val('{{ key.credential_id }}'); $('#formManageKey').submit();">Delete</button></td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
<tr>
|
||||
<th scope="row">#</th>
|
||||
<td>Link a New Key</td>
|
||||
<td></td>
|
||||
<td class="text-center"><a href="{{ url_for('dashboard.fido_setup') }}"><button class="btn btn-outline-success">Link</button></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -97,7 +97,7 @@
|
|||
{% 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>
|
||||
<a href="{{ url_for('dashboard.fido_manage') }}" class="btn btn-outline-info">Manage WebAuthn</a>
|
||||
<a href="{{ url_for('dashboard.recovery_code_route') }}" class="btn btn-outline-secondary">Recovery Codes</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
from flask import render_template, flash, redirect, url_for
|
||||
from flask_login import login_required, current_user
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import PasswordField, validators
|
||||
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db
|
||||
from app.models import RecoveryCode
|
||||
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
password = PasswordField("Password", validators=[validators.DataRequired()])
|
||||
|
||||
|
||||
@dashboard_bp.route("/fido_cancel", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def fido_cancel():
|
||||
if not current_user.fido_enabled():
|
||||
flash("You haven't registed a security key", "warning")
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
password_check_form = LoginForm()
|
||||
|
||||
if password_check_form.validate_on_submit():
|
||||
password = password_check_form.password.data
|
||||
|
||||
if current_user.check_password(password):
|
||||
current_user.fido_pk = None
|
||||
current_user.fido_uuid = None
|
||||
current_user.fido_sign_count = None
|
||||
current_user.fido_credential_id = None
|
||||
db.session.commit()
|
||||
|
||||
# user does not have any 2FA enabled left, delete all recovery codes
|
||||
if not current_user.two_factor_authentication_enabled():
|
||||
RecoveryCode.empty(current_user)
|
||||
|
||||
flash("We've unlinked your security key.", "success")
|
||||
return redirect(url_for("dashboard.index"))
|
||||
else:
|
||||
flash("Incorrect password", "warning")
|
||||
|
||||
return render_template(
|
||||
"dashboard/fido_cancel.html", password_check_form=password_check_form
|
||||
)
|
|
@ -0,0 +1,59 @@
|
|||
from flask import render_template, flash, redirect, url_for
|
||||
from flask_login import login_required, current_user
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import HiddenField, validators
|
||||
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db
|
||||
from app.log import LOG
|
||||
from app.models import RecoveryCode, FIDO
|
||||
from app.dashboard.views.enter_sudo import sudo_required
|
||||
|
||||
|
||||
class FidoManageForm(FlaskForm):
|
||||
credential_id = HiddenField("credential_id", validators=[validators.DataRequired()])
|
||||
|
||||
|
||||
@dashboard_bp.route("/fido_manage", methods=["GET", "POST"])
|
||||
@login_required
|
||||
@sudo_required
|
||||
def fido_manage():
|
||||
if not current_user.fido_enabled():
|
||||
flash("You haven't registed a security key", "warning")
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
fido_manage_form = FidoManageForm()
|
||||
|
||||
if fido_manage_form.validate_on_submit():
|
||||
credential_id = fido_manage_form.credential_id.data
|
||||
|
||||
fido_key = FIDO.get_by(uuid=current_user.fido_uuid, credential_id=credential_id)
|
||||
|
||||
if not fido_key:
|
||||
flash("Unknown error, redirect back to manage page", "warning")
|
||||
return redirect(url_for("dashboard.fido_manage"))
|
||||
|
||||
FIDO.delete(fido_key.id)
|
||||
db.session.commit()
|
||||
|
||||
LOG.d(f"FIDO Key ID={fido_key.id} Removed")
|
||||
flash(f"Key {fido_key.name} successfully unlinked", "success")
|
||||
|
||||
# Disable FIDO for the user if all keys have been deleted
|
||||
if not FIDO.filter_by(uuid=current_user.fido_uuid).all():
|
||||
current_user.fido_uuid = None
|
||||
db.session.commit()
|
||||
|
||||
# user does not have any 2FA enabled left, delete all recovery codes
|
||||
if not current_user.two_factor_authentication_enabled():
|
||||
RecoveryCode.empty(current_user)
|
||||
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
return redirect(url_for("dashboard.fido_manage"))
|
||||
|
||||
return render_template(
|
||||
"dashboard/fido_manage.html",
|
||||
fido_manage_form=fido_manage_form,
|
||||
keys=FIDO.filter_by(uuid=current_user.fido_uuid),
|
||||
)
|
|
@ -13,7 +13,7 @@ from app.config import RP_ID, URL
|
|||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db
|
||||
from app.log import LOG
|
||||
from app.models import FIDO
|
||||
from app.models import FIDO, RecoveryCode
|
||||
from app.dashboard.views.enter_sudo import sudo_required
|
||||
|
||||
|
||||
|
@ -84,7 +84,10 @@ def fido_setup():
|
|||
)
|
||||
|
||||
flash("Security key has been activated", "success")
|
||||
return redirect(url_for("dashboard.recovery_code_route"))
|
||||
if not RecoveryCode.query.filter_by(user_id=current_user.id).all():
|
||||
return redirect(url_for("dashboard.recovery_code_route"))
|
||||
else:
|
||||
return redirect(url_for("dashboard.fido_manage"))
|
||||
|
||||
# Prepare information for key registration process
|
||||
fido_uuid = (
|
||||
|
|
Loading…
Reference in New Issue