add mail verification on server side (does not send the mail for now)

This commit is contained in:
2024-09-09 21:47:55 +02:00
parent e070edbcd2
commit eaf71af8d1
8 changed files with 72 additions and 57 deletions

View File

@ -7,6 +7,7 @@ class User(models.Model):
password = models.CharField(max_length=100, null=True, blank=True) password = models.CharField(max_length=100, null=True, blank=True)
id42 = models.DecimalField(max_digits=15, decimal_places=0, null=True, unique=True) id42 = models.DecimalField(max_digits=15, decimal_places=0, null=True, unique=True)
pfp = models.CharField(max_length=1024, default="/static/img/default_pfp.jpg") pfp = models.CharField(max_length=1024, default="/static/img/default_pfp.jpg")
mail_verified = models.BooleanField(default=False)
class Message(models.Model): class Message(models.Model):
id = models.AutoField(primary_key=True) id = models.AutoField(primary_key=True)
@ -19,3 +20,7 @@ class Game(models.Model):
id = models.AutoField(primary_key=True) id = models.AutoField(primary_key=True)
player1 = models.ForeignKey("User", on_delete=models.SET_NULL, null=True, related_name="p1") player1 = models.ForeignKey("User", on_delete=models.SET_NULL, null=True, related_name="p1")
player2 = models.ForeignKey("User", on_delete=models.SET_NULL, null=True, related_name="p2") player2 = models.ForeignKey("User", on_delete=models.SET_NULL, null=True, related_name="p2")
class MailVerify(models.Model):
token = models.CharField(primary_key=True, max_length=200, unique=True)
uid = models.ForeignKey("User", on_delete=models.CASCADE, null=False)

View File

@ -6,12 +6,11 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ # # By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2024/08/09 08:08:00 by edbernar #+# #+# # # Created: 2024/08/09 08:08:00 by edbernar #+# #+# #
# Updated: 2024/09/06 18:53:05 by tomoron ### ########.fr # # Updated: 2024/09/09 21:10:56 by tomoron ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
from .login import userList from ..models import User, MailVerify
from ..models import User
import random import random
import re import re
import json import json
@ -21,6 +20,8 @@ mail_pattern = "^((?!\.)[\w\-_.]*[^.])(@\w+)(\.\w+(\.\w+)?[^.\W])$"
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$" password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
def createAccount(socket, content): def createAccount(socket, content):
if (socket.logged_in):
socket.sendError("Already logged in", 9012)
try: try:
if (not bool(re.match(mail_pattern, content["mail"]))): if (not bool(re.match(mail_pattern, content["mail"]))):
socket.sendError("Invalid mail", 9014) socket.sendError("Invalid mail", 9014)
@ -55,9 +56,16 @@ def createAccount(socket, content):
password = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest() password = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
new_user = User.objects.create(username=content["username"], mail=content["mail"], password=password) new_user = User.objects.create(username=content["username"], mail=content["mail"], password=password)
new_user.save() new_user.save()
if(socket.login(new_user.id, content["username"])): verif_str = gen_string(200)
socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"})) MailVerify.objects.create(uid=new_user, token=verif_str).save()
else: sendVerifMail(verif_str)
socket.sendError("Already logged in", 9012) socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"}))
except Exception as e: except Exception as e:
socket.sendError("An error occured while creating the account", 9024, e) socket.sendError("An error occured while creating the account", 9024, e)
def sendVerifMail(verif_str):
print("nope")
def gen_string(length):
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return(''.join(random.choice(letters) for i in range(length)))

View File

@ -0,0 +1,14 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# gameRequest.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/09 16:10:26 by tomoron #+# #+# #
# Updated: 2024/09/09 16:53:01 by tomoron ### ########.fr #
# #
# **************************************************************************** #
def gameRequest(socket, content):
print("nope")

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ # # 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/30 11:26:02 by edbernar ### ########.fr # # Updated: 2024/09/09 21:19:50 by tomoron ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -16,51 +16,13 @@ import requests
import json import json
import os import os
# 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": "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
}
]
def loginByPass(socket, content): def loginByPass(socket, content):
password_hash = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest() password_hash = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
user = User.objects.filter(mail=content["mail"], password=password_hash) user = User.objects.filter(mail=content["mail"], password=password_hash)
if(user.exists()): if(user.exists()):
if(user[0].mail != None and not user[0].mail_verified):
socket.sendError("Account not verified, please verify your account before logging in",9025)
return ;
if(socket.login(user[0].id, user[0].username)): if(socket.login(user[0].id, user[0].username)):
socket.send(text_data=json.dumps({"type":"logged_in", "content":{ socket.send(text_data=json.dumps({"type":"logged_in", "content":{
"status":True, "status":True,
@ -71,10 +33,6 @@ def loginByPass(socket, content):
socket.send(text_data=json.dumps({"type": "error", "content": "Invalid email or password", "code": 9007})) socket.send(text_data=json.dumps({"type": "error", "content": "Invalid email or password", "code": 9007}))
def login(socket, content): def login(socket, content):
# |TOM| Faire 3 types de requêtes:
# - 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)
# - will probably change
try: try:
if (content["type"] == "byPass"): if (content["type"] == "byPass"):
loginByPass(socket, content) loginByPass(socket, content)

View File

@ -22,5 +22,6 @@ urlpatterns = [
path("homePage",views.homePage, name='homePage'), path("homePage",views.homePage, name='homePage'),
path("lobbyPage", views.lobbyPage, name='lobbyPage'), path("lobbyPage", views.lobbyPage, name='lobbyPage'),
path("login42", views.login42, name='login42'), path("login42", views.login42, name='login42'),
path("logout", views.logout, name='logout') path("logout", views.logout, name='logout'),
path("verify", views.verify, name='verify')
] ]

View File

@ -1,6 +1,6 @@
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from .models import User from .models import User, MailVerify
import requests import requests
import json import json
import os import os
@ -32,6 +32,21 @@ def lobbyPage(request):
request.session.save() request.session.save()
return render(request, "lobbyPage.html", {}) return render(request, "lobbyPage.html", {})
def verify(request):
req_token = request.GET.get('token', None)
if(req_token == None):
return(HttpResponse("token param missing"))
user_code = MailVerify.objects.filter(token=req_token)
if(not user_code.exists()):
return(HttpResponse("token not found (PS : il faudrais peut-être faire une page avec un petit peu css pour ça mais moi ça me va là) ( PSS: il faudrait peut-être faire une page aussi pour quand il manque le parametre token, flemme de mettre ce message dans sa réponse c'est genre 3 lignes au dessus, c'est trop loin) (PSSS: peut-être une page d'erreur générique qu'on peut remplir avec des variables pour les messages d'erreur"))
user_code = user_code[0]
if(user_code.uid.mail_verified):
return(HttpResponse("your mail is already verified, you can now login (PS: voir erreur token not found)"))
user_code.uid.mail_verified = True
user_code.uid.save()
user_code.delete()
return(HttpResponse("your mail has been verified ! (et pourquoi pas une page pour dire que l'email a été verifié, sinon je peut juste redirect vers la page principale)"))
def login42(request): def login42(request):
if(request.session.get("logged_in", False)): if(request.session.get("logged_in", False)):
return HttpResponse("you're already logged in") return HttpResponse("you're already logged in")

View File

@ -1,3 +1,15 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# websocket.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/09 14:31:30 by tomoron #+# #+# #
# Updated: 2024/09/09 16:10:15 by tomoron ### ########.fr #
# #
# **************************************************************************** #
from channels.generic.websocket import WebsocketConsumer from channels.generic.websocket import WebsocketConsumer
import json import json
@ -10,11 +22,12 @@ from .typeRequests.sendPrivateMessage import sendPrivateMessage
from .typeRequests.createAccount import createAccount from .typeRequests.createAccount import createAccount
from .typeRequests.login import login from .typeRequests.login import login
from .typeRequests.getAllListUser import getAllListUser from .typeRequests.getAllListUser import getAllListUser
from .typeRequests.gameRequest import gameRequest
typeRequest = ["login", "get_private_list_user", "get_private_list_message", typeRequest = ["login", "get_private_list_user", "get_private_list_message",
"send_private_message", "create_account", "get_all_list_user"] "send_private_message", "create_account", "get_all_list_user", "game"]
functionRequest = [login, getPrivateListUser, getPrivateListMessage, functionRequest = [login, getPrivateListUser, getPrivateListMessage,
sendPrivateMessage, createAccount, getAllListUser] sendPrivateMessage, createAccount, getAllListUser, gameRequest]
from random import randint from random import randint

View File

@ -26,3 +26,4 @@
- 9022 : Mail already used - 9022 : Mail already used
- 9023 : Username already used - 9023 : Username already used
- 9024 : An error occured while creating the account - 9024 : An error occured while creating the account
- 9025 : Account not verified, please verify your account before logging in