myems/myems-api/core/user.py

719 lines
29 KiB
Python

import falcon
import simplejson as json
import mysql.connector
import config
import uuid
import hashlib
import re
import os
from datetime import datetime, timedelta
class UserCollection:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_get(req, resp):
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
query = (" SELECT u.id, u.name, u.display_name, u.uuid, "
" u.email, u.is_admin, p.id,p.name "
" FROM tbl_users u "
" LEFT JOIN tbl_privileges p ON u.privilege_id = p.id "
" ORDER BY u.name ")
cursor.execute(query)
rows = cursor.fetchall()
cursor.close()
cnx.disconnect()
result = list()
if rows is not None and len(rows) > 0:
for row in rows:
meta_result = {"id": row[0],
"name": row[1],
"display_name": row[2],
"uuid": row[3],
"email": row[4],
"is_admin": True if row[5] else False,
"privilege": {
"id": row[6],
"name": row[7]} if row[6] is not None else None}
result.append(meta_result)
resp.body = json.dumps(result)
@staticmethod
def on_post(req, resp):
"""Handles POST requests"""
try:
raw_json = req.stream.read().decode('utf-8')
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
new_values = json.loads(raw_json)
if 'name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['name'], str) or \
len(str.strip(new_values['data']['name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_NAME')
name = str.strip(new_values['data']['name'])
if 'display_name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['display_name'], str) or \
len(str.strip(new_values['data']['display_name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_DISPLAY_NAME')
display_name = str.strip(new_values['data']['display_name'])
if 'email' not in new_values['data'].keys() or \
not isinstance(new_values['data']['email'], str) or \
len(str.strip(new_values['data']['email'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
email = str.lower(str.strip(new_values['data']['email']))
match = re.match(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email)
if match is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
if 'is_admin' not in new_values['data'].keys() or \
not isinstance(new_values['data']['is_admin'], bool):
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_IS_ADMIN_VALUE')
is_admin = new_values['data']['is_admin']
if 'privilege_id' in new_values['data'].keys():
if not isinstance(new_values['data']['privilege_id'], int) or \
new_values['data']['privilege_id'] <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_PRIVILEGE_ID')
privilege_id = new_values['data']['privilege_id']
else:
privilege_id = None
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE name = %s ", (name,))
if cursor.fetchone() is not None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
description='API.USER_NAME_IS_ALREADY_IN_USE')
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE email = %s ", (email,))
if cursor.fetchone() is not None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
description='API.EMAIL_IS_ALREADY_IN_USE')
if privilege_id is not None:
cursor.execute(" SELECT name "
" FROM tbl_privileges "
" WHERE id = %s ",
(privilege_id,))
if cursor.fetchone() is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.PRIVILEGE_NOT_FOUND')
add_row = (" INSERT INTO tbl_users "
" (name, uuid, display_name, email, salt, password, is_admin, privilege_id) "
" VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
salt = uuid.uuid4().hex
password = new_values['data']['password']
hashed_password = hashlib.sha512(salt.encode() + password.encode()).hexdigest()
cursor.execute(add_row, (name,
str(uuid.uuid4()),
display_name,
email,
salt,
hashed_password,
is_admin,
privilege_id))
new_id = cursor.lastrowid
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_201
resp.location = '/users/' + str(new_id)
class UserItem:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp, id_):
resp.status = falcon.HTTP_200
@staticmethod
def on_get(req, resp, id_):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_ID')
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
query = (" SELECT id, name, display_name, uuid, email "
" FROM tbl_users "
" WHERE id =%s ")
cursor.execute(query, (id_,))
row = cursor.fetchone()
cursor.close()
cnx.disconnect()
if row is None:
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_NOT_FOUND')
result = {"id": row[0],
"name": row[1],
"display_name": row[2],
"uuid": row[3],
"email": row[4]}
resp.body = json.dumps(result)
@staticmethod
def on_delete(req, resp, id_):
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_ID')
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE id = %s ", (id_,))
if cursor.fetchone() is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_NOT_FOUND')
# TODO: delete associated objects
cursor.execute(" DELETE FROM tbl_users WHERE id = %s ", (id_,))
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_204
@staticmethod
def on_put(req, resp, id_):
"""Handles PUT requests"""
try:
raw_json = req.stream.read().decode('utf-8')
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
if not id_.isdigit() or int(id_) <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_ID')
new_values = json.loads(raw_json)
if 'name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['name'], str) or \
len(str.strip(new_values['data']['name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_NAME')
name = str.strip(new_values['data']['name'])
if 'display_name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['display_name'], str) or \
len(str.strip(new_values['data']['display_name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_DISPLAY_NAME')
display_name = str.strip(new_values['data']['display_name'])
if 'email' not in new_values['data'].keys() or \
not isinstance(new_values['data']['email'], str) or \
len(str.strip(new_values['data']['email'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
email = str.lower(str.strip(new_values['data']['email']))
match = re.match(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email)
if match is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
if 'is_admin' not in new_values['data'].keys() or \
not isinstance(new_values['data']['is_admin'], bool):
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_IS_ADMIN_VALUE')
is_admin = new_values['data']['is_admin']
if 'privilege_id' in new_values['data'].keys():
if not isinstance(new_values['data']['privilege_id'], int) or \
new_values['data']['privilege_id'] <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_PRIVILEGE_ID')
privilege_id = new_values['data']['privilege_id']
else:
privilege_id = None
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE id = %s ", (id_,))
if cursor.fetchone() is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_NOT_FOUND')
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE name = %s AND id != %s ", (name, id_))
if cursor.fetchone() is not None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
description='API.USER_NAME_IS_ALREADY_IN_USE')
cursor.execute(" SELECT name "
" FROM tbl_users "
" WHERE email = %s AND id != %s ", (email, id_))
if cursor.fetchone() is not None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
description='API.EMAIL_IS_ALREADY_IN_USE')
if privilege_id is not None:
cursor.execute(" SELECT name "
" FROM tbl_privileges "
" WHERE id = %s ",
(privilege_id,))
if cursor.fetchone() is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.PRIVILEGE_NOT_FOUND')
update_row = (" UPDATE tbl_users "
" SET name = %s, display_name = %s, email = %s, "
" is_admin = %s, privilege_id = %s "
" WHERE id = %s ")
cursor.execute(update_row, (name,
display_name,
email,
is_admin,
privilege_id,
id_,))
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_200
class UserLogin:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_put(req, resp):
"""Handles PUT requests"""
try:
raw_json = req.stream.read().decode('utf-8')
new_values = json.loads(raw_json)
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
if not isinstance(new_values['data']['password'], str) or \
len(str.strip(new_values['data']['password'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_PASSWORD')
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
result = dict()
if 'name' in new_values['data']:
if not isinstance(new_values['data']['name'], str) or \
len(str.strip(new_values['data']['name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_NAME')
query = (" SELECT id, name, uuid, display_name, email, salt, password, is_admin "
" FROM tbl_users "
" WHERE name = %s ")
cursor.execute(query, (str.strip(new_values['data']['name']).lower(),))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, 'API.ERROR', 'API.USER_NOT_FOUND')
result = {"id": row[0],
"name": row[1],
"uuid": row[2],
"display_name": row[3],
"email": row[4],
"salt": row[5],
"password": row[6],
"is_admin": True if row[7] else False}
elif 'email' in new_values['data']:
if not isinstance(new_values['data']['email'], str) or \
len(str.strip(new_values['data']['email'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
query = (" SELECT id, name, uuid, display_name, email, salt, password, is_admin "
" FROM tbl_users "
" WHERE email = %s ")
cursor.execute(query, (str.strip(new_values['data']['email']).lower(),))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, 'API.ERROR', 'API.USER_NOT_FOUND')
result = {"id": row[0],
"name": row[1],
"uuid": row[2],
"display_name": row[3],
"email": row[4],
"salt": row[5],
"password": row[6],
"is_admin": True if row[7] else False}
else:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_NAME_OR_EMAIL')
salt = result['salt']
password = str.strip(new_values['data']['password'])
hashed_password = hashlib.sha512(salt.encode() + password.encode()).hexdigest()
if hashed_password != result['password']:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, 'API.BAD_REQUEST', 'API.INVALID_PASSWORD')
add_session = (" INSERT INTO tbl_sessions "
" (user_uuid, token, utc_expires) "
" VALUES (%s, %s, %s) ")
user_uuid = result['uuid']
token = hashlib.sha512(os.urandom(24)).hexdigest()
utc_expires = datetime.utcnow() + timedelta(seconds=60 * 60 * 8)
cursor.execute(add_session, (user_uuid, token, utc_expires))
cnx.commit()
cursor.close()
cnx.disconnect()
resp.set_cookie('user_uuid', user_uuid,
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.set_cookie('token', token,
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
del result['salt']
del result['password']
result['token'] = token
resp.body = json.dumps(result)
resp.status = falcon.HTTP_200
class UserLogout:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_put(req, resp):
"""Handles PUT requests"""
if 'USER-UUID' not in req.headers or \
not isinstance(req.headers['USER-UUID'], str) or \
len(str.strip(req.headers['USER-UUID'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_UUID')
user_uuid = str.strip(req.headers['USER-UUID'])
if 'TOKEN' not in req.headers or \
not isinstance(req.headers['TOKEN'], str) or \
len(str.strip(req.headers['TOKEN'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_TOKEN')
token = str.strip(req.headers['TOKEN'])
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
query = (" DELETE FROM tbl_sessions "
" WHERE user_uuid = %s AND token = %s ")
cursor.execute(query, (user_uuid, token,))
rowcount = cursor.rowcount
cnx.commit()
cursor.close()
cnx.disconnect()
if rowcount is None or rowcount == 0:
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_SESSION_NOT_FOUND')
resp.set_cookie('user_uuid', '',
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.set_cookie('token', '',
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.body = json.dumps("OK")
resp.status = falcon.HTTP_200
class ChangePassword:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_put(req, resp):
"""Handles PUT requests"""
if 'USER-UUID' not in req.headers or \
not isinstance(req.headers['USER-UUID'], str) or \
len(str.strip(req.headers['USER-UUID'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_UUID')
user_uuid = str.strip(req.headers['USER-UUID'])
if 'TOKEN' not in req.headers or \
not isinstance(req.headers['TOKEN'], str) or \
len(str.strip(req.headers['TOKEN'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_TOKEN')
token = str.strip(req.headers['TOKEN'])
try:
raw_json = req.stream.read().decode('utf-8')
new_values = json.loads(raw_json)
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, 'API.ERROR', ex.args)
if 'old_password' not in new_values['data'] or \
not isinstance(new_values['data']['old_password'], str) or \
len(str.strip(new_values['data']['old_password'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_OLD_PASSWORD')
old_password = str.strip(new_values['data']['old_password'])
if 'new_password' not in new_values['data'] or \
not isinstance(new_values['data']['new_password'], str) or \
len(str.strip(new_values['data']['new_password'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_NEW_PASSWORD')
new_password = str.strip(new_values['data']['new_password'])
# Verify User Session
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
query = (" SELECT utc_expires "
" FROM tbl_sessions "
" WHERE user_uuid = %s AND token = %s")
cursor.execute(query, (user_uuid, token,))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_SESSION_NOT_FOUND')
else:
utc_expires = row[0]
if datetime.utcnow() > utc_expires:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.USER_SESSION_TIMEOUT')
query = (" SELECT salt, password "
" FROM tbl_users "
" WHERE uuid = %s ")
cursor.execute(query, (user_uuid,))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, 'API.NOT_FOUND', 'API.USER_NOT_FOUND')
result = {'salt': row[0], 'password': row[1]}
# verify old password
salt = result['salt']
hashed_password = hashlib.sha512(salt.encode() + old_password.encode()).hexdigest()
if hashed_password != result['password']:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, 'API.BAD_REQUEST', 'API.INVALID_OLD_PASSWORD')
# Update User password
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(salt.encode() + new_password.encode()).hexdigest()
update_user = (" UPDATE tbl_users "
" SET salt = %s, password = %s "
" WHERE uuid = %s ")
cursor.execute(update_user, (salt, hashed_password, user_uuid,))
cnx.commit()
# Refresh User session
update_session = (" UPDATE tbl_sessions "
" SET utc_expires = %s "
" WHERE user_uuid = %s AND token = %s ")
utc_expires = datetime.utcnow() + timedelta(seconds=1000 * 60 * 60 * 8)
cursor.execute(update_session, (utc_expires, user_uuid, token, ))
cnx.commit()
cursor.close()
cnx.disconnect()
resp.body = json.dumps("OK")
resp.status = falcon.HTTP_200
class ResetPassword:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
@staticmethod
def on_put(req, resp):
"""Handles PUT requests"""
if 'USER-UUID' not in req.headers or \
not isinstance(req.headers['USER-UUID'], str) or \
len(str.strip(req.headers['USER-UUID'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_UUID')
admin_user_uuid = str.strip(req.headers['USER-UUID'])
if 'TOKEN' not in req.headers or \
not isinstance(req.headers['TOKEN'], str) or \
len(str.strip(req.headers['TOKEN'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_TOKEN')
admin_token = str.strip(req.headers['TOKEN'])
try:
raw_json = req.stream.read().decode('utf-8')
new_values = json.loads(raw_json)
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, 'API.ERROR', ex.args)
if 'name' not in new_values['data'] or \
not isinstance(new_values['data']['name'], str) or \
len(str.strip(new_values['data']['name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_USER_NAME')
user_name = str.strip(new_values['data']['name'])
if 'password' not in new_values['data'] or \
not isinstance(new_values['data']['password'], str) or \
len(str.strip(new_values['data']['password'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_PASSWORD')
new_password = str.strip(new_values['data']['password'])
# Verify Administrator
cnx = mysql.connector.connect(**config.myems_user_db)
cursor = cnx.cursor()
query = (" SELECT utc_expires "
" FROM tbl_sessions "
" WHERE user_uuid = %s AND token = %s")
cursor.execute(query, (admin_user_uuid, admin_token,))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.ADMINISTRATOR_SESSION_NOT_FOUND')
else:
utc_expires = row[0]
if datetime.utcnow() > utc_expires:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.ADMINISTRATOR_SESSION_TIMEOUT')
query = (" SELECT name "
" FROM tbl_users "
" WHERE uuid = %s AND is_admin = true ")
cursor.execute(query, (admin_user_uuid,))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_400, 'API.BAD_REQUEST', 'API.INVALID_PRIVILEGE')
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(salt.encode() + new_password.encode()).hexdigest()
update_user = (" UPDATE tbl_users "
" SET salt = %s, password = %s "
" WHERE name = %s ")
cursor.execute(update_user, (salt, hashed_password, user_name,))
cnx.commit()
# Refresh administrator session
update_session = (" UPDATE tbl_sessions "
" SET utc_expires = %s "
" WHERE user_uuid = %s and token = %s ")
utc_expires = datetime.utcnow() + timedelta(seconds=1000 * 60 * 60 * 8)
cursor.execute(update_session, (utc_expires, admin_user_uuid, admin_token, ))
cnx.commit()
cursor.close()
cnx.disconnect()
resp.body = json.dumps("OK")
resp.status = falcon.HTTP_200