Websocket :

- New class "User" in server
    - Doing the auth
This commit is contained in:
Kum1ta
2024-08-03 17:21:40 +02:00
parent f3698d3683
commit 6b40fb5927
13 changed files with 228 additions and 72 deletions

View File

@ -0,0 +1,82 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# User.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 15:54:14 by edbernar #+# #+# #
# Updated: 2024/08/03 17:17:39 by edbernar ### ########.fr #
# #
# **************************************************************************** #
import websockets
import asyncio
import json
class User(websockets.WebSocketServerProtocol):
debugMode = True
websocket = None
username = ""
token = ""
id = -1
def __init__(self, websocket):
if (self.debugMode):
print("\033[0;34m|------ New user Connected ------|\033[0;0m")
self.websocket = websocket
def __del__(self):
if (self.debugMode):
print("\033[0;31m|------ User disconnected ------|\033[0;0m")
async def sendError(self, message, code):
jsonVar = {"type": "error", "content": message, "code": code}
self.printDebug( jsonVar, 2)
await self.websocket.send(json.dumps(jsonVar))
async def send(self, content):
self.printDebug(content, 1)
if (type(content) == dict):
await self.websocket.send(json.dumps(content))
else:
await self.websocket.send(content)
async def verifyToken(self, token):
if (self.token != token or self.token == ""):
await self.sendError("Invalid token", 9001)
return False
return True
def printDebug(self, infoUser, request, typeRequest):
try:
if (self.debugMode and typeRequest == 0):
print("\033[0;34m|----- New received request -----|\033[0;0m")
print("User :", infoUser.username)
print("Token :", infoUser.token)
print("Id :", infoUser.id)
print("Var type :", type(request["type"]))
print("Type :", request["type"])
print("Content :", request["content"])
elif (self.debugMode and typeRequest == 1):
print("\033[0;32m|------- New sent request -------|\033[0;0m")
print("To :", infoUser.username)
print("Var type :", type(request["type"]))
print("Type :", request["type"])
print("Content :", request["content"])
elif (self.debugMode and typeRequest == 2):
print("\033[0;31m|------------- Error ------------|\033[0;0m")
print("User :", infoUser.username)
print("Token :", infoUser.token)
print("Id :", infoUser.id)
print("Error message :", request["content"])
print("Error code :", request["code"])
except:
print("\033[0;31m|------- Error in printDebug -----|\033[0;0m")
async def close(self):
try:
await self.websocket.close()
except:
pass

View File

@ -3,71 +3,55 @@
# ::: :::::::: #
# main.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:40 by edbernar #+# #+# #
# Updated: 2024/08/03 08:46:38 by edbernar ### ########.fr #
# Updated: 2024/08/03 17:20:07 by edbernar ### ########.fr #
# #
# **************************************************************************** #
from typeRequets.getPrivateListUser import getPrivateListUser
from typeRequets.login import login, userList
from typeRequets.login import login
from Class.User import User
import websockets
import asyncio
import json
connected_clients = set()
class userInfo(websockets.WebSocketServerProtocol):
def __init__(self, websocket):
self.websocket = websocket
self.username = ""
self.token = ""
self.id = 0
typeRequest = ["login", "get_private_list_user"]
functionRequest = [login, getPrivateListUser]
async def sendError(websocket, message, code):
jsonVar = {"type": "error", "content": message, "code": code}
await websocket.send(json.dumps(jsonVar))
def verifyToken(websocket, token):
for user in userList:
if (user["token"] == token):
return True
return False
async def handler(websocket, path):
if (path != "/"):
await sendError(websocket, "Invalid path", 9003)
await websocket.sendError("Invalid path", 9003)
await websocket.close()
return
connected_clients.add(userInfo(websocket))
userClass = User(websocket)
connected_clients.add(userClass)
try:
async for resquet in websocket:
async for resquet in userClass.websocket:
try:
jsonRequest = json.loads(resquet)
except json.JSONDecodeError:
await sendError(websocket, "Invalid JSON", 9002)
await userClass.sendError("Invalid JSON", 9002)
continue
try:
if (jsonRequest["type"] in typeRequest):
if jsonRequest["type"] == "login":
await functionRequest[typeRequest.index(jsonRequest["type"])](websocket, jsonRequest["content"])
else:
if (verifyToken(websocket, jsonRequest["token"]) == False):
await sendError(websocket, "Invalid token", 9001)
if (userClass.verifyToken(websocket, jsonRequest["token"]) == False):
continue
await functionRequest[typeRequest.index(jsonRequest["type"])](websocket)
else:
await sendError(websocket, "Invalid type", 9004)
await userClass.sendError("Invalid type", 9004)
except:
await sendError(websocket, "Invalid request", 9005)
await userClass.sendError("Invalid request", 9005)
except websockets.ConnectionClosed:
connected_clients.remove(websocket)
print("Client déconnecté")
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)

View File

@ -1,5 +1,17 @@
import asyncio
# **************************************************************************** #
# #
# ::: :::::::: #
# getPrivateListUser.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 15:10:23 by edbernar #+# #+# #
# Updated: 2024/08/03 17:07:21 by edbernar ### ########.fr #
# #
# **************************************************************************** #
import websockets
import asyncio
import json
data = [
@ -35,10 +47,8 @@ data = [
},
]
async def getPrivateListUser(websocket):
async def getPrivateListUser(userClass):
# |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)
jsonVar = {"type": "private_list_user", "content": data}
print(jsonVar)
await websocket.send(json.dumps(jsonVar))
await userClass.send({"type": "get_private_list_user", "content": data})

View File

@ -3,34 +3,101 @@
# ::: :::::::: #
# login.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# #
# Updated: 2024/08/03 08:46:00 by edbernar ### ########.fr #
# Updated: 2024/08/03 17:08:07 by edbernar ### ########.fr #
# #
# **************************************************************************** #
import asyncio
import websockets
import requests
import json
# Les requêtes de login peuvent être de 3 types:
# <-- {"type" : "login", "content" : {"type": "byToken", "token": "123456"}}
# <-- {"type" : "login", "content" : {"type": "byPass", "mail": "aaa@a.com", "pass": "dasd"}}
# <-- {"type" : "login", "content" : {"type": "by42", "token": "1dsa23dsa456"}}
# --> {"type" : "login", "content" : {"username": "". "token": "", "id": 0}}
userList = [
{
"username": "user1",
"token": "123456",
"mail": "aa@aa.fr",
"password": "ABC123",
"id": 1
},
{
"username": "user2",
"token": "789123",
"mail": "bb@bb.fr",
"password": "DEF456",
"id": 2
},
{
"username": "user3",
"token": "456789",
"mail": "cc@cc,fr",
"password": "GHI789",
"id": 3
}
]
async def loginByToken(websocket, 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"]}}
await websocket.send(json.dumps(jsonVar))
return
jsonVar = {"type": "error", "content": "Invalid token", "code": 9001}
await websocket.send(json.dumps(jsonVar))
async def loginByPass(websocket, content):
# |TOM| Requete pour savoir si le mail et le mot de passe sont valides
# et créer un token s'il n'existe pas
for user in userList:
if (user["username"] == content["username"] and user["password"] == content["password"]):
jsonVar = {"type": "login", "content": {"username": user["username"], "token": user["token"], "id": user["id"]}}
await websocket.send(json.dumps(jsonVar))
return
jsonVar = {"type": "error", "content": "Invalid username or password", "code": 9007}
await websocket.send(json.dumps(jsonVar))
async def verifyToken42(token42):
url = "https://api.intra.42.fr/v2/me"
headers = {
"Authorization": f"Bearer {token42}"
}
response = requests.get(url, headers=headers)
# |Eddy| Regarder ce que renvoie la requete quand elle est valide pour savoir qui rechercher
# dans la base de données
return (response.status_code == 200)
async def loginBy42(websocket, content):
# |TOM| Requete pour récuperer les informations de l'utilisateur selon l'intra de la personne
# et créer un token s'il n'existe pas
for user in userList:
if (await verifyToken42(content["token42"])):
jsonVar = {"type": "login", "content": {"username": user["username"], "token": user["token"], "id": user["id"]}}
await websocket.send(json.dumps(jsonVar))
jsonVar = {"type": "error", "content": "Invalid 42 token", "code": 9008}
await websocket.send(json.dumps(jsonVar))
async def login(websocket, content):
print(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(websocket, content)
elif (content["type"] == "byPass"):
await loginByPass(websocket, content)
elif (content["type"] == "by42"):
await loginBy42(websocket, content)
else:
await sendError(websocket, "Invalid login type", 9006)
except:
await sendError(websocket, "Invalid request", 9005)