89 lines
2.3 KiB
Python
89 lines
2.3 KiB
Python
|
#!/usr/bin/env python3
|
||
|
"""
|
||
|
Co-routines for handling various forms in Buckler.
|
||
|
"""
|
||
|
import tools
|
||
|
|
||
|
|
||
|
async def invite_user(request):
|
||
|
"""Allows an admin to invite a new user."""
|
||
|
if not request['session']['admin']:
|
||
|
return {'main': "You do not have permission to do that."}
|
||
|
|
||
|
data = await request.post()
|
||
|
email = data.get('email')
|
||
|
|
||
|
if not email:
|
||
|
return {'invite_user': "This field is required."}
|
||
|
# TODO: validate email address
|
||
|
|
||
|
await tools.send_invite(request, email)
|
||
|
return {}
|
||
|
|
||
|
|
||
|
async def change_password(request):
|
||
|
"""Allows a user to change their password."""
|
||
|
errors = {}
|
||
|
data = await request.post()
|
||
|
current_pw = data.get('current_password')
|
||
|
new_pw = data.get('new_password')
|
||
|
verify_pw = data.get('verify_password')
|
||
|
|
||
|
if not all((current_pw, new_pw, verify_pw)):
|
||
|
errors['change_password'] = "All fields are required."
|
||
|
return errors
|
||
|
if not new_pw == verify_pw:
|
||
|
errors['change_password'] = "Passwords do not match."
|
||
|
return errors
|
||
|
|
||
|
async with request.app['pool'].acquire() as conn:
|
||
|
pw_hash = conn.fetchrow(
|
||
|
"SELECT password_hash FROM user_info WHERE id = $1",
|
||
|
request['session']['id'])
|
||
|
if not argon2.verify(current_pw, pw_hash['password_hash']):
|
||
|
errors['change_password'] = "Invalid password."
|
||
|
return errors
|
||
|
h = argon2.hash(new_pw)
|
||
|
conn.execute(
|
||
|
"UPDATE user_info SET password_hash = $1 WHERE id = $2",
|
||
|
h, request['session']['id'])
|
||
|
return errors
|
||
|
|
||
|
|
||
|
async def delete_key(request):
|
||
|
"""Allows a user to delete a security key."""
|
||
|
data = await request.post()
|
||
|
async with request.app['pool'].acquire() as conn:
|
||
|
for key, value in data.items():
|
||
|
key_id = key.replace('fido-', '')
|
||
|
if not key_id:
|
||
|
continue
|
||
|
try:
|
||
|
key_id = int(key_id)
|
||
|
except ValueError:
|
||
|
continue
|
||
|
if value != 'on':
|
||
|
continue
|
||
|
await conn.execute(
|
||
|
"DELETE FROM user_credential "
|
||
|
"WHERE id = $1 AND user_id = $2",
|
||
|
key_id, request['session']['id'])
|
||
|
return {}
|
||
|
|
||
|
|
||
|
async def delete_session(request):
|
||
|
"""Allows a user to delete a session ."""
|
||
|
data = await request.post()
|
||
|
async with request.app['pool'].acquire() as conn:
|
||
|
for key, value in data.items():
|
||
|
session_id = key.replace('session-', '', 1)
|
||
|
if not session_id:
|
||
|
continue
|
||
|
if value != 'on':
|
||
|
continue
|
||
|
await conn.execute(
|
||
|
"DELETE FROM user_session "
|
||
|
"WHERE id = $1 AND user_id = $2",
|
||
|
session_id, request['session']['id'])
|
||
|
return {}
|