sudo mode

This commit is contained in:
devStorm 2020-05-18 02:14:40 -07:00
parent 35f0c094fe
commit f79eb90d2a
No known key found for this signature in database
GPG Key ID: D52E1B66F336AC57
6 changed files with 94 additions and 1 deletions

View File

@ -9,6 +9,7 @@ from .views import (
api_key,
custom_domain,
alias_contact_manager,
enter_sudo,
mfa_setup,
mfa_cancel,
fido_setup,

View File

@ -0,0 +1,31 @@
{% extends 'default.html' %}
{% set active_page = "setting" %}
{% block title %}
SUDO MODE
{% endblock %}
{% block default_content %}
<div class="card">
<div class="card-body">
<h1 class="h2">Entering Sudo Mode</h1>
<p>
You are trying to change sensitive settings
</p>
<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">Submit</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,55 @@
from time import time
from flask import render_template, flash, redirect, url_for, session, request
from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import PasswordField, validators
from functools import wraps
from app.dashboard.base import dashboard_bp
from app.config import DEBUG
from app.log import LOG
class LoginForm(FlaskForm):
password = PasswordField("Password", validators=[validators.DataRequired()])
@dashboard_bp.route("/enter_sudo", methods=["GET", "POST"])
@login_required
def enter_sudo():
password_check_form = LoginForm()
if password_check_form.validate_on_submit():
password = password_check_form.password.data
if current_user.check_password(password):
session["sudo_time"] = int(time())
# User comes to sudo page from another page
next_url = request.args.get("next")
if next_url:
LOG.debug("redirect user to %s", next_url)
return redirect(next_url)
else:
LOG.debug("redirect user to dashboard")
return redirect(url_for("dashboard.index"))
else:
flash("Incorrect password", "warning")
return render_template(
"dashboard/enter_sudo.html", password_check_form=password_check_form
)
def sudo_required(f):
@wraps(f)
def wrap(*args, **kwargs):
# Reset sudo mode in every 20s under dev mode
SUDO_GAP = 900 if not DEBUG else 20
if "sudo_time" not in session or (time() - int(session["sudo_time"])) > SUDO_GAP:
return redirect(
url_for("dashboard.enter_sudo", next=request.path)
)
return f(*args, **kwargs)
return wrap

View File

@ -1,6 +1,7 @@
import json
import secrets
import uuid
from time import time
import webauthn
from flask import render_template, flash, redirect, url_for, session
@ -13,7 +14,7 @@ from app.dashboard.base import dashboard_bp
from app.extensions import db
from app.log import LOG
from app.models import FIDO
from app.dashboard.views.enter_sudo import sudo_required
class FidoTokenForm(FlaskForm):
sk_assertion = HiddenField("sk_assertion", validators=[validators.DataRequired()])
@ -21,6 +22,7 @@ class FidoTokenForm(FlaskForm):
@dashboard_bp.route("/fido_setup", methods=["GET", "POST"])
@login_required
@sudo_required
def fido_setup():
if not current_user.can_use_fido:
flash(

View File

@ -7,6 +7,7 @@ from wtforms import StringField, validators
from app.dashboard.base import dashboard_bp
from app.extensions import db
from app.models import RecoveryCode
from app.dashboard.views.enter_sudo import sudo_required
class OtpTokenForm(FlaskForm):
@ -15,6 +16,7 @@ class OtpTokenForm(FlaskForm):
@dashboard_bp.route("/mfa_cancel", methods=["GET", "POST"])
@login_required
@sudo_required
def mfa_cancel():
if not current_user.enable_otp:
flash("you don't have MFA enabled", "warning")

View File

@ -7,6 +7,7 @@ from wtforms import StringField, validators
from app.dashboard.base import dashboard_bp
from app.extensions import db
from app.log import LOG
from app.dashboard.views.enter_sudo import sudo_required
class OtpTokenForm(FlaskForm):
@ -15,6 +16,7 @@ class OtpTokenForm(FlaskForm):
@dashboard_bp.route("/mfa_setup", methods=["GET", "POST"])
@login_required
@sudo_required
def mfa_setup():
if current_user.enable_otp:
flash("you have already enabled MFA", "warning")