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)
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")
mail_verified = models.BooleanField(default=False)
class Message(models.Model):
id = models.AutoField(primary_key=True)
@ -19,3 +20,7 @@ class Game(models.Model):
id = models.AutoField(primary_key=True)
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")
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. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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
from ..models import User, MailVerify
import random
import re
import json
@ -21,6 +20,8 @@ mail_pattern = "^((?!\.)[\w\-_.]*[^.])(@\w+)(\.\w+(\.\w+)?[^.\W])$"
password_pattern = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"
def createAccount(socket, content):
if (socket.logged_in):
socket.sendError("Already logged in", 9012)
try:
if (not bool(re.match(mail_pattern, content["mail"]))):
socket.sendError("Invalid mail", 9014)
@ -55,9 +56,16 @@ def createAccount(socket, content):
password = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
new_user = User.objects.create(username=content["username"], mail=content["mail"], password=password)
new_user.save()
if(socket.login(new_user.id, content["username"])):
socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"}))
else:
socket.sendError("Already logged in", 9012)
verif_str = gen_string(200)
MailVerify.objects.create(uid=new_user, token=verif_str).save()
sendVerifMail(verif_str)
socket.send(text_data=json.dumps({"type": "create_account", "content": "Account created"}))
except Exception as 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. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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 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):
password_hash = hashlib.md5((content["mail"] + content["password"]).encode()).hexdigest()
user = User.objects.filter(mail=content["mail"], password=password_hash)
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)):
socket.send(text_data=json.dumps({"type":"logged_in", "content":{
"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}))
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:
if (content["type"] == "byPass"):
loginByPass(socket, content)

View File

@ -22,5 +22,6 @@ urlpatterns = [
path("homePage",views.homePage, name='homePage'),
path("lobbyPage", views.lobbyPage, name='lobbyPage'),
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.shortcuts import render, redirect
from .models import User
from .models import User, MailVerify
import requests
import json
import os
@ -32,6 +32,21 @@ def lobbyPage(request):
request.session.save()
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):
if(request.session.get("logged_in", False)):
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
import json
@ -10,11 +22,12 @@ from .typeRequests.sendPrivateMessage import sendPrivateMessage
from .typeRequests.createAccount import createAccount
from .typeRequests.login import login
from .typeRequests.getAllListUser import getAllListUser
from .typeRequests.gameRequest import gameRequest
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,
sendPrivateMessage, createAccount, getAllListUser]
sendPrivateMessage, createAccount, getAllListUser, gameRequest]
from random import randint

View File

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