from django.conf import settings from django.contrib.auth import login, authenticate, get_user_model from django.http.response import JsonResponse from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt, csrf_protect from django.utils.decorators import method_decorator from django.core.exceptions import ValidationError from django.core.cache import cache from django.middleware.csrf import get_token from rest_framework.views import APIView from rest_framework.parsers import JSONParser from rest_framework import status from datetime import datetime import jwt import json from . import validator from .models import Profile from Auth.serializers import ProfileSerializer, ProfilUpdateSerializer from Subscriptions.models import RegistrationForm from Subscriptions.signals import clear_cache import Subscriptions.mailManager as mailer import Subscriptions.util as util from N3wtSchool import bdd, error def csrf(request): token = get_token(request) return JsonResponse({'csrfToken': token}) class SessionView(APIView): def post(self, request): token = request.META.get('HTTP_AUTHORIZATION', '').split('Bearer ')[-1] try: decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256']) print(f'decode : {decoded_token}') user_id = decoded_token.get('id') user = Profile.objects.get(id=user_id) response_data = { 'user': { 'id': user.id, 'email': user.email, 'role': user.droit, # Assure-toi que le champ 'droit' existe et contient le rôle } } return JsonResponse(response_data, status=status.HTTP_200_OK) except jwt.ExpiredSignatureError: return JsonResponse({"error": "Token has expired"}, status=status.HTTP_401_UNAUTHORIZED) except jwt.InvalidTokenError: return JsonResponse({"error": "Invalid token"}, status=status.HTTP_401_UNAUTHORIZED) class ProfileListView(APIView): def get(self, request): profilsList = bdd.getAllObjects(_objectName=Profile) profils_serializer = ProfileSerializer(profilsList, many=True) return JsonResponse(profils_serializer.data, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class ProfileView(APIView): def get(self, request, _id): profil=bdd.getObject(Profile, "id", _id) profil_serializer=ProfileSerializer(profil) return JsonResponse(profil_serializer.data, safe=False) def post(self, request): profil_data=JSONParser().parse(request) print(f'{profil_data}') profil_serializer = ProfileSerializer(data=profil_data) if profil_serializer.is_valid(): profil_serializer.save() return JsonResponse(profil_serializer.data, safe=False) return JsonResponse(profil_serializer.errors, safe=False) def put(self, request, _id): data=JSONParser().parse(request) profil = Profile.objects.get(id=_id) profil_serializer = ProfilUpdateSerializer(profil, data=data) if profil_serializer.is_valid(): profil_serializer.save() return JsonResponse("Updated Successfully", safe=False) return JsonResponse(profil_serializer.errors, safe=False) def infoSession(request): profilCache = cache.get('session_cache') if profilCache: return JsonResponse({"cacheSession":True,"typeProfil":profilCache.droit, "username":profilCache.email}, safe=False) else: return JsonResponse({"cacheSession":False,"typeProfil":Profile.Droits.PROFIL_UNDEFINED, "username":""}, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class LoginView(APIView): def get(self, request): return JsonResponse({ 'errorFields':'', 'errorMessage':'', 'profil':0, }, safe=False) def post(self, request): data=JSONParser().parse(request) validatorAuthentication = validator.ValidatorAuthentication(data=data) retour = error.returnMessage[error.WRONG_ID] validationOk, errorFields = validatorAuthentication.validate() user = None if validationOk: user = authenticate( email=data.get('email'), password=data.get('password'), ) if user is not None: if user.is_active: login(request, user) user.estConnecte = True user.save() clear_cache() retour = '' else: retour = error.returnMessage[error.PROFIL_INACTIVE] # Génération du token JWT # jwt_token = jwt.encode({ # 'id': user.id, # 'email': user.email, # 'role': "admin" # }, settings.SECRET_KEY, algorithm='HS256') else: retour = error.returnMessage[error.WRONG_ID] return JsonResponse({ 'errorFields':errorFields, 'errorMessage':retour, 'profil':user.id if user else -1, 'droit':user.droit if user else -1, #'jwtToken':jwt_token if profil != -1 else '' }, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class SubscribeView(APIView): def get(self, request): return JsonResponse({ 'message':'', 'errorFields':'', 'errorMessage':'' }, safe=False) def post(self, request): retourErreur = error.returnMessage[error.BAD_URL] retour = '' newProfilConnection=JSONParser().parse(request) validatorSubscription = validator.ValidatorSubscription(data=newProfilConnection) validationOk, errorFields = validatorSubscription.validate() if validationOk: # On vérifie que l'email existe : si ce n'est pas le cas, on retourne une erreur profil = bdd.getProfile(Profile.objects.all(), newProfilConnection.get('email')) if profil == None: retourErreur = error.returnMessage[error.PROFIL_NOT_EXISTS] else: if profil.is_active: retourErreur=error.returnMessage[error.PROFIL_ACTIVE] return JsonResponse({'message':retour,'errorMessage':retourErreur, "errorFields":errorFields, "id":profil.id}, safe=False) else: try: profil.set_password(newProfilConnection.get('password1')) profil.is_active = True profil.full_clean() profil.save() clear_cache() retour = error.returnMessage[error.MESSAGE_ACTIVATION_PROFILE] retourErreur='' return JsonResponse({'message':retour,'errorMessage':retourErreur, "errorFields":errorFields, "id":profil.id}, safe=False) except ValidationError as e: retourErreur = error.returnMessage[error.WRONG_MAIL_FORMAT] return JsonResponse({'message':retour,'errorMessage':retourErreur, "errorFields":errorFields}, safe=False) return JsonResponse({'message':retour, 'errorMessage':retourErreur, "errorFields":errorFields, "id":-1}, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class NewPasswordView(APIView): def get(self, request): return JsonResponse({ 'message':'', 'errorFields':'', 'errorMessage':'' }, safe=False) def post(self, request): retourErreur = error.returnMessage[error.BAD_URL] retour = '' newProfilConnection=JSONParser().parse(request) validatorNewPassword = validator.ValidatorNewPassword(data=newProfilConnection) validationOk, errorFields = validatorNewPassword.validate() if validationOk: profil = bdd.getProfile(Profile.objects.all(), newProfilConnection.get('email')) if profil == None: retourErreur = error.returnMessage[error.PROFIL_NOT_EXISTS] else: # Génération d'une URL provisoire pour modifier le mot de passe profil.code = util.genereRandomCode(12) profil.datePeremption = util.calculeDatePeremption(util._now(), settings.EXPIRATION_URL_NB_DAYS) profil.save() clear_cache() retourErreur = '' retour = error.returnMessage[error.MESSAGE_REINIT_PASSWORD]%(newProfilConnection.get('email')) mailer.envoieReinitMotDePasse(newProfilConnection.get('email'), profil.code) return JsonResponse({'message':retour, 'errorMessage':retourErreur, "errorFields":errorFields}, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class ResetPasswordView(APIView): def get(self, request, _uuid): return JsonResponse({ 'message':'', 'errorFields':'', 'errorMessage':'' }, safe=False) def post(self, request, _uuid): retourErreur = error.returnMessage[error.BAD_URL] retour = '' newProfilConnection=JSONParser().parse(request) validatorResetPassword = validator.ValidatorResetPassword(data=newProfilConnection) validationOk, errorFields = validatorResetPassword.validate() profil = bdd.getObject(Profile, "code", _uuid) if profil: if datetime.strptime(util.convertToStr(util._now(), '%d-%m-%Y %H:%M'), '%d-%m-%Y %H:%M') > datetime.strptime(profil.datePeremption, '%d-%m-%Y %H:%M'): retourErreur = error.returnMessage[error.EXPIRED_URL]%(_uuid) elif validationOk: retour = error.returnMessage[error.PASSWORD_CHANGED] profil.set_password(newProfilConnection.get('password1')) profil.code = '' profil.datePeremption = '' profil.save() clear_cache() retourErreur='' return JsonResponse({'message':retour, "errorMessage":retourErreur, "errorFields":errorFields}, safe=False)