Add 'Add user' to Users section

Creates "Add user" form with the following inputs: username, password,
password confirmation, role (administrator or regular), allowed scopes.
multi-ogserver
Javier Sánchez Parra 2022-04-26 17:16:52 +02:00
parent d8bac16a98
commit 661254b76e
5 changed files with 150 additions and 2 deletions

View File

@ -7,7 +7,7 @@
from wtforms import (
Form, SubmitField, HiddenField, SelectField, BooleanField, IntegerField,
StringField, RadioField, PasswordField
StringField, RadioField, PasswordField, SelectMultipleField
)
from wtforms.validators import InputRequired
from flask_wtf import FlaskForm
@ -28,3 +28,32 @@ class LoginForm(FlaskForm):
submit_btn = SubmitField(
label=_l('Login')
)
class UserForm(FlaskForm):
username = StringField(
label=_l('Username'),
validators=[InputRequired()]
)
pwd = PasswordField(
label=_l('Password'),
)
pwd_hash = HiddenField(
validators=[InputRequired()]
)
pwd_confirm = PasswordField(
label=_l('Repeat password'),
)
pwd_hash_confirm = HiddenField(
validators=[InputRequired()]
)
admin = BooleanField(
label=_l('Administrator'),
)
scopes = SelectMultipleField(
label=_l('Allowed scopes'),
description=_l('Leave this empty to give full permissions'),
)
submit_btn = SubmitField(
label=_l('Submit')
)

View File

@ -231,3 +231,25 @@ function digestLoginPassword() {
$(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()
});
}

View File

@ -0,0 +1,26 @@
{% extends 'users.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% set sidebar_state = 'disabled' %}
{% set btn_back = true %}
{% block nav_user_add %}active{% endblock %}
{% block content %}
<h1 class="m-5">{{_('Add a user')}}</h1>
{{ wtf.quick_form(form,
action=url_for('user_add_post'),
method='post',
button_map={'submit_btn':'primary'},
id='user-form') }}
<script>
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
digestUserFormPassword()
}
});
</script>
{% endblock %}

View File

@ -24,6 +24,8 @@
{% endblock %}
{% block commands %}
<input class="btn btn-light {% block nav_user_add %}{% endblock %}" type="submit" value="{{ _('Add user') }}"
form="usersForm" formaction="{{ url_for('user_add_get') }}" formmethod="get">
{% if btn_back %}
<button class="btn btn-danger ml-3" type="button" id="backButton" onclick="history.back()">
{{ _("Back") }}

View File

@ -23,13 +23,15 @@ from flask_login import (
from pathlib import Path
from ogcp.models import User
from ogcp.forms.auth import LoginForm
from ogcp.forms.auth import LoginForm, UserForm
from ogcp.og_server import OGServer
from flask_babel import lazy_gettext as _l
from flask_babel import _
from ogcp import app
import requests
import datetime
import json
import os
import re
FS_CODES = {
@ -1194,6 +1196,73 @@ def users():
return render_template('users.html', users=users)
def get_available_scopes():
resp = g.server.get('/scopes')
centers = parse_scopes_from_tree(resp.json(), 'center')
centers = [(center['name'], center['name']) for center in centers]
rooms = parse_scopes_from_tree(resp.json(), 'room')
rooms = [(room['name'], room['name']) for room in rooms]
return centers + rooms
def save_user(form):
username = form.username.data
pwd_hash = form.pwd_hash.data
pwd_hash_confirm = form.pwd_hash_confirm.data
if not pwd_hash == pwd_hash_confirm:
flash(_('Passwords do not match'), category='error')
return redirect(url_for('users'))
admin = form.admin.data
scopes = form.scopes.data
user = {
'USER': username,
'PASS': pwd_hash,
'ADMIN': admin,
'SCOPES': scopes,
}
filename = os.path.join(app.root_path, 'cfg', 'ogcp.json')
with open(filename, 'r+') as file:
config = json.load(file)
config['USERS'].append(user)
file.seek(0)
json.dump(config, file, indent='\t')
file.truncate()
app.config['USERS'].append(user)
return redirect(url_for('users'))
@app.route('/user/add', methods=['GET'])
@login_required
def user_add_get():
form = UserForm()
form.scopes.choices = get_available_scopes()
return render_template('auth/add_user.html', form=form)
@app.route('/user/add', methods=['POST'])
@login_required
def user_add_post():
form = UserForm(request.form)
form.scopes.choices = get_available_scopes()
if not form.validate():
flash(form.errors, category='error')
return redirect(url_for('users'))
if get_user(form.username.data):
flash(_('This username already exists'), category='error')
return redirect(url_for('users'))
return save_user(form)
@app.route('/action/image/info', methods=['GET'])
@login_required
def action_image_info():