mirror of https://git.48k.eu/ogcp
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
parent
d8bac16a98
commit
661254b76e
|
@ -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')
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 %}
|
|
@ -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") }}
|
||||
|
|
|
@ -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():
|
||||
|
|
Loading…
Reference in New Issue