From bdbaa995978e400649bf5806974da8509262c85e Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 29 Aug 2024 21:44:20 +0200 Subject: [PATCH] prevent two different socket for same user and remove ws from server folder --- .../typeRequests/getPrivateListMessage.py | 3 +- .../file/server/server/typeRequests/login.py | 4 +- .../server/typeRequests/sendPrivateMessage.py | 8 +- .../file/server/server/websocket.py | 35 ++--- .../file/server/server/ws/Class/User.py | 120 ------------------ .../file/server/server/ws/main.py | 65 ---------- .../server/ws/typeRequets/createAccount.py | 75 ----------- .../ws/typeRequets/getPrivateListMessage.py | 69 ---------- .../ws/typeRequets/getPrivateListUser.py | 61 --------- .../server/server/ws/typeRequets/login.py | 110 ---------------- .../server/ws/typeRequets/login42/login42.py | 72 ----------- .../ws/typeRequets/sendPrivateMessage.py | 35 ----- listError.txt | 1 + 13 files changed, 28 insertions(+), 630 deletions(-) delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/Class/User.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/main.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/createAccount.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/getPrivateListMessage.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/getPrivateListUser.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login42/login42.py delete mode 100644 docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/sendPrivateMessage.py diff --git a/docker-compose/requirements/djangoserver/file/server/server/typeRequests/getPrivateListMessage.py b/docker-compose/requirements/djangoserver/file/server/server/typeRequests/getPrivateListMessage.py index a5999bf..bfec47b 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/typeRequests/getPrivateListMessage.py +++ b/docker-compose/requirements/djangoserver/file/server/server/typeRequests/getPrivateListMessage.py @@ -6,7 +6,7 @@ # By: edbernar 100): + Message.objects.order_by('date').first().delete() + jsonVar = {"type": "new_private_message", "content": { "from": new_msg.sender.id, "channel": content["to"], @@ -38,7 +42,7 @@ def sendPrivateMessage(socket, content): "date": new_msg.date.strftime("%H:%M:%S %d/%m/%Y") }} if(content["to"] in socket.onlinePlayers): - socket.send_to_all(content["to"], json.dumps(jsonVar)) + socket.onlinePlayers[content["to"]].send(text_data=json.dumps(jsonVar)) socket.send(text_data=json.dumps(jsonVar)) except Exception as e: socket.sendError("Invalid message sent", 9009, e) diff --git a/docker-compose/requirements/djangoserver/file/server/server/websocket.py b/docker-compose/requirements/djangoserver/file/server/server/websocket.py index 0d0fbaf..9319846 100644 --- a/docker-compose/requirements/djangoserver/file/server/server/websocket.py +++ b/docker-compose/requirements/djangoserver/file/server/server/websocket.py @@ -21,51 +21,54 @@ from random import randint class WebsocketHandler(WebsocketConsumer): debugMode = True - # format : {id : [socket,...], ...} + # format : {id : socket, ...} onlinePlayers = {} - def send_to_all(self, uid, text_data): - print("\033[32msending", text_data, " to all socket of", uid) - for x in self.onlinePlayers[uid]: - x.send(text_data=text_data) - def add_to_online(self, uid): if(not uid): return if(uid not in self.onlinePlayers): - self.onlinePlayers[uid] = [self] - else: - self.onlinePlayers[uid].append(self) - print("online : ", self.onlinePlayers) + self.onlinePlayers[uid] = self + return(1) + print("\033[32monline : ", self.onlinePlayers) + return(0) def login(self, uid: int, username: str) -> int: if(self.scope["session"].get("logged_in", False)): return(0) + if(not self.add_to_online(uid)): + socket.sendError("Already logged in", 9012) + return(0) self.scope["session"]["logged_in"] = True self.scope["session"]["id"] = uid self.scope["session"]["username"] = username self.scope["session"].save() - self.add_to_online(uid) + self.logged_in = True return(1) def connect(self): + self.logged_in = False self.accept() + if(self.scope["session"].get("logged_in", False)): + if(not self.add_to_online(self.scope["session"].get("id", 0))): + self.sendError("User already connected", 9013) + self.close() + return; self.send(text_data=json.dumps({"type":"logged_in", "content":{ "status":self.scope["session"].get("logged_in",False), "username":self.scope["session"].get("username",None), "id":self.scope["session"].get("id",0) }})) - if(self.scope["session"].get("logged_in", False)): - self.add_to_online(self.scope["session"].get("id", 0)) + self.logged_in = self.scope["session"].get("logged_in", False) print("new client") def disconnect(self, close_code): print("you can go, i am not mad, we never wanted you anyway") + if(not self.logged_in): + return ; uid = self.scope["session"].get("id", 0) if(uid in self.onlinePlayers): - self.onlinePlayers[uid].remove(self) - if(not len(self.onlinePlayers[uid])): - del self.onlinePlayers[uid] + del self.onlinePlayers[uid] def receive(self, text_data): print("someone is talking") diff --git a/docker-compose/requirements/djangoserver/file/server/server/ws/Class/User.py b/docker-compose/requirements/djangoserver/file/server/server/ws/Class/User.py deleted file mode 100644 index 7a98576..0000000 --- a/docker-compose/requirements/djangoserver/file/server/server/ws/Class/User.py +++ /dev/null @@ -1,120 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# User.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: edbernar +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2024/08/03 08:10:40 by edbernar #+# #+# # -# Updated: 2024/08/22 15:54:03 by tomoron ### ########.fr # -# # -# **************************************************************************** # - -from typeRequets.getPrivateListMessage import getPrivateListMessage -from typeRequets.getPrivateListUser import getPrivateListUser -from typeRequets.sendPrivateMessage import sendPrivateMessage -from typeRequets.createAccount import createAccount -from typeRequets.login import login -from Class.User import User, connected_clients -import websockets -import asyncio -import json - -# Todo (Eddy): -# - verifier que l'utilisateur n'est pas déjà connecté pour éviter les doublons -# Todo (Tom) : -# - Mettre des pages temporaires accesibles qu'on envoie par mail pour confirmer le compte - -typeRequest = ["login", "get_private_list_user", "get_private_list_message", - "send_private_message", "create_account"] -functionRequest = [login, getPrivateListUser, getPrivateListMessage, - sendPrivateMessage, createAccount] - -async def handler(websocket, path): - userClass = User(websocket) - try: - async for resquet in userClass.websocket: - try: - jsonRequest = json.loads(resquet) - except json.JSONDecodeError: - await userClass.sendError("Invalid JSON", 9002) - continue - try: - userClass.printDebug(jsonRequest, 0) - if (jsonRequest["type"] in typeRequest): - if (jsonRequest["type"] == "login" or jsonRequest["type"] == "create_account"): - await functionRequest[typeRequest.index(jsonRequest["type"])](userClass, jsonRequest["content"]) - else: - if (await userClass.verifyToken(jsonRequest["token"]) == False): - continue - await functionRequest[typeRequest.index(jsonRequest["type"])](userClass, jsonRequest["content"]) - else: - await userClass.sendError("Invalid type", 9004) - except Exception as e: - await userClass.sendError("Invalid request", 9005, e) - except websockets.ConnectionClosed: - pass - await userClass.close() - connected_clients.remove(userClass) - - -start_server = websockets.serve(handler, "localhost", 8000, subprotocols=['123456']) - -asyncio.get_event_loop().run_until_complete(start_server) -print("Server started") -asyncio.get_event_loop().run_forever() diff --git a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/createAccount.py b/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/createAccount.py deleted file mode 100644 index 1e328b0..0000000 --- a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/createAccount.py +++ /dev/null @@ -1,75 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# createAccount.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: edbernar 20): - await userClass.sendError("Username must be at most 20 characters long", 9009) - return - if (content["username"].find(' ') != -1): - await userClass.sendError("Username must not contain spaces", 9011) - return - if (content["username"].isalnum() == False): - await userClass.sendError("Username must contain only letters and numbers", 9012) - return - if (len(content["password"]) < 8): - await userClass.sendError("Password must be at least 8 characters long", 9013) - return - if (bool(re.match(pattern, content["password"]))): - await userClass.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9014) - return - if (content["password"].find(content["username"]) != -1): - await userClass.sendError("Password must not contain the username", 9015) - return - # |Tom| Au lieu d'utiliser userList, faire une requête à la base de donnée pour savoir si on a un utilisateur avec cet email ou cet username - if (content["mail"] in userList): - await userClass.sendError("Mail already used", 9016) - return - if (content["username"] in userList): - await userClass.sendError("Username already used", 9017) - return - content["token"] = generateToken() - while (True): - content["id"] = random.randint(1000000, 9999999) - if (content["id"] not in userList): - break - userList.append(content) - await userClass.send({"type": "create_account", "content": "Account created"}) - except Exception as e: - await userClass.sendError("Error create account", 9005, e) - -def generateToken(): - list = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - token = "" - - for i in range(0, 35): - token += list[random.randint(0, len(list) - 1)] - return token \ No newline at end of file diff --git a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/getPrivateListMessage.py b/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/getPrivateListMessage.py deleted file mode 100644 index 90ffbcc..0000000 --- a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/getPrivateListMessage.py +++ /dev/null @@ -1,69 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# getPrivateListMessage.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: edbernar +#+ +:+ +#+ # -# +#+#+#+#+#+ +#+ # -# Created: 2024/08/03 15:10:23 by edbernar #+# #+# # -# Updated: 2024/08/05 16:36:53 by edbernar ### ########.fr # -# # -# **************************************************************************** # - -import websockets -import asyncio -import json - -data = [ - { - "name": "Nessundorma", - "status": "online", - "pfp": "https://wallpapers-clan.com/wp-content/uploads/2023/05/cool-pfp-02.jpg", - "id": 145564 - }, - { - "name": "Succotash", - "status": "offline", - "pfp": "https://i.pinimg.com/200x/28/75/96/287596f98304bf1adc2c411619ae8fef.jpg", - "id": 256981 - }, - { - "name": "Astropower", - "status": "online", - "pfp": "https://ashisheditz.com/wp-content/uploads/2024/03/cool-anime-pfp-demon-slayer-HD.jpg", - "id": 301547 - }, - { - "name": "Assaultive", - "status": "offline", - "pfp": "https://i1.sndcdn.com/artworks-1Li0JIJrQGlojD3y-AEiNkw-t500x500.jpg", - "id": 432448 - }, - { - "name": "Redshock", - "status": "offline", - "pfp": "https://cdn.pfps.gg/pfps/7094-boy-pfp.png", - "id": 543211 - }, - { - "name": "Parley", - "status": "offline", - "pfp": "https://pbs.twimg.com/media/EscE6ckU0AA-Uhe.png", - "id": 654123 - } -] - -async def getPrivateListUser(userClass, content=None): - # |TOM| Faire une requête à la base de données pour récupérer la liste des - # utilisateurs qui doivent apparaitre dans la liste du chat privé - # (ceux qui ont eu conversation avec l'utilisateur) - # Si user existe pas, faire ça : await userClass.sendError("User not found", 9008) - await userClass.send({"type": "private_list_user", "content": data}) \ No newline at end of file diff --git a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login.py b/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login.py deleted file mode 100644 index 8e68af4..0000000 --- a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login.py +++ /dev/null @@ -1,110 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# login.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: edbernar {"type" : "login", "content" : {"username": "". "token": "", "id": 0}} - -userList = [ - { - "username": "Eddy", - "token": "54dsadw8f4a6w5f4a62s4f984fa62f4as65", - "mail": "aaaaa", - "password": "ed968e840d10d2d313a870bc131a4e2c311d7ad09bdf32b3418147221f51a6e2", # not hashed : aaaaa - "id": 2135421, - "id42": -1 - }, - { - "username": "Hugo", - "token": "dsa4d6sa4sa1hfd1jhgk6g4k21bn65m4nb4", - "mail": "bbbbb", - "password": "bbbbb", - "id": 9892154, - "id42": -1 - }, - { - "username": "Mathis", - "token": "8cb1qjlfndc12mn2l1mn654xzkkhad54cxz", - "mail": "ccccc", - "password": "6304fbfe2b22557c34c42a70056616786a733b3d09fb326308c813d6ab712ec0", # not hashed : ccccc - "id": 2371234, - "id42": -1 - }, - { - "username": "Tom", - "token": "poiuygfvbdsv5c21vcxvcxhgbjqnkmds546", - "mail": "ddddd", - "password": "ddddd", - "id": 6423457, - "id42": -1 - } -] - -async def loginByToken(userClass, content): - # |TOM| Requete pour savoir si le token est valide - for user in userList: - if (user["token"] == content["token"]): - jsonVar = {"type": "login", "content": {"username": user["username"], "token": user["token"], "id": user["id"]}} - userClass.username = jsonVar["content"]["username"] - userClass.token = jsonVar["content"]["token"] - userClass.id = jsonVar["content"]["id"] - await userClass.send(jsonVar) - return - jsonVar = {"type": "error", "content": "Invalid token", "code": 9001} - await userClass.send(json.dumps(jsonVar)) - -async def loginByPass(userClass, content): - # |TOM| Requete pour savoir si le mail et le mot de passe sont valides - # et créer un token si celui-ci n'existe pas - for user in userList: - if (user["mail"] == content["mail"] and user["password"] == content["password"]): - jsonVar = {"type": "login", "content": {"username": user["username"], "token": user["token"], "id": user["id"]}} - userClass.username = jsonVar["content"]["username"] - userClass.token = jsonVar["content"]["token"] - userClass.id = jsonVar["content"]["id"] - await userClass.send(jsonVar) - return - await userClass.send({"type": "error", "content": "Invalid username or password", "code": 9007}) - - - -async def loginBy42(userClass, content): - # |TOM| Requete pour récuperer les informations de l'utilisateur selon l'intra de la personne - # et créer un token si celui-ci n'existe pas - try: - await main42login(userClass, content, userList) - except Exception as e: - await userClass.sendError("Invalid 42 token", 9010, e) - -async def login(userClass, content): - # |TOM| Faire 3 types de requêtes: - # - byToken: Récupérer les informations de l'utilisateur en fonction de son token - # - byPass: Récupérer les informations de l'utilisateur en fonction de mail et de son mot de passe - # - by42: Récupérer les informations de l'utilisateur en fonction de son token42 (qui sera different du token) - try: - if (content["type"] == "byToken"): - await loginByToken(userClass, content) - elif (content["type"] == "byPass"): - await loginByPass(userClass, content) - elif (content["type"] == "by42"): - await loginBy42(userClass, content) - else: - await userClass.sendError("Invalid login type", 9006) - except Exception as e: - await userClass.sendError("Invalid request", 9005, e) \ No newline at end of file diff --git a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login42/login42.py b/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login42/login42.py deleted file mode 100644 index 16a9e70..0000000 --- a/docker-compose/requirements/djangoserver/file/server/server/ws/typeRequets/login42/login42.py +++ /dev/null @@ -1,72 +0,0 @@ -# **************************************************************************** # -# # -# ::: :::::::: # -# login42.py :+: :+: :+: # -# +:+ +:+ +:+ # -# By: edbernar