From 61bd6bc4bac0cb930304b6fd7dfadd24e5318914 Mon Sep 17 00:00:00 2001 From: Javier Sánchez Parra Date: Tue, 28 Jun 2022 12:31:59 +0200 Subject: Move password hashing to the backend This patch moves login password hashing from the frontend/javascript to the backend/flask. This patch moves password hashing of login and user management forms. Related commits: * c7b0024 ("Add password hashing") * 661254b ("Add 'Add user' to Users section") --- ogcp/forms/auth.py | 10 ++------- ogcp/static/js/ogcp.js | 45 --------------------------------------- ogcp/templates/auth/add_user.html | 11 +--------- ogcp/templates/auth/login.html | 11 +--------- ogcp/views.py | 19 +++++++++++++---- 5 files changed, 19 insertions(+), 77 deletions(-) (limited to 'ogcp') diff --git a/ogcp/forms/auth.py b/ogcp/forms/auth.py index edc5d9a..526fdb0 100644 --- a/ogcp/forms/auth.py +++ b/ogcp/forms/auth.py @@ -21,8 +21,6 @@ class LoginForm(FlaskForm): ) pwd = PasswordField( label=_l('Password'), - ) - pwd_hash = HiddenField( validators=[InputRequired()] ) submit_btn = SubmitField( @@ -37,15 +35,11 @@ class UserForm(FlaskForm): ) pwd = PasswordField( label=_l('Password'), - ) - pwd_hash = HiddenField( - validators=[InputRequired()] + validators=[InputRequired()], ) pwd_confirm = PasswordField( label=_l('Repeat password'), - ) - pwd_hash_confirm = HiddenField( - validators=[InputRequired()] + validators=[InputRequired()], ) admin = BooleanField( label=_l('Administrator'), diff --git a/ogcp/static/js/ogcp.js b/ogcp/static/js/ogcp.js index eaae467..8678759 100644 --- a/ogcp/static/js/ogcp.js +++ b/ogcp/static/js/ogcp.js @@ -242,48 +242,3 @@ function RemovePartition(evt) { }); } -async function digestMessage(msg) { - const msgUint8 = new TextEncoder().encode(msg); - const hashBuffer = await crypto.subtle.digest('SHA-512', msgUint8); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); - return hashHex; -} - -function digestLoginPassword() { - const loginForm = $('#login-form') - loginForm.one('submit', async function (event) { - event.preventDefault() - - const pwdInput = $('#pwd'); - const pwdHashInput = $('#pwd_hash'); - const pwdStr = pwdInput.val(); - const pwdStrHash = await digestMessage(pwdStr); - - pwdInput.prop( "disabled", true ); - pwdHashInput.val(pwdStrHash); - $(this).submit() - }); -} - -function digestUserFormPassword() { - const loginForm = $('#user-form') - loginForm.one('submit', async function (event) { - event.preventDefault() - - const pwdInput = $('#pwd'); - const pwdHashInput = $('#pwd_hash'); - const pwdStr = pwdInput.val(); - const pwdStrHash = await digestMessage(pwdStr); - - const pwdConfirmInput = $('#pwd_confirm'); - const pwdHashConfirmInput = $('#pwd_hash_confirm'); - const pwdConfirmStr = pwdConfirmInput.val(); - const pwdConfirmStrHash = await digestMessage(pwdConfirmStr); - - pwdInput.prop( "disabled", true ); - pwdHashInput.val(pwdStrHash); - pwdHashConfirmInput.val(pwdConfirmStrHash); - $(this).submit() - }); -} diff --git a/ogcp/templates/auth/add_user.html b/ogcp/templates/auth/add_user.html index af44caa..91866fb 100644 --- a/ogcp/templates/auth/add_user.html +++ b/ogcp/templates/auth/add_user.html @@ -12,15 +12,6 @@ {{ wtf.quick_form(form, action=url_for('user_add_post'), method='post', - button_map={'submit_btn':'primary'}, - id='user-form') }} - - + button_map={'submit_btn':'primary'}) }} {% endblock %} diff --git a/ogcp/templates/auth/login.html b/ogcp/templates/auth/login.html index 2b6cce9..20f6f8c 100644 --- a/ogcp/templates/auth/login.html +++ b/ogcp/templates/auth/login.html @@ -15,8 +15,7 @@ {{ wtf.quick_form(form, method='post', form_type='basic', - button_map={'submit_btn':'primary'}, - id='login-form') }} + button_map={'submit_btn':'primary'}) }} @@ -24,12 +23,4 @@ - - {% endblock %} diff --git a/ogcp/views.py b/ogcp/views.py index cd7213c..8d1b2e2 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -30,6 +30,7 @@ from flask_babel import _ from ogcp import app import requests import datetime +import hashlib import json import os import re @@ -187,6 +188,15 @@ def get_scopes(ips=set()): return scopes, clients + +def hash_password(pwd): + sha = hashlib.sha512() + sha.update(pwd.encode()) + pwd_hash = sha.hexdigest() + + return pwd_hash + + def authenticate_user(username, pwd): for user in app.config['USERS']: if user.get("USER") == username: @@ -280,8 +290,9 @@ def login(): form = LoginForm(request.form) if request.method == 'POST' and form.validate(): form_user = request.form['user'] - pwd = request.form['pwd_hash'] - user_dict = authenticate_user(form_user, pwd) + pwd = request.form['pwd'] + pwd_hash = hash_password(pwd) + user_dict = authenticate_user(form_user, pwd_hash) if not user_dict: return render_template('auth/login.html', form=form) user = User(form_user, user_dict.get('SCOPES'), user_dict.get('ADMIN')) @@ -1245,8 +1256,8 @@ def get_available_scopes(): def save_user(form): username = form.username.data - pwd_hash = form.pwd_hash.data - pwd_hash_confirm = form.pwd_hash_confirm.data + pwd_hash = hash_password(form.pwd.data) + pwd_hash_confirm = hash_password(form.pwd_confirm.data) if not pwd_hash == pwd_hash_confirm: flash(_('Passwords do not match'), category='error') return redirect(url_for('users')) -- cgit v1.2.3-18-g5258