add part of site to docker and login works using sessions

This commit is contained in:
2024-08-24 18:28:32 +02:00
parent 1291a6add8
commit 57ef3a5d2d
49 changed files with 2544 additions and 108 deletions

View File

@ -123,6 +123,12 @@ USE_TZ = True
STATIC_URL = 'static/'
STATIC_DIRS = [
BASE_DIR/ "static"
]
STATIC_ROOT = BASE_DIR / 'staticfiles'
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

View File

@ -0,0 +1,127 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Chat</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' href='/static/style/home.css'>
<link rel='stylesheet' type='text/css' href='/static/style/liveChat.css'>
<link rel='stylesheet' type='text/css' href='/static/style/notification.css'>
<link rel='stylesheet' type='text/css' href='/static/style/loginPage.css'>
<script type="module" src='/static/main.js'></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
</head>
<body>
<div id="divNotification">
</div>
<div id="topBar">
<h1>PTME</h1>
<div id="topButton">
<p>HOME</p>
<p>PROJECT</p>
<p>NEWS</p>
</div>
<div id="loginButton">
<p>LOGIN</p>
</div>
</div>
<div id="loginPopup" class="popup">
<div class="container">
<div class="left-side"></div>
<div class="right-side">
<h1>Access to a new WORLD</h1>
<form>
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="Email">
<label for="password">Password</label>
<input type="password" id="password" name="password" placeholder="Password">
<button type="submit" class="login-btn">Login</button>
<div class="new-player">
New player? <a href="#">Create an account</a>
</div>
<div class="divider">
<span></span>
<p>Or</p>
<span></span>
</div>
<button type="button" class="login-42-btn">Log with <span>42</span></button>
</form>
</div>
</div>
</div>
<div id="chatButton">
<p>CHAT</p>
</div>
<div id="chatDiv">
<div id="topChatHome">
<h1>Chat</h1>
<div id="topChatCross">
<h2>X</h2>
</div>
</div>
</div>
<section class="homeSection">
</section>
<section class="homeSection relative">
<img id="firstBall" src="static/style/ball3D2.png">
<img id="secondBall" src="static/style/ball3D3.png">
<div class="relative">
<p id="firstText">Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia totam cupiditate magni unde expedita molestiae eum aliquam fugit voluptatibus omnis! Dolores, ipsa inventore necessitatibus numquam aspernatur in perferendis id voluptas?</p>
<p id="secondText">Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia totam cupiditate magni unde expedita molestiae eum aliquam fugit voluptatibus omnis! Dolores, ipsa inventore necessitatibus numquam aspernatur in perferendis id voluptas?</p>
</div>
</section>
<section class="homeSection">
<div class="team">
<div class="team-member">
<img src="/static/style/tomoron.png" alt="Tom" class="team-photo">
<h2>Tom, tomoron</h2>
<p>Partie Backend</p>
<div class="info">
<p>Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.</p>
</div>
</div>
<div class="team-member">
<img src="/static/style/madegryc.png" alt="Mathis" class="team-photo">
<h2>Mathis, madegryc</h2>
<p>Partie Frontend / Design</p>
<div class="info">
<p>Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.</p>
</div>
</div>
<div class="team-member">
<img src="/static/style/edbernard.png" alt="Eddy" class="team-photo">
<h2>Eddy, edbernar</h2>
<p>Partie Midend</p>
<div class="info">
<p>Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.</p>
</div>
</div>
<div class="team-member">
<img src="/static/style/hubourge.png" alt="Hugo" class="team-photo">
<h2>Hugo, hubourge</h2>
<p>Partie jeu</p>
<div class="info">
<p>Tom est spécialisé en développement backend et travaille principalement avec Node.js et MongoDB.</p>
</div>
</div>
</div>
</section>
<footer>
<div class="footer-content">
<div class="footer-left">
<h1>PTME</h1>
<p>ft_transcendance project<br>for 42 shcool</p>
</div>
<div class="footer-right">
<p>2024</p>
</div>
</footer>
</body>
</html>

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/09 08:08:00 by edbernar #+# #+# #
# Updated: 2024/08/22 19:13:09 by tomoron ### ########.fr #
# Updated: 2024/08/24 01:11:45 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -19,42 +19,42 @@ pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_]).+$'
# {'username': 'Kumita', 'mail': 'eddydhj@gmail.com', 'password': '3b19482535d1ab2f4e3c629c4e3e5e2d6af0a5f5280be190726a4c3be518a475'}
async def createAccount(socket, content):
def createAccount(socket, content):
try:
content["mail"] = content["mail"].lower()
if (content["mail"].find('@') == -1 or content["mail"].find('.') == -1):
await socket.sendError("Invalid mail", 9006)
socket.sendError("Invalid mail", 9006)
return
if (content["username"].find(' ') != -1):
await socket.sendError("Username must not contain spaces", 9007)
socket.sendError("Username must not contain spaces", 9007)
return
if (len(content["username"]) < 3):
await socket.sendError("Username must be at least 3 characters long", 9008)
socket.sendError("Username must be at least 3 characters long", 9008)
return
if (len(content["username"]) > 20):
await socket.sendError("Username must be at most 20 characters long", 9009)
socket.sendError("Username must be at most 20 characters long", 9009)
return
if (content["username"].find(' ') != -1):
await socket.sendError("Username must not contain spaces", 9011)
socket.sendError("Username must not contain spaces", 9011)
return
if (content["username"].isalnum() == False):
await socket.sendError("Username must contain only letters and numbers", 9012)
socket.sendError("Username must contain only letters and numbers", 9012)
return
if (len(content["password"]) < 8):
await socket.sendError("Password must be at least 8 characters long", 9013)
socket.sendError("Password must be at least 8 characters long", 9013)
return
if (bool(re.match(pattern, content["password"]))):
await socket.sendError("Password must contain at least one lowercase letter, one uppercase letter and one special character", 9014)
socket.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 socket.sendError("Password must not contain the username", 9015)
socket.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 socket.sendError("Mail already used", 9016)
socket.sendError("Mail already used", 9016)
return
if (content["username"] in userList):
await socket.sendError("Username already used", 9017)
socket.sendError("Username already used", 9017)
return
content["token"] = generateToken()
while (True):
@ -62,9 +62,12 @@ async def createAccount(socket, content):
if (content["id"] not in userList):
break
userList.append(content)
await socket.send({"type": "create_account", "content": "Account created"})
socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"}))
socket.scope["session"]["logged_in"] = True
socket.scope["session"]["username"] = content["username"]
socket.scope["session"].save()
except Exception as e:
await socket.sendError("Error create account", 9005, e)
socket.sendError("Error create account", 9005, e)
def generateToken():
list = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 22:53:14 by edbernar #+# #+# #
# Updated: 2024/08/22 19:13:09 by tomoron ### ########.fr #
# Updated: 2024/08/23 23:56:06 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -56,7 +56,7 @@ def generate_random_string():
string += char[random.randint(0, len(char) - 1)]
return string
async def getPrivateListMessage(socket, content):
def getPrivateListMessage(socket, content):
# |TOM| Requete pour avoir la liste des messages privés grace à l'id de l'utilisateur
copyListMessage = listMessage.copy()
for message in copyListMessage["content"]:
@ -65,5 +65,5 @@ async def getPrivateListMessage(socket, content):
else:
message["from"] = content["id"]
message["content"] = generate_random_string()
await socket.send(copyListMessage)
socket.send(text_data=json.dumps(copyListMessage))

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 15:10:23 by edbernar #+# #+# #
# Updated: 2024/08/22 19:13:09 by tomoron ### ########.fr #
# Updated: 2024/08/23 23:55:50 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -52,9 +52,9 @@ data = [
}
]
async def getPrivateListUser(socket, content=None):
def getPrivateListUser(socket, 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 socket.sendError("User not found", 9008)
await socket.send({"type": "private_list_user", "content": data})
# Si user existe pas, faire ça : socket.sendError("User not found", 9008)
socket.send(text_data=json.dumps({"type": "private_list_user", "content": data}))

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# #
# Updated: 2024/08/22 19:12:23 by tomoron ### ########.fr #
# Updated: 2024/08/24 01:11:15 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -56,55 +56,44 @@ userList = [
}
]
async def loginByToken(socket, 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"]}}
socket.username = jsonVar["content"]["username"]
socket.token = jsonVar["content"]["token"]
socket.id = jsonVar["content"]["id"]
await socket.send(jsonVar)
return
jsonVar = {"type": "error", "content": "Invalid token", "code": 9001}
await socket.send(json.dumps(jsonVar))
async def loginByPass(socket, content):
def loginByPass(socket, 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"]}}
socket.username = jsonVar["content"]["username"]
socket.token = jsonVar["content"]["token"]
socket.id = jsonVar["content"]["id"]
await socket.send(jsonVar)
jsonVar = {"type": "login", "content": {"username": user["username"]}}
socket.scope["session"]["logged_in"] = True
socket.scope["session"]["username"] = jsonVar["content"]["username"]
socket.scope["session"].save()
socket.send(text_data=json.dumps(jsonVar))
return
await socket.send({"type": "error", "content": "Invalid username or password", "code": 9007})
socket.send(text_data=json.dumps({"type": "error", "content": "Invalid username or password", "code": 9007}))
async def loginBy42(socket, content):
def loginBy42(socket, 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(socket, content, userList)
main42login(socket, content, userList)
except Exception as e:
await socket.sendError("Invalid 42 token", 9010, e)
socket.sendError("Invalid 42 token", 9010, e)
async def login(socket, content):
def login(socket, content):
# |TOM| Faire 3 types de requêtes:
# - byToken: Récupérer les informations de l'utilisateur en fonction de son token
# - nope
# - 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)
print(json.dumps(content))
try:
if (content["type"] == "byToken"):
await loginByToken(socket, content)
elif (content["type"] == "byPass"):
await loginByPass(socket, content)
# if (content["type"] == "byToken"):
# loginByToken(socket, content)
if (content["type"] == "byPass"):
loginByPass(socket, content)
elif (content["type"] == "by42"):
await loginBy42(socket, content)
loginBy42(socket, content)
else:
await socket.sendError("Invalid login type", 9006)
socket.sendError("Invalid login type", 9006)
except Exception as e:
await socket.sendError("Invalid request", 9005, e)
socket.sendError("Invalid request", 9005, e)

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/09 09:32:17 by edbernar #+# #+# #
# Updated: 2024/08/22 19:13:31 by tomoron ### ########.fr #
# Updated: 2024/08/24 01:12:08 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -27,7 +27,7 @@ if (UID42 == None or SECRET42 == None):
print("Please set the environment variables uid and secret")
exit()
async def main42login(socket, content, userList):
def main42login(socket, content, userList):
global access_token
print(content['token'])
@ -56,17 +56,13 @@ async def main42login(socket, content, userList):
break
i += 1
if (i == len(userList)):
await socket.sendError("Not user registered with this 42 account", 9011)
socket.sendError("Not user registered with this 42 account", 9011)
return
else:
await socket.send({
socket.scope["session"]["logged_in"] = True
socket.scope["session"]["username"] = userList[i]['username']
socket.scope["session"].save()
socket.send(text_data=json.dumps({
"type": "login",
"content": {
"username": userList[i]['username'],
"token": userList[i]['token'],
"id": userList[i]['id']
}
})
"content": {"username": userList[i]['username']}
}))

View File

@ -6,15 +6,15 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/04 13:44:11 by edbernar #+# #+# #
# Updated: 2024/08/22 19:13:31 by tomoron ### ########.fr #
# Updated: 2024/08/23 23:54:32 by tomoron ### ########.fr #
# #
# **************************************************************************** #
from datetime import datetime
async def sendPrivateMessage(socket, content):
def sendPrivateMessage(socket, content):
# |Tom| Requete pour vérifier si l'user existe
# Si user existe pas, faire ça : await socket.sendError("User not found", 9008)
# Si user existe pas, faire ça : socket.sendError("User not found", 9008)
# Sinon l'ajouter à la base de données
# |Eddy| Si user existe, envoyer le message privé aux deux personnes concernées
# sachant que le receveur doit être connecté. Dans le cas contraire, uniquement
@ -30,6 +30,6 @@ async def sendPrivateMessage(socket, content):
"content": content["content"],
"date": time
}}
await socket.send(jsonVar)
socket.send(text_data=json.dumps(jsonVar))
except Exception as e:
await socket.sendError("Invalid message sent", 9009, e)
socket.sendError("Invalid message sent", 9009, e)

View File

@ -1,9 +1,6 @@
from django.http import HttpResponse
from django.shortcuts import render
from .models import User
def index(request):
if(request.session.get("visited", False)):
print("already visited")
request.session["visited"] = True
return HttpResponse("AAAAAAAAAAAAAAAAAAAAAAA")
return render(request, "index.html", {})

View File

@ -17,25 +17,21 @@ from random import randint
class WebsocketHandler(WebsocketConsumer):
debugMode = True
session = None
def connect(self):
print("new client")
self.accept()
print(self.scope["session"].get("number"))
if(self.scope["session"].get("number") == None):
self.scope["session"]["number"] = randint(0,2147483647)
self.scope["session"].save()
print("new number : ", self.scope["session"].get("number"))
else:
print("remembered number : ", self.scope["session"].get("number"))
self.send(text_data=json.dumps({"type":"is_logged_in", "content":self.scope["session"].get("logged_in",False)}))
print("new client")
def disconnect(self, close_code):
print("you can go, we never wanted you anyway")
print("you can go, i am not mad, we never wanted you anyway")
def receive(self, text_data):
print(self.scope["session"].get("number"))
print("someone is talking")
print("username is ", self.scope["session"].get("username"))
if(self.scope["session"].get("logged_in", False)):
print("user is logged in")
else:
print("user is not logged in")
try:
jsonRequest = json.loads(text_data)
except json.JSONDecodeError:
@ -47,13 +43,14 @@ class WebsocketHandler(WebsocketConsumer):
if (jsonRequest["type"] == "login" or jsonRequest["type"] == "create_account"):
functionRequest[typeRequest.index(jsonRequest["type"])](self, jsonRequest["content"])
else:
if (self.verifyToken(jsonRequest["token"]) == False):
return
if (not self.scope["session"].get("logged_in", False)):
return;
functionRequest[typeRequest.index(jsonRequest["type"])](self, jsonRequest["content"])
else:
self.sendError("Invalid type", 9004)
except Exception as e:
self.sendError("Invalid request", 9005, e)
print(e)
def sendError(self, message, code, error=None):
try: