hardening server
This commit is contained in:
parent
86b766e0b5
commit
e1d31cc291
@ -6,12 +6,14 @@ from user_manager import UserManager
|
|||||||
from match_manager import MatchManager
|
from match_manager import MatchManager
|
||||||
from match import Match
|
from match import Match
|
||||||
|
|
||||||
|
from tools import debug
|
||||||
|
|
||||||
|
|
||||||
def parse_message(msg: str):
|
def parse_message(msg: str):
|
||||||
# TODO: make it more robust by validating each part of a message
|
# TODO: make it more robust by validating each part of a message
|
||||||
msg_obj = json.loads(msg)
|
msg_obj = json.loads(msg)
|
||||||
if "type" not in msg_obj or "data" not in msg_obj:
|
if "type" not in msg_obj or "data" not in msg_obj:
|
||||||
print("got strange message")
|
debug("got strange message")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return msg_obj
|
return msg_obj
|
||||||
@ -33,7 +35,7 @@ class Connection(object):
|
|||||||
try:
|
try:
|
||||||
await self.websocket.send(msg)
|
await self.websocket.send(msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("error sending message to user " +
|
debug("error sending message to user " +
|
||||||
self.user_name + ". Reason: " + str(e))
|
self.user_name + ". Reason: " + str(e))
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
@ -44,7 +46,7 @@ class Connection(object):
|
|||||||
self.is_closed = True
|
self.is_closed = True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("error closing session to user " +
|
debug("error closing session to user " +
|
||||||
self.user_name + ". Reason: " + str(e))
|
self.user_name + ". Reason: " + str(e))
|
||||||
|
|
||||||
|
|
||||||
@ -114,7 +116,7 @@ class ConnectionHandler(object):
|
|||||||
socket: websockets.WebSocketServerProtocol,
|
socket: websockets.WebSocketServerProtocol,
|
||||||
login_msg: str):
|
login_msg: str):
|
||||||
msg = parse_message(login_msg)
|
msg = parse_message(login_msg)
|
||||||
print("new incomming connection...")
|
debug("new incomming connection...")
|
||||||
if msg is None:
|
if msg is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -395,7 +397,7 @@ class ConnectionHandler(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("error processing match request: " + str(data) + str(e))
|
debug("error processing match request: " + str(data) + str(e))
|
||||||
|
|
||||||
async def _on_match_state_req(self, conn, data):
|
async def _on_match_state_req(self, conn, data):
|
||||||
db_matches = self.match_manager.get_matches_for_user(conn.user_name)
|
db_matches = self.match_manager.get_matches_for_user(conn.user_name)
|
||||||
@ -432,7 +434,7 @@ class ConnectionHandler(object):
|
|||||||
if match is not None:
|
if match is not None:
|
||||||
match_state = match.to_json_state()
|
match_state = match.to_json_state()
|
||||||
|
|
||||||
print(match_state)
|
debug(match_state)
|
||||||
|
|
||||||
await conn.send(json.dumps({
|
await conn.send(json.dumps({
|
||||||
'type': 'match_update',
|
'type': 'match_update',
|
||||||
@ -580,7 +582,7 @@ class ConnectionHandler(object):
|
|||||||
async def handle_message(self, conn, msg_str):
|
async def handle_message(self, conn, msg_str):
|
||||||
msg = parse_message(msg_str)
|
msg = parse_message(msg_str)
|
||||||
|
|
||||||
print("incoming message" + str(msg))
|
debug("incoming message" + str(msg))
|
||||||
|
|
||||||
if msg is None:
|
if msg is None:
|
||||||
return None
|
return None
|
||||||
@ -607,4 +609,4 @@ class ConnectionHandler(object):
|
|||||||
await self._on_unfriend_request(conn, msg['data'])
|
await self._on_unfriend_request(conn, msg['data'])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("could not interpret message: " + msg_str)
|
debug("could not interpret message: " + msg_str)
|
||||||
|
@ -36,23 +36,30 @@ class DatabaseConnection(object):
|
|||||||
DatabaseConnection.instance.commit()
|
DatabaseConnection.instance.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def global_single_query(query):
|
def global_single_query(query, params=None):
|
||||||
if ';' in query:
|
if ';' in query:
|
||||||
# Possible injection!
|
# Possible injection!
|
||||||
raise SQLInjectionError()
|
raise SQLInjectionError()
|
||||||
|
|
||||||
with DatabaseConnection.global_cursor() as c:
|
with DatabaseConnection.global_cursor() as c:
|
||||||
|
if params is None:
|
||||||
c.execute(query)
|
c.execute(query)
|
||||||
|
else:
|
||||||
|
c.execute(query, params)
|
||||||
|
|
||||||
return c.fetchall()
|
return c.fetchall()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def global_single_execution(sql_statement):
|
def global_single_execution(sql_statement, params=None):
|
||||||
if ';' in sql_statement:
|
if ';' in sql_statement:
|
||||||
# Possible injection detected!
|
# Possible injection detected!
|
||||||
raise SQLInjectionError()
|
raise SQLInjectionError()
|
||||||
|
|
||||||
with DatabaseConnection.global_cursor() as c:
|
with DatabaseConnection.global_cursor() as c:
|
||||||
|
if params is None:
|
||||||
c.execute(sql_statement)
|
c.execute(sql_statement)
|
||||||
|
else:
|
||||||
|
c.execute(sql_statement, params)
|
||||||
DatabaseConnection.global_commit()
|
DatabaseConnection.global_commit()
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -84,7 +91,7 @@ class DatabaseConnection(object):
|
|||||||
":" +
|
":" +
|
||||||
str(port) +
|
str(port) +
|
||||||
"\nCheck the configuration in settings.py!\n")
|
"\nCheck the configuration in settings.py!\n")
|
||||||
raise Exception('could not connec to database')
|
raise Exception('could not connect to database')
|
||||||
|
|
||||||
def get_cursor(self):
|
def get_cursor(self):
|
||||||
return self.connection.cursor()
|
return self.connection.cursor()
|
||||||
@ -96,6 +103,7 @@ class DatabaseConnection(object):
|
|||||||
def commit(self):
|
def commit(self):
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
|
|
||||||
|
|
||||||
def test_connection():
|
def test_connection():
|
||||||
import settings
|
import settings
|
||||||
DatabaseConnection(settings.db_host,
|
DatabaseConnection(settings.db_host,
|
||||||
|
17
main.py
17
main.py
@ -12,6 +12,8 @@ from user_manager import UserManager
|
|||||||
from database_connection import DatabaseConnection
|
from database_connection import DatabaseConnection
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from tools import debug
|
||||||
|
|
||||||
um = UserManager()
|
um = UserManager()
|
||||||
sm = SessionManager(datetime.timedelta(hours=12))
|
sm = SessionManager(datetime.timedelta(hours=12))
|
||||||
mm = MatchManager()
|
mm = MatchManager()
|
||||||
@ -29,7 +31,6 @@ DatabaseConnection(db_host,
|
|||||||
async def socket_worker(websocket, path):
|
async def socket_worker(websocket, path):
|
||||||
connection = None
|
connection = None
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raw_msg = await websocket.recv()
|
raw_msg = await websocket.recv()
|
||||||
|
|
||||||
@ -38,20 +39,24 @@ async def socket_worker(websocket, path):
|
|||||||
if connection is None:
|
if connection is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
print("successfull logged in user: " + connection.user_name)
|
debug("successfull logged in user: " + connection.user_name)
|
||||||
|
|
||||||
async for m in websocket:
|
async for m in websocket:
|
||||||
await ch.handle_message(connection, m)
|
await ch.handle_message(connection, m)
|
||||||
|
|
||||||
|
except websockets.ConnectionClosed as e:
|
||||||
|
# nothing suspicious here
|
||||||
|
pass
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# TODO: each disconnect is an exception so far
|
# TODO: each disconnect is an exception so far
|
||||||
if connection is not None:
|
if connection is not None:
|
||||||
print("catched exception in worker for user: " +
|
debug("catched exception in worker for user: " +
|
||||||
connection.user_name + ": " + str(e))
|
connection.user_name + ": " + str(e))
|
||||||
else:
|
else:
|
||||||
print("catched exception in worker for unknown user: " + str(e))
|
debug("catched exception in worker for unknown user: " + str(e))
|
||||||
|
|
||||||
print(traceback.print_exc())
|
debug(traceback.debug_exc())
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
id = None
|
id = None
|
||||||
@ -62,7 +67,7 @@ async def socket_worker(websocket, path):
|
|||||||
|
|
||||||
if connection is None:
|
if connection is None:
|
||||||
id = "unknown_user"
|
id = "unknown_user"
|
||||||
print("close connection to user: " + id)
|
debug("close connection to user: " + id)
|
||||||
|
|
||||||
if cert_file is not None and key_file is not None:
|
if cert_file is not None and key_file is not None:
|
||||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||||
|
6
match.py
6
match.py
@ -3,6 +3,8 @@ import numpy as np
|
|||||||
import json
|
import json
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
from tools import debug
|
||||||
|
|
||||||
# decoder/encoder took from: https://stackoverflow.com/a/19271311
|
# decoder/encoder took from: https://stackoverflow.com/a/19271311
|
||||||
|
|
||||||
|
|
||||||
@ -158,7 +160,7 @@ class Match(object):
|
|||||||
player_mark = FIELD_USER_A if self.is_player_a else FIELD_USER_B
|
player_mark = FIELD_USER_A if self.is_player_a else FIELD_USER_B
|
||||||
|
|
||||||
if not self.is_move_valid(sub_x, sub_y, x, y):
|
if not self.is_move_valid(sub_x, sub_y, x, y):
|
||||||
print("invalid move")
|
debug("invalid move")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# else: move!
|
# else: move!
|
||||||
@ -169,7 +171,7 @@ class Match(object):
|
|||||||
|
|
||||||
# check whether this indicates changes in the global field:
|
# check whether this indicates changes in the global field:
|
||||||
if self.global_field[sub_y, sub_x] != FIELD_EMPTY:
|
if self.global_field[sub_y, sub_x] != FIELD_EMPTY:
|
||||||
print("field not empty")
|
debug("field not empty")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
subgrid = self.complete_field[sub_y * self.n: (
|
subgrid = self.complete_field[sub_y * self.n: (
|
||||||
|
@ -5,14 +5,16 @@ import uuid
|
|||||||
import settings
|
import settings
|
||||||
from match import Match
|
from match import Match
|
||||||
|
|
||||||
|
from tools import debug
|
||||||
|
|
||||||
|
|
||||||
class MatchManager(object):
|
class MatchManager(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_match(self, id):
|
def get_match(self, id):
|
||||||
query = f"SELECT * FROM matches WHERE id='{id}'"
|
query = "SELECT * FROM matches WHERE id=%s"
|
||||||
result = DatabaseConnection.global_single_query(query)
|
result = DatabaseConnection.global_single_query(query, (id))
|
||||||
if len(result) == 0:
|
if len(result) == 0:
|
||||||
return None
|
return None
|
||||||
match = Match(n=settings.n, match_id=id, player_a_name=result[0]['user_a'],
|
match = Match(n=settings.n, match_id=id, player_a_name=result[0]['user_a'],
|
||||||
@ -20,25 +22,28 @@ class MatchManager(object):
|
|||||||
return match
|
return match
|
||||||
|
|
||||||
def get_matches_for_user(self, user_name):
|
def get_matches_for_user(self, user_name):
|
||||||
query = f"SELECT * FROM matches WHERE user_a='{user_name}' OR user_b='{user_name}'"
|
query = "SELECT * FROM matches WHERE user_a=%s OR user_b=%s"
|
||||||
return DatabaseConnection.global_single_query(query)
|
return DatabaseConnection.global_single_query(query, (user_name, user_name))
|
||||||
|
|
||||||
def create_new_match(self, user_a, user_b):
|
def create_new_match(self, user_a, user_b):
|
||||||
match_id = uuid.uuid4().hex
|
match_id = uuid.uuid4().hex
|
||||||
# check if already existent (but should not be the case)
|
# check if already existent (but should not be the case)
|
||||||
if len(DatabaseConnection.global_single_query(f"SELECT id FROM matches WHERE id='{match_id}'")) > 0:
|
if len(DatabaseConnection.global_single_query("SELECT id FROM matches WHERE id=%s", (match_id))) > 0:
|
||||||
return self.create_new_match(user_a, user_b)
|
return self.create_new_match(user_a, user_b)
|
||||||
|
|
||||||
match = Match(n=settings.n, match_id=match_id, player_a_name=user_a, player_b_name=user_b)
|
match = Match(n=settings.n, match_id=match_id,
|
||||||
|
player_a_name=user_a, player_b_name=user_b)
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
query = f"INSERT INTO matches (id, user_a, user_b, match_state, active_user, last_active) VALUES ('{match_id}', '{user_a}', '{user_b}', '{match.to_json_state()}', '{match.get_current_player()}','{get_sql_time(now)}')"
|
query = "INSERT INTO matches (id, user_a, user_b, match_state, active_user, last_active) VALUES (%s, %s, %s, %s, %s,%s)"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(
|
||||||
|
query, (match_id, user_a, user_b, match.to_json_state(), match.get_current_player(), get_sql_time(now)))
|
||||||
return match
|
return match
|
||||||
|
|
||||||
def update_match(self, match_id, match):
|
def update_match(self, match_id, match):
|
||||||
now = get_sql_time(datetime.datetime.now())
|
now = get_sql_time(datetime.datetime.now())
|
||||||
query = f"UPDATE matches SET match_state='{match.to_json_state()}', active_user='{match.get_current_player()}', last_active='{now}' WHERE id='{match_id}'"
|
query = "UPDATE matches SET match_state=%s, active_user=%s, last_active=%s WHERE id=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(
|
||||||
|
query, (match.to_json_state(), match.get_current_player(), now, match_id))
|
||||||
|
|
||||||
def apply_move(self, move_data):
|
def apply_move(self, move_data):
|
||||||
match = self.get_match(move_data['id'])
|
match = self.get_match(move_data['id'])
|
||||||
@ -46,19 +51,17 @@ class MatchManager(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if not match.move(move_data):
|
if not match.move(move_data):
|
||||||
print("error applying match move")
|
debug("error applying match move")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
self.update_match(move_data['id'], match)
|
self.update_match(move_data['id'], match)
|
||||||
print("updated match")
|
debug("updated match")
|
||||||
return match
|
return match
|
||||||
|
|
||||||
def is_match(self, player_a, player_b):
|
def is_match(self, player_a, player_b):
|
||||||
query = f"SELECT * FROM matches WHERE (user_a='{player_a}' AND user_b='{player_b}') OR (user_a='{player_b}' AND user_b='{player_a}')"
|
query = "SELECT * FROM matches WHERE (user_a=%s AND user_b=%s) OR (user_a=%s AND user_b=%s)"
|
||||||
return len(DatabaseConnection.global_single_query(query))
|
return len(DatabaseConnection.global_single_query(query, (player_a, player_b, player_b, player_a)))
|
||||||
|
|
||||||
def delete_match(self, match_id):
|
def delete_match(self, match_id):
|
||||||
query = f"DELETE FROM matches WHERE id='{match_id}'"
|
query = "DELETE FROM matches WHERE id=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (match_id))
|
||||||
|
|
||||||
|
@ -9,59 +9,60 @@ class SessionManager(object):
|
|||||||
self.session_lifespan_timedelta = session_lifespan_timedelta
|
self.session_lifespan_timedelta = session_lifespan_timedelta
|
||||||
|
|
||||||
def get_session_by_id(self, session_id):
|
def get_session_by_id(self, session_id):
|
||||||
query = f"SELECT * FROM sessions WHERE id='{session_id}'"
|
query = "SELECT * FROM sessions WHERE id=%s"
|
||||||
return DatabaseConnection.global_single_query(query)
|
return DatabaseConnection.global_single_query(query, (session_id))
|
||||||
|
|
||||||
def touch_session(self, session_id):
|
def touch_session(self, session_id):
|
||||||
query = f"UPDATE sessions SET last_seen='{datetime.datetime.now()}' WHERE id='{session_id}'"
|
query = "UPDATE sessions SET last_seen=%s WHERE id=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (datetime.datetime.now(), session_id))
|
||||||
|
|
||||||
def get_session_by_registered_user(self, user_name):
|
def get_session_by_registered_user(self, user_name):
|
||||||
query = f"SELECT * FROM sessions WHERE registered_user='{user_name}'"
|
query = "SELECT * FROM sessions WHERE registered_user=%s"
|
||||||
return DatabaseConnection.global_single_query(query)
|
return DatabaseConnection.global_single_query(query, (user_name))
|
||||||
|
|
||||||
def get_session_by_temp_user(self, user_name):
|
def get_session_by_temp_user(self, user_name):
|
||||||
query = f"SELECT * FROM sessions WHERE temp_user='{user_name}'"
|
query = "SELECT * FROM sessions WHERE temp_user=%s"
|
||||||
return DatabaseConnection.global_single_query(query)
|
return DatabaseConnection.global_single_query(query, (user_name))
|
||||||
|
|
||||||
def create_session_for_registered_user(self, user_name):
|
def create_session_for_registered_user(self, user_name):
|
||||||
new_id = uuid.uuid4().hex
|
new_id = uuid.uuid4().hex
|
||||||
# check if already existent (but should not be the case)
|
# check if already existent (but should not be the case)
|
||||||
if len(DatabaseConnection.global_single_query(f"SELECT id FROM sessions WHERE id='{new_id}'")) > 0:
|
if len(DatabaseConnection.global_single_query("SELECT id FROM sessions WHERE id=%s", (str(new_id)))) > 0:
|
||||||
# okay, next try:
|
# okay, next try:
|
||||||
return self.create_session_for_registered_user(user_name)
|
return self.create_session_for_registered_user(user_name)
|
||||||
|
|
||||||
# delete other active sessions:
|
# delete other active sessions:
|
||||||
query = f"DELETE FROM sessions WHERE registered_user='{user_name}'"
|
query = "DELETE FROM sessions WHERE registered_user=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name))
|
||||||
|
|
||||||
|
query = "INSERT INTO sessions (id, registered_user, temp_user, last_seen) VALUES ( %s, %s, NULL, %s)"
|
||||||
|
DatabaseConnection.global_single_execution(query, (new_id, user_name, datetime.datetime.now()))
|
||||||
|
|
||||||
query = f"INSERT INTO sessions (id, registered_user, temp_user, last_seen) VALUES ( '{new_id}', '{user_name}', NULL, '{datetime.datetime.now()}')"
|
|
||||||
DatabaseConnection.global_single_execution(query)
|
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def create_session_for_temp_user(self, user_name):
|
def create_session_for_temp_user(self, user_name):
|
||||||
new_id = uuid.uuid4().hex
|
new_id = uuid.uuid4().hex
|
||||||
# check if already existent (but should not be the case)
|
# check if already existent (but should not be the case)
|
||||||
if len(DatabaseConnection.global_single_query(f"SELECT id FROM sessions WHERE id='{new_id}'")) > 0:
|
if len(DatabaseConnection.global_single_query("SELECT id FROM sessions WHERE id=%s", (new_id))) > 0:
|
||||||
# okay, next try:
|
# okay, next try:
|
||||||
return self.create_session_for_registered_user(user_name)
|
return self.create_session_for_registered_user(user_name)
|
||||||
|
|
||||||
# delete other active sessions:
|
# delete other active sessions:
|
||||||
query = f"DELETE FROM sessions WHERE temp_user='{user_name}'"
|
query = "DELETE FROM sessions WHERE temp_user=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name))
|
||||||
|
|
||||||
query = f"INSERT INTO sessions (id, registered_user, temp_user, last_seen) VALUES ( '{new_id}', NULL, '{user_name}', '{datetime.datetime.now()}')"
|
query = "INSERT INTO sessions (id, registered_user, temp_user, last_seen) VALUES ( %s, NULL, %s, %s)"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (new_id, user_name, datetime.datetime.now()))
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def delete_session(self, session_id):
|
def delete_session(self, session_id):
|
||||||
query = f"DELETE FROM sessions WHERE id='{session_id}'"
|
query = "DELETE FROM sessions WHERE id=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (session_id))
|
||||||
|
|
||||||
def revoke_inactive_sessions(self):
|
def revoke_inactive_sessions(self):
|
||||||
revoke_time = datetime.datetime.now() - self.session_lifespan_timedelta
|
revoke_time = datetime.datetime.now() - self.session_lifespan_timedelta
|
||||||
query = f"SELECT * from sessions WHERE last_seen < '{get_sql_time(revoke_time)}'"
|
query = "SELECT * from sessions WHERE last_seen < %s"
|
||||||
revoked_sessions = DatabaseConnection.global_single_query(query)
|
revoked_sessions = DatabaseConnection.global_single_query(query, (get_sql_time(revoke_time)))
|
||||||
query = f"DELETE FROM sessions WHERE last_seen < '{get_sql_time(revoke_time)}'"
|
query = "DELETE FROM sessions WHERE last_seen < %s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (get_sql_time(revoke_time)))
|
||||||
return revoked_sessions
|
return revoked_sessions
|
||||||
|
5
tools.py
Normal file
5
tools.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def debug(msg):
|
||||||
|
print("[" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "]: " + msg)
|
@ -10,23 +10,23 @@ class UserManager(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_user(self, user_name):
|
def get_user(self, user_name):
|
||||||
query = f"SELECT name, last_seen FROM users where name='{user_name}'"
|
query = "SELECT name, last_seen FROM users where name=%s"
|
||||||
return DatabaseConnection.global_single_query(query)
|
return DatabaseConnection.global_single_query(query, (user_name))
|
||||||
|
|
||||||
def delete_user(self, user_name):
|
def delete_user(self, user_name):
|
||||||
query = f"DELETE FROM users where name='{user_name}'"
|
query = "DELETE FROM users where name=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name))
|
||||||
|
|
||||||
# remove from friends:
|
# remove from friends:
|
||||||
query = f"DELETE FROM friends WHERE user='{user_name}'"
|
query = "DELETE FROM friends WHERE user=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name))
|
||||||
|
|
||||||
query = f"DELETE FROM friends WHERE friend='{user_name}'"
|
query = "DELETE FROM friends WHERE friend=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name))
|
||||||
|
|
||||||
def verify_user(self, user_name, pw):
|
def verify_user(self, user_name, pw):
|
||||||
query = f"SELECT * FROM users where name='{user_name}'"
|
query = "SELECT * FROM users where name=%s"
|
||||||
users = DatabaseConnection.global_single_query(query)
|
users = DatabaseConnection.global_single_query(query, (user_name))
|
||||||
if len(self.get_user(user_name)) == 0:
|
if len(self.get_user(user_name)) == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -41,33 +41,33 @@ class UserManager(object):
|
|||||||
assert len(self.get_user(user_name)) == 0
|
assert len(self.get_user(user_name)) == 0
|
||||||
pw_salt = uuid.uuid4().hex
|
pw_salt = uuid.uuid4().hex
|
||||||
pw_hash = hashlib.sha512(pw.encode() + pw_salt.encode()).hexdigest()
|
pw_hash = hashlib.sha512(pw.encode() + pw_salt.encode()).hexdigest()
|
||||||
query = f"INSERT INTO users (name, pw_hash, pw_salt, last_seen) VALUES ( '{user_name}', '{pw_hash}', '{pw_salt}', '{datetime.datetime.now()}')"
|
query = "INSERT INTO users (name, pw_hash, pw_salt, last_seen) VALUES ( %s, %s, %s, %s)"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name, pw_hash, pw_salt, datetime.datetime.now()))
|
||||||
|
|
||||||
def touch_user(self, user_name):
|
def touch_user(self, user_name):
|
||||||
matches = self.get_user(user_name)
|
matches = self.get_user(user_name)
|
||||||
assert len(matches) == 1
|
assert len(matches) == 1
|
||||||
query = f"UPDATE users SET last_seen='{datetime.datetime.now()}' WHERE name='{user_name}'"
|
query = "UPDATE users SET last_seen=%s WHERE name=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (datetime.datetime.now(), user_name))
|
||||||
|
|
||||||
def add_friend_to_user(self, user_name, friend_name):
|
def add_friend_to_user(self, user_name, friend_name):
|
||||||
if len(self.get_user(friend_name)) > 0:
|
if len(self.get_user(friend_name)) > 0:
|
||||||
query = f"INSERT INTO friends (user, friend) VALUES ( '{user_name}', '{friend_name}')"
|
query = "INSERT INTO friends (user, friend) VALUES ( %s, %s)"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name, friend_name))
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_friends_for_user(self, user_name):
|
def get_friends_for_user(self, user_name):
|
||||||
query = f"SELECT friend FROM friends WHERE user='{user_name}'"
|
query = "SELECT friend FROM friends WHERE user=%s"
|
||||||
tmp = DatabaseConnection.global_single_query(query)
|
tmp = DatabaseConnection.global_single_query(query, (user_name))
|
||||||
friends = set()
|
friends = set()
|
||||||
for entry in tmp:
|
for entry in tmp:
|
||||||
friends.add(entry['friend'])
|
friends.add(entry['friend'])
|
||||||
return friends
|
return friends
|
||||||
|
|
||||||
def remove_friend_from_user(self, user_name, friend_name):
|
def remove_friend_from_user(self, user_name, friend_name):
|
||||||
query = f"DELETE FROM friends WHERE user='{user_name}' AND friend='{friend_name}'"
|
query = "DELETE FROM friends WHERE user=%s AND friend=%s"
|
||||||
DatabaseConnection.global_single_execution(query)
|
DatabaseConnection.global_single_execution(query, (user_name, friend_name))
|
||||||
|
|
||||||
def get_all_users(self):
|
def get_all_users(self):
|
||||||
query = "SELECT name, last_seen FROM users"
|
query = "SELECT name, last_seen FROM users"
|
||||||
|
Loading…
Reference in New Issue
Block a user