Release pool connection handle und all circumstances especially also when a query fails before the call is finished. This should avoid connection starvation. fix prod. link production fix Fixed application path
89 lines
3.9 KiB
Python
89 lines
3.9 KiB
Python
import json
|
|
import logging
|
|
import pydapper
|
|
import bcrypt
|
|
|
|
from ..schemas import model
|
|
from .. import local_db
|
|
from BreCal.database.sql_queries import SQLQuery, create_sql_query_user_put
|
|
|
|
def PutUser(schemaModel):
|
|
"""
|
|
|
|
:param schemaModel: The deserialized dict of the request
|
|
"""
|
|
|
|
# This updates an *existing* entry
|
|
pooledConnection = None
|
|
try:
|
|
pooledConnection = local_db.getPoolConnection()
|
|
commands = pydapper.using(pooledConnection)
|
|
|
|
# test if object to update is found
|
|
|
|
sentinel = object()
|
|
# query = SQLQuery.get_user_by_id()
|
|
# theuser = commands.query_single_or_default(query, sentinel, param={"id" : schemaModel["id"]}, model=model.User)
|
|
theuser = commands.query_single_or_default("SELECT * FROM user where id = ?id?", sentinel, param={"id" : schemaModel["id"]}, model=model.User)
|
|
if theuser is sentinel:
|
|
# #TODO: result = {"message":"no such record"} -> json.dumps
|
|
return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'}
|
|
|
|
# see if we need to update public fields
|
|
# #TODO_determine: this filter blocks Put-Requests, which update the 'notify_email', 'notify_whatsapp', 'notify_signal', 'notify_popup' fields
|
|
# should this be refactored?
|
|
# Also, what about the 'user_name'?
|
|
# 'participant_id' would also not trigger an update in isolation
|
|
if "first_name" in schemaModel or "last_name" in schemaModel or "user_phone" in schemaModel or "user_email" in schemaModel or "notify_email" in schemaModel or "notify_whatsapp" in schemaModel or "notify_signal" in schemaModel or "notify_popup" in schemaModel or "notify_on" in schemaModel:
|
|
# query = SQLQuery.get_user_put(schemaModel)
|
|
query = "UPDATE user SET "
|
|
isNotFirst = False
|
|
for key in schemaModel.keys():
|
|
if key == "id":
|
|
continue
|
|
if key == "old_password":
|
|
continue
|
|
if key == "new_password":
|
|
continue
|
|
if isNotFirst:
|
|
query += ", "
|
|
isNotFirst = True
|
|
|
|
if key != "notify_on":
|
|
query += key + " = ?" + key + "? "
|
|
else:
|
|
flag_value = model.list_to_bitflag(schemaModel["notify_on"])
|
|
query += "notify_event = " + str(flag_value) + " "
|
|
|
|
|
|
|
|
query += "WHERE id = ?id?"
|
|
affected_rows = commands.execute(query, param=schemaModel)
|
|
|
|
# update password if available and old pw is (correctly!) given
|
|
if "old_password" in schemaModel and schemaModel["old_password"] and "new_password" in schemaModel and schemaModel["new_password"]:
|
|
if bcrypt.checkpw(schemaModel["old_password"].encode("utf-8"), bytes(theuser.password_hash, "utf-8")): # old pw matches
|
|
password_hash = bcrypt.hashpw(schemaModel["new_password"].encode('utf-8'), bcrypt.gensalt( 12 )).decode('utf8')
|
|
# query = SQLQuery.get_update_user_password()
|
|
query = "UPDATE user SET password_hash = ?password_hash? WHERE id = ?id?"
|
|
commands.execute(query, param={"password_hash" : password_hash, "id" : schemaModel["id"]})
|
|
else:
|
|
result = {}
|
|
result["error_field"] = "old password invalid"
|
|
return json.dumps(result), 400, {'Content-Type': 'application/json; charset=utf-8'}
|
|
|
|
return json.dumps({"id" : schemaModel["id"]}), 200
|
|
|
|
except Exception as ex:
|
|
logging.error(ex)
|
|
print(ex)
|
|
result = {}
|
|
result["error_field"] = "call failed"
|
|
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
|
|
|
|
finally:
|
|
if pooledConnection is not None:
|
|
pooledConnection.close()
|
|
|
|
|