login with 42 works, fix crash when session is deleted from database

This commit is contained in:
2024-08-28 18:35:40 +02:00
parent d28f1a3c26
commit 0fd9d162d5
9 changed files with 89 additions and 140 deletions

View File

@ -6,7 +6,7 @@
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/07/13 16:18:56 by tomoron #+# #+# #
# Updated: 2024/08/11 16:54:45 by tomoron ### ########.fr #
# Updated: 2024/08/28 18:27:14 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -24,7 +24,7 @@ up: build
up_att: build
$(COMPOSE) up
watch: build
watch:
$(COMPOSE) watch
down:
$(COMPOSE) down -v

View File

@ -35,6 +35,8 @@ services:
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
UID_42: ${UID_42}
SECRET_42: ${SECRET_42}
depends_on:
- postgresql
restart: always

View File

@ -14,12 +14,12 @@ RUN python3.12 /root/get-pip.py
RUN pip3 install requests django psycopg "channels[daphne]" bcrypt
ARG DB_HOST=;
ARG DB_NAME=;
ARG DB_USERNAME=;
ARG DB_PASSWORD=;
ARG SECRET_42=;
ARG SECRET_42=;
ARG DB_HOST
ARG DB_NAME
ARG DB_USERNAME
ARG DB_PASSWORD
ARG UID_42
ARG SECRET_42
ENV DB_HOST=${DB_HOST}
ENV PYTHONUNBUFFERED=1
@ -41,4 +41,6 @@ sed -i "s/VAR_DB_NAME/$DB_NAME/" /var/www/djangoserver/server/server/settings.py
sed -i "s/VAR_DB_USERNAME/$DB_USERNAME/" /var/www/djangoserver/server/server/settings.py && \
sed -i "s/VAR_DB_PASSWORD/$DB_PASSWORD/" /var/www/djangoserver/server/server/settings.py
RUN echo -n $UID_42:$SECRET_42 > /var/www/djangoserver/42_credentials
ENTRYPOINT ["sh", "/root/start.sh"]

View File

@ -3,8 +3,8 @@ from django.db import models
class User(models.Model):
id = models.AutoField(primary_key=True)
username = models.CharField(max_length=20, unique=True)
mail = models.EmailField(unique=True)
password = models.CharField(max_length=100)
mail = models.EmailField(unique=True, 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)
pfp = models.CharField(max_length=1024, default="/static/img/default_pfp.jpg")

View File

@ -1,61 +1,23 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# getPrivateListUser.py :+: :+: :+: #
# getAllListUser.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 15:10:23 by edbernar #+# #+# #
# Updated: 2024/08/25 21:23:08 by tomoron ### ########.fr #
# Updated: 2024/08/28 18:22:43 by tomoron ### ########.fr #
# #
# **************************************************************************** #
import asyncio
import json
from django.db.models import Q
from ..models import Message, User
#data = [
# {
# "name": "Nessundorma",
# "status": "online",
# "pfp": "https://wallpapers-clan.com/wp-content/uploads/2023/05/cool-pfp-02.jpg",
# "id": 145564
# },
# {
# "name": "Succotash",
# "status": "offline",
# "pfp": "https://i.pinimg.com/200x/28/75/96/287596f98304bf1adc2c411619ae8fef.jpg",
# "id": 256981
# },
# {
# "name": "Astropower",
# "status": "online",
# "pfp": "https://ashisheditz.com/wp-content/uploads/2024/03/cool-anime-pfp-demon-slayer-HD.jpg",
# "id": 301547
# },
# {
# "name": "Assaultive",
# "status": "offline",
# "pfp": "https://i1.sndcdn.com/artworks-1Li0JIJrQGlojD3y-AEiNkw-t500x500.jpg",
# "id": 432448
# },
# {
# "name": "Redshock",
# "status": "offline",
# "pfp": "https://cdn.pfps.gg/pfps/7094-boy-pfp.png",
# "id": 543211
# },
# {
# "name": "Parley",
# "status": "offline",
# "pfp": "https://pbs.twimg.com/media/EscE6ckU0AA-Uhe.png",
# "id": 654123
# }
#]
def getAllListUser(socket, content=None):
id = socket.scope["session"].get("id", 0)
res = User.objects.all()
uid = socket.scope["session"].get("uid", 0)
res = User.objects.filter(~Q(id=uid))
data = []
for x in res:
data.append({"name":x.username, "pfp":x.pfp, "id":x.id})

View File

@ -6,11 +6,10 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/03 08:10:38 by edbernar #+# #+# #
# Updated: 2024/08/27 23:40:35 by tomoron ### ########.fr #
# Updated: 2024/08/28 16:45:14 by tomoron ### ########.fr #
# #
# **************************************************************************** #
from .login42.login42 import main42login
from ..models import User
import hashlib
import requests
@ -73,16 +72,6 @@ def loginByPass(socket, content):
else:
socket.send(text_data=json.dumps({"type": "error", "content": "Invalid email or password", "code": 9007}))
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:
main42login(socket, content, userList)
except Exception as e:
socket.sendError("Invalid 42 token", 9010, e)
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
@ -91,8 +80,6 @@ def login(socket, content):
try:
if (content["type"] == "byPass"):
loginByPass(socket, content)
elif (content["type"] == "by42"):
loginBy42(socket, content)
else:
socket.sendError("Invalid login type", 9006)
except Exception as e:

View File

@ -1,68 +0,0 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# login42.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/08/09 09:32:17 by edbernar #+# #+# #
# Updated: 2024/08/24 01:12:08 by tomoron ### ########.fr #
# #
# **************************************************************************** #
import requests
import json
import os
UID42 = os.environ.get("UID_42")
SECRET42 = os.environ.get("SECRET_42")
TOKENURL = 'https://api.intra.42.fr/oauth/token'
INFOURL = 'https://api.intra.42.fr/v2/me'
REDIRECT = 'http://127.0.0.1:5500/site/'
# |Eddy| Changer le redirect quand il y aura un vrai serveur
access_token = ""
if (UID42 == None or SECRET42 == None):
print("Please set the environment variables uid and secret")
exit()
def main42login(socket, content, userList):
global access_token
print(content['token'])
data = {
'grant_type': 'authorization_code',
'client_id': UID42,
'client_secret': SECRET42,
'code': content['token'],
'redirect_uri': REDIRECT
}
response = requests.post(TOKENURL, data=data)
if (response.status_code != 200):
raise Exception(f"Problem with the request (access_token {response.status_code})")
response = response.json()
headers = {
'Authorization': f'Bearer {response["access_token"]}',
}
response = requests.get(INFOURL, headers=headers)
if (response.status_code != 200):
raise Exception(f"Problem with the request (user info {response.status_code})")
response = response.json()
# |Tom| Au lieu d'utiliser userList, faire une requête à la base de donnée pour savoir si on a un utilisateur avec cet id42
i = 0
while (i < len(userList)):
if (userList[i]['id42'] == response['id']):
break
i += 1
if (i == len(userList)):
socket.sendError("Not user registered with this 42 account", 9011)
return
else:
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']}
}))

View File

@ -18,7 +18,9 @@ from django.urls import path
from . import views
urlpatterns = [
path("",views.index, name='patate'),
path("",views.index, name='index'),
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("logout", views.logout, name='logout')
]

View File

@ -1,9 +1,26 @@
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import render, redirect
from .models import User
import requests
import json
import os
UID42 = None
SECRET42 = None
with open("/var/www/djangoserver/42_credentials", 'r') as f:
creds = f.read().split(':')
UID42=creds[0]
SECRET42=creds[1]
TOKENURL = 'https://api.intra.42.fr/oauth/token'
INFOURL = 'https://api.intra.42.fr/v2/me'
REDIRECT = 'https://localhost:8000/login42'
def index(request):
request.session.save()
try:
request.session.save()
except Exception:
request.session.flush()
request.session.save()
return render(request, "index.html", {})
def homePage(request):
@ -12,4 +29,49 @@ def homePage(request):
def lobbyPage(request):
request.session.save()
return render(request, "lobbyPage.html", {})
return render(request, "lobbyPage.html", {})
def login42(request):
#url = https://api.intra.42.fr/oauth/authorize?client_id=<CLIENT_ID>&redirect_uri=https://localhost:8000/login42&response_type=code&scope=public'
if(request.session.get("logged_in", False)):
return HttpResponse("you're already logged in")
code = request.GET.get('code', None)
if(code == None):
return(HttpResponse("code param not found"))
data = {
'grant_type': 'authorization_code',
'client_id': UID42,
'client_secret': SECRET42,
'code': code,
'redirect_uri': REDIRECT
}
print("\033[31m",data)
response = requests.post(TOKENURL, data=data)
if (response.status_code != 200):
print(response.json())
return HttpResponse("couln't get authorization token, likely invalid code")
response = response.json()
headers = {
'Authorization': f'Bearer {response["access_token"]}',
}
response = requests.get(INFOURL, headers=headers)
if (response.status_code != 200):
return HttpResponse("couln't get user info... what, why ?")
response = response.json()
id42 = response['id']
login42 = response['login']
db_user = User.objects.filter(id42=id42)
if(not db_user.exists()):
while(User.objects.filter(username=login42).exists()):
login42 += "_"
db_user = [User.objects.create(username=login42, id42=id42)]
db_user[0].save()
request.session["logged_in"] = True
request.session["username"] = db_user[0].username
request.session["id"] = db_user[0].id
return redirect("/")
def logout(request):
request.session.delete()
return redirect("/")