forked from s3lph/matemat
Basic user bootstrapping, still needs documentation & testing.
This commit is contained in:
parent
d119447572
commit
7f58da298b
5 changed files with 80 additions and 4 deletions
|
@ -62,7 +62,18 @@ class MatematDatabase(object):
|
|||
"""
|
||||
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.
|
||||
|
@ -72,7 +83,10 @@ class MatematDatabase(object):
|
|||
for row in c.execute('''
|
||||
SELECT user_id, username, email, is_admin, is_member, balance
|
||||
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
|
||||
user_id, username, email, is_admin, is_member, balance = row
|
||||
users.append(User(user_id, username, balance, email, is_admin, is_member))
|
||||
|
|
|
@ -13,3 +13,4 @@ from .deposit import deposit
|
|||
from .admin import admin
|
||||
from .moduser import moduser
|
||||
from .modproduct import modproduct
|
||||
from .userbootstrap import userbootstrap
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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
|
||||
|
||||
|
||||
|
@ -30,7 +30,9 @@ def main_page(method: str,
|
|||
authuser=user, products=products, authlevel=authlevel,
|
||||
setupname=config['InstanceName'])
|
||||
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
|
||||
users = db.list_users()
|
||||
users = db.list_users(with_touchkey=True)
|
||||
return TemplateResponse('userlist.html',
|
||||
users=users, setupname=config['InstanceName'])
|
||||
|
|
32
matemat/webserver/pagelets/userbootstrap.py
Normal file
32
matemat/webserver/pagelets/userbootstrap.py
Normal 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'])
|
27
templates/userbootstrap.html
Normal file
27
templates/userbootstrap.html
Normal 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 %}
|
Loading…
Reference in a new issue