Basic user bootstrapping, still needs documentation & testing.

This commit is contained in:
s3lph 2018-08-14 22:53:39 +02:00
parent d119447572
commit 7f58da298b
5 changed files with 80 additions and 4 deletions

View file

@ -62,7 +62,18 @@ class MatematDatabase(object):
""" """
return self.db.transaction(exclusive=exclusive) return self.db.transaction(exclusive=exclusive)
def list_users(self) -> List[User]: def has_admin_users(self) -> bool:
"""
Check whether the instance has any admin users configured.
:return: True if there are admin users, false otherwise.
"""
with self.db.transaction(exclusive=False) as c:
c.execute('SELECT COUNT(user_id) FROM users WHERE is_admin = 1')
n, = c.fetchone()
return n > 0
def list_users(self, with_touchkey: bool = False) -> List[User]:
""" """
Return a list of users in the database. Return a list of users in the database.
:return: A list of users. :return: A list of users.
@ -72,7 +83,10 @@ class MatematDatabase(object):
for row in c.execute(''' for row in c.execute('''
SELECT user_id, username, email, is_admin, is_member, balance SELECT user_id, username, email, is_admin, is_member, balance
FROM users FROM users
'''): WHERE touchkey IS NOT NULL OR NOT :must_have_touchkey
''', {
'must_have_touchkey': with_touchkey
}):
# Decompose each row and put the values into a User object # Decompose each row and put the values into a User object
user_id, username, email, is_admin, is_member, balance = row user_id, username, email, is_admin, is_member, balance = row
users.append(User(user_id, username, balance, email, is_admin, is_member)) users.append(User(user_id, username, balance, email, is_admin, is_member))

View file

@ -13,3 +13,4 @@ from .deposit import deposit
from .admin import admin from .admin import admin
from .moduser import moduser from .moduser import moduser
from .modproduct import modproduct from .modproduct import modproduct
from .userbootstrap import userbootstrap

View file

@ -1,6 +1,6 @@
from typing import Any, Dict, Union from typing import Any, Dict, Union
from matemat.webserver import pagelet, RequestArguments, PageletResponse, TemplateResponse from matemat.webserver import pagelet, RequestArguments, PageletResponse, TemplateResponse, RedirectResponse
from matemat.db import MatematDatabase from matemat.db import MatematDatabase
@ -30,7 +30,9 @@ def main_page(method: str,
authuser=user, products=products, authlevel=authlevel, authuser=user, products=products, authlevel=authlevel,
setupname=config['InstanceName']) setupname=config['InstanceName'])
else: else:
if not db.has_admin_users():
return RedirectResponse('/userbootstrap')
# If no user is logged in, fetch the list of users and render the userlist template # If no user is logged in, fetch the list of users and render the userlist template
users = db.list_users() users = db.list_users(with_touchkey=True)
return TemplateResponse('userlist.html', return TemplateResponse('userlist.html',
users=users, setupname=config['InstanceName']) users=users, setupname=config['InstanceName'])

View file

@ -0,0 +1,32 @@
from typing import Any, Dict, Union
from matemat.db import MatematDatabase
from matemat.webserver import pagelet, RequestArguments, PageletResponse, RedirectResponse, TemplateResponse
from matemat.exceptions import HttpException
@pagelet('/userbootstrap')
def userbootstrap(method: str,
path: str,
args: RequestArguments,
session_vars: Dict[str, Any],
headers: Dict[str, str],
config: Dict[str, str]) \
-> Union[bytes, str, PageletResponse]:
with MatematDatabase(config['DatabaseFile']) as db:
if db.has_admin_users():
return RedirectResponse('/')
if method == 'POST':
if 'username' not in args or 'password' not in args or 'password2' not in args:
raise HttpException(400, 'Some arguments are missing')
username: str = str(args.username)
password: str = str(args.password)
password2: str = str(args.password2)
if password != password2:
return RedirectResponse('/userbootstrap')
db.create_user(username, password, None, True, False)
return RedirectResponse('/')
else:
return TemplateResponse('userbootstrap.html',
setupname=config['InstanceName'])

View file

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% block header %}
<h1>Setup</h1>
{{ super() }}
{% endblock %}
{% block main %}
{# Show a user creation form #}
Please create an admin user account
<form method="post" action="/userbootstrap" accept-charset="UTF-8">
<label for="username">Username: </label>
<input id="username" type="text" name="username"/><br/>
<label for="password">Password: </label>
<input id="password" type="password" name="password"/><br/>
<label for="password2">Repeat: </label>
<input id="password2" type="password" name="password2"/><br/>
<input type="submit" value="Create user">
</form>
{{ super() }}
{% endblock %}