Websocket :

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

View File

@ -6,4 +6,6 @@
- 9002 : Invalid json - 9002 : Invalid json
- 9003 : Invalid path - 9003 : Invalid path
- 9004 : Invalid type - 9004 : Invalid type
- 9005 : Invalid request - 9005 : Invalid request
- 9006 : Invalid login type
- 9007 : Invalid username or password

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 :+: :+: :+: # # main.py :+: :+: :+: #
# +:+ +:+ +:+ # # +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ # # By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:40 by edbernar #+# #+# # # 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.getPrivateListUser import getPrivateListUser
from typeRequets.login import login, userList from typeRequets.login import login
from Class.User import User
import websockets import websockets
import asyncio import asyncio
import json import json
connected_clients = set() 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"] typeRequest = ["login", "get_private_list_user"]
functionRequest = [login, getPrivateListUser] 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): async def handler(websocket, path):
if (path != "/"): if (path != "/"):
await sendError(websocket, "Invalid path", 9003) await websocket.sendError("Invalid path", 9003)
await websocket.close() await websocket.close()
return return
connected_clients.add(userInfo(websocket)) userClass = User(websocket)
connected_clients.add(userClass)
try: try:
async for resquet in websocket: async for resquet in userClass.websocket:
try: try:
jsonRequest = json.loads(resquet) jsonRequest = json.loads(resquet)
except json.JSONDecodeError: except json.JSONDecodeError:
await sendError(websocket, "Invalid JSON", 9002) await userClass.sendError("Invalid JSON", 9002)
continue continue
try: try:
if (jsonRequest["type"] in typeRequest): if (jsonRequest["type"] in typeRequest):
if jsonRequest["type"] == "login": if jsonRequest["type"] == "login":
await functionRequest[typeRequest.index(jsonRequest["type"])](websocket, jsonRequest["content"]) await functionRequest[typeRequest.index(jsonRequest["type"])](websocket, jsonRequest["content"])
else: else:
if (verifyToken(websocket, jsonRequest["token"]) == False): if (userClass.verifyToken(websocket, jsonRequest["token"]) == False):
await sendError(websocket, "Invalid token", 9001)
continue continue
await functionRequest[typeRequest.index(jsonRequest["type"])](websocket) await functionRequest[typeRequest.index(jsonRequest["type"])](websocket)
else: else:
await sendError(websocket, "Invalid type", 9004) await userClass.sendError("Invalid type", 9004)
except: except:
await sendError(websocket, "Invalid request", 9005) await userClass.sendError("Invalid request", 9005)
except websockets.ConnectionClosed: except websockets.ConnectionClosed:
connected_clients.remove(websocket) pass
print("Client déconnecté") await userClass.close()
connected_clients.remove(userClass)
start_server = websockets.serve(handler, "localhost", 8000, subprotocols=['123456']) start_server = websockets.serve(handler, "localhost", 8000, subprotocols=['123456'])
asyncio.get_event_loop().run_until_complete(start_server) 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 websockets
import asyncio
import json import json
data = [ 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 # |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é # utilisateurs qui doivent apparaitre dans la liste du chat privé
# (ceux qui ont eu conversation avec l'utilisateur) # (ceux qui ont eu conversation avec l'utilisateur)
jsonVar = {"type": "private_list_user", "content": data} await userClass.send({"type": "get_private_list_user", "content": data})
print(jsonVar)
await websocket.send(json.dumps(jsonVar))

View File

@ -3,34 +3,101 @@
# ::: :::::::: # # ::: :::::::: #
# login.py :+: :+: :+: # # login.py :+: :+: :+: #
# +:+ +:+ +:+ # # +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ # # By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# # # 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 requests
import websockets
import json 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 = [ userList = [
{ {
"username": "user1", "username": "user1",
"token": "123456", "token": "123456",
"mail": "aa@aa.fr",
"password": "ABC123",
"id": 1 "id": 1
}, },
{ {
"username": "user2", "username": "user2",
"token": "789123", "token": "789123",
"mail": "bb@bb.fr",
"password": "DEF456",
"id": 2 "id": 2
}, },
{ {
"username": "user3", "username": "user3",
"token": "456789", "token": "456789",
"mail": "cc@cc,fr",
"password": "GHI789",
"id": 3 "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): 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)

View File

@ -3,16 +3,15 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* main.js :+: :+: :+: */ /* main.js :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/30 13:50:35 by edbernar #+# #+# */ /* Created: 2024/07/30 13:50:35 by edbernar #+# #+# */
/* Updated: 2024/08/03 08:31:07 by edbernar ### ########.fr */ /* Updated: 2024/08/03 14:57:19 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
import { socket, token } from "./websocket.js"; import { socket, sendRequest } from "./websocket.js";
import { userList, waitForUserList } from "./typeResponse/typePrivateListUser.js"; import { userList, waitForUserList } from "./typeResponse/typePrivateListUser.js";
// Peut etre faire une fonction pour faire les requetes pour ne pas à avoir à ramener token partout
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
liveChat(); liveChat();
@ -51,28 +50,25 @@ async function showListUserMessage() {
const divMessageListChatHome = document.getElementById("messageListChatHome"); const divMessageListChatHome = document.getElementById("messageListChatHome");
let divUser; let divUser;
socket.send(JSON.stringify({ sendRequest("get_private_list_user", {});
type: 'get_private_list_user',
token: token,
content: {}
}));
await waitForUserList(); await waitForUserList();
console.log(userList);
divMessageListChatHome.style.height = "100%"; divMessageListChatHome.style.height = "100%";
divMessageListChatHome.style.paddingBottom = "10px"; divMessageListChatHome.style.paddingBottom = "10px";
divMessageListChatHome.innerHTML = ''; divMessageListChatHome.innerHTML = '';
divMessageListChatHome.scrollTop = 0; divMessageListChatHome.scrollTop = 0;
userList.forEach(element => { if (JSON.stringify(userList) !== "{}")
divMessageListChatHome.innerHTML += ` {
<div class="user"> userList.forEach(element => {
<div class="status ${element.status}"> divMessageListChatHome.innerHTML += `
<img src="${element.pfp}"> <div class="user">
<div class="status ${element.status}">
<img src="${element.pfp}">
</div>
<h3>${element.name}</h3>
</div> </div>
<h3>${element.name}</h3> `;
</div> });
`; }
});
divMessageListChatHome.innerHTML += "<p style='text-align: center; margin-top: 20px;'>New conversation +</p>"; divMessageListChatHome.innerHTML += "<p style='text-align: center; margin-top: 20px;'>New conversation +</p>";
divUser = document.getElementsByClassName("user"); divUser = document.getElementsByClassName("user");
for (let i = 0; i < divUser.length; i++) { for (let i = 0; i < divUser.length; i++) {

View File

@ -3,10 +3,10 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* typePrivateListUser.js :+: :+: :+: */ /* typePrivateListUser.js :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 01:56:15 by edbernar #+# #+# */ /* Created: 2024/08/02 01:56:15 by edbernar #+# #+# */
/* Updated: 2024/08/02 11:42:46 by edbernar ### ########.fr */ /* Updated: 2024/08/03 14:36:20 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -16,19 +16,18 @@ let userListResolve = null;
function waitForUserList() { function waitForUserList() {
return new Promise((resolve) => { return new Promise((resolve) => {
if (userListAvailable) { if (userListAvailable)
resolve(); resolve();
} else { else
userListResolve = resolve; userListResolve = resolve;
}
}); });
} }
function typePrivateListUser(list) { function typePrivateListUser(list) {
userList = list; userList = list;
userListAvailable = true; userListAvailable = true;
console.log(userListResolve) if (userListResolve)
if (userListResolve) { {
userListResolve(); userListResolve();
userListResolve = null; userListResolve = null;
} }

View File

@ -3,10 +3,10 @@
/* ::: :::::::: */ /* ::: :::::::: */
/* websocket.js :+: :+: :+: */ /* websocket.js :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ */ /* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */ /* Created: 2024/07/31 22:17:24 by edbernar #+# #+# */
/* Updated: 2024/08/03 08:46:22 by edbernar ### ########.fr */ /* Updated: 2024/08/03 15:04:37 by edbernar ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -21,6 +21,8 @@ const functionResponse = [typeLogin, typePrivateListUser];
socket.onopen = () => { socket.onopen = () => {
console.log('Connected'); console.log('Connected');
if (token)
sendRequest("login", {"type": "byToken", "token": token});
}; };
socket.onmessage = (event) => { socket.onmessage = (event) => {
@ -48,4 +50,18 @@ socket.onclose = () => {
console.log('Disconnected'); console.log('Disconnected');
}; };
export { socket, token}; function sendRequest(type, content) {
let coc = null;
if (content instanceof Object)
coc = JSON.stringify(content);
else
coc = content;
socket.send(JSON.stringify({
type: type,
token: token,
content: content
}));
}
export { socket, token, sendRequest };