matemat/matemat/webserver/pagelets/moduser.py
2018-07-22 15:30:59 +02:00

87 lines
3.3 KiB
Python

from typing import Any, Dict, Union
import os
import magic
from matemat.webserver import pagelet, RequestArguments, PageletResponse, RedirectResponse, TemplateResponse
from matemat.db import MatematDatabase
from matemat.db.primitives import User
from matemat.exceptions import DatabaseConsistencyError, HttpException
from matemat.util.currency_format import parse_chf
@pagelet('/moduser')
def moduser(method: str,
path: str,
args: RequestArguments,
session_vars: Dict[str, Any],
headers: Dict[str, str],
config: Dict[str, str]) \
-> Union[str, bytes, PageletResponse]:
if 'authentication_level' not in session_vars or 'authenticated_user' not in session_vars:
return RedirectResponse('/login')
authlevel: int = session_vars['authentication_level']
auth_uid: int = session_vars['authenticated_user']
if authlevel < 2:
raise HttpException(403)
with MatematDatabase(config['DatabaseFile']) as db:
authuser = db.get_user(auth_uid)
if not authuser.is_admin:
raise HttpException(403)
if 'userid' not in args:
raise HttpException(400, '"userid" argument missing')
moduser_id = int(str(args.userid))
user = db.get_user(moduser_id)
if 'change' in args:
handle_change(args, user, db, config)
if str(args.change) == 'del':
return RedirectResponse('/admin')
return TemplateResponse('moduser.html',
authuser=authuser, user=user, authlevel=authlevel,
setupname=config['InstanceName'])
def handle_change(args: RequestArguments, user: User, db: MatematDatabase, config: Dict[str, str]) -> None:
change = str(args.change)
if change == 'del':
db.delete_user(user)
try:
abspath: str = os.path.join(os.path.abspath(config['UploadDir']), 'thumbnails/users/')
os.remove(os.path.join(abspath, f'{user.id}.png'))
except FileNotFoundError:
pass
elif change == 'update':
if 'username' not in args or 'email' not in args or 'password' not in args or 'balance' not in args:
return
username = str(args.username)
email = str(args.email)
password = str(args.password)
balance = parse_chf(str(args.balance))
is_member = 'ismember' in args
is_admin = 'isadmin' in args
if len(email) == 0:
email = None
try:
db.change_user(user, name=username, email=email, is_member=is_member, is_admin=is_admin, balance=balance)
except DatabaseConsistencyError:
pass
if len(password) > 0:
db.change_password(user, '', password, verify_password=False)
if 'avatar' in args:
avatar = bytes(args.avatar)
filemagic: magic.FileMagic = magic.detect_from_content(avatar)
if filemagic.mime_type != 'image/png':
# TODO: Optionally convert to png
return
if len(avatar) > 0:
abspath: str = os.path.join(os.path.abspath(config['UploadDir']), 'thumbnails/users/')
os.makedirs(abspath, exist_ok=True)
with open(os.path.join(abspath, f'{user.id}.png'), 'wb') as f:
f.write(avatar)