ska-referee-test/ref-test/admin/auth.py
viveksantayana db59e6c85c Dockerised. Restructured to remove circular import
Moved most of app definitions out of guard function to use wsgi
Updated configuration files and referencing of .env values.
Local version needs dotenv or exporting of env variables.
Dockerised version works fine without load_dotenv.
Ready to test now!
2021-12-05 03:49:31 +00:00

147 lines
5.6 KiB
Python

from flask import Blueprint, render_template, request, session, redirect
from flask.helpers import flash, url_for
from flask.json import jsonify
from .models.users import User
from uuid import uuid4
from common.security.database import decrypt_find_one, encrypted_update
from werkzeug.security import check_password_hash
from .views import admin_account_required, disable_on_registration, login_required, disable_if_logged_in, get_id_from_cookie
auth = Blueprint(
'admin_auth',
__name__,
template_folder='templates',
static_folder='static'
)
@auth.route('/account/', methods = ['GET', 'POST'])
@admin_account_required
@login_required
def account():
from .models.forms import UpdateAccountForm
from main import db
form = UpdateAccountForm()
_id = get_id_from_cookie()
user = decrypt_find_one(db.users, {'_id': _id})
if request.method == 'GET':
return render_template('/admin/auth/account.html', form = form, user = user)
if request.method == 'POST':
if form.validate_on_submit():
password_confirm = request.form.get('password_confirm')
if not check_password_hash(user['password'], password_confirm):
return jsonify({ 'error': 'The password you entered is incorrect.' }), 401
entry = User(
_id = _id,
password = request.form.get('password'),
email = request.form.get('email')
)
return entry.update()
else:
errors = [*form.password_confirm.errors, *form.password_reenter.errors, *form.password.errors, *form.email.errors]
return jsonify({ 'error': errors}), 400
@auth.route('/login/', methods=['GET','POST'])
@admin_account_required
@disable_if_logged_in
def login():
from .models.forms import LoginForm
form = LoginForm()
if request.method == 'GET':
return render_template('/admin/auth/login.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
entry = User(
username = request.form.get('username').lower(),
password = request.form.get('password'),
remember = request.form.get('remember')
)
return entry.login()
else:
errors = [*form.username.errors, *form.password.errors]
return jsonify({ 'error': errors}), 400
@auth.route('/logout/')
@admin_account_required
@login_required
def logout():
_id = get_id_from_cookie()
return User(_id=_id).logout()
@auth.route('/register/', methods=['GET','POST'])
@disable_on_registration
def register():
from .models.forms import RegistrationForm
form = RegistrationForm()
if request.method == 'GET':
return render_template('/admin/auth/register.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
entry = User(
_id = uuid4().hex,
username = request.form.get('username').lower(),
email = request.form.get('email'),
password = request.form.get('password'),
)
return entry.register()
else:
errors = [*form.username.errors, *form.email.errors, *form.password.errors, *form.password_reenter.errors]
return jsonify({ 'error': errors}), 400
@auth.route('/reset/', methods = ['GET', 'POST'])
@admin_account_required
@disable_if_logged_in
def reset():
from .models.forms import ResetPasswordForm
form = ResetPasswordForm()
if request.method == 'GET':
return render_template('/admin/auth/reset.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
entry = User(
username = request.form.get('username').lower(),
email = request.form.get('email'),
)
return entry.reset_password()
else:
errors = [*form.username.errors, *form.email.errors]
return jsonify({ 'error': errors}), 400
@auth.route('/reset/<token1>/<token2>/', methods = ['GET'])
@admin_account_required
@disable_if_logged_in
def reset_gateway(token1,token2):
from main import db
user = decrypt_find_one( db.users, {'reset_token' : token1} )
if not user:
return redirect(url_for('admin_auth.login'))
encrypted_update( db.users, {'reset_token': token1}, {'$unset': {'reset_token' : '', 'verification_token': ''}})
if not user['verification_token'] == token2:
flash('The verification of your password reset request failed and the token has been invalidated. Please make a new reset password request.', 'error'), 401
return redirect(url_for('admin_auth.reset'))
session['_id'] = user['_id']
session['reset_validated'] = True
return redirect(url_for('admin_auth.update_password_'))
@auth.route('/reset/update/', methods = ['GET','POST'])
@admin_account_required
@disable_if_logged_in
def update_password_():
from .models.forms import UpdatePasswordForm
form = UpdatePasswordForm()
if request.method == 'GET':
if 'reset_validated' not in session:
return redirect(url_for('admin_auth.login'))
session.pop('reset_validated')
return render_template('/admin/auth/update-password.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
entry = User(
_id = session['_id'],
password = request.form.get('password')
)
session.pop('_id')
return entry.update()
else:
errors = [*form.password.errors, *form.password_reenter.errors]
return jsonify({ 'error': errors}), 400