mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-03 16:51:26 +00:00
117 lines
4.3 KiB
Python
117 lines
4.3 KiB
Python
"""
|
|
Tests de sécurité — GestionEmail
|
|
Vérifie :
|
|
- search_recipients nécessite une authentification (plus accessible anonymement)
|
|
- send-email nécessite une authentification
|
|
- Les données personnelles ne sont pas dans les logs INFO
|
|
"""
|
|
|
|
import json
|
|
|
|
from django.test import TestCase, override_settings
|
|
from django.urls import reverse
|
|
from rest_framework import status
|
|
from rest_framework.test import APIClient
|
|
from rest_framework_simplejwt.tokens import RefreshToken
|
|
|
|
from Auth.models import Profile, ProfileRole
|
|
from Establishment.models import Establishment
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def create_user_with_role(email, password="TestPass!123"):
|
|
user = Profile.objects.create_user(
|
|
username=email, email=email, password=password
|
|
)
|
|
est = Establishment.objects.create(
|
|
name=f"Ecole {email}",
|
|
address="1 rue Test",
|
|
total_capacity=50,
|
|
establishment_type=[1],
|
|
)
|
|
ProfileRole.objects.create(
|
|
profile=user,
|
|
role_type=ProfileRole.RoleType.PROFIL_ECOLE,
|
|
establishment=est,
|
|
is_active=True,
|
|
)
|
|
return user, est
|
|
|
|
|
|
OVERRIDE = dict(
|
|
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}},
|
|
SESSION_ENGINE='django.contrib.sessions.backends.db',
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tests : search_recipients exige une authentification
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@override_settings(**OVERRIDE)
|
|
class SearchRecipientsAuthTest(TestCase):
|
|
"""
|
|
GET /email/search-recipients/ doit retourner 401 si non authentifié.
|
|
Avant la correction, cet endpoint était accessible anonymement
|
|
(harvesting d'emails des membres d'un établissement).
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.url = reverse('GestionEmail:search_recipients')
|
|
|
|
def test_sans_auth_retourne_401(self):
|
|
"""Accès anonyme doit être rejeté avec 401."""
|
|
response = self.client.get(self.url, {'q': 'test', 'establishment_id': 1})
|
|
self.assertEqual(
|
|
response.status_code, status.HTTP_401_UNAUTHORIZED,
|
|
"search_recipients doit exiger une authentification (OWASP A01 - Broken Access Control)"
|
|
)
|
|
|
|
def test_avec_auth_et_query_vide_retourne_200_ou_liste_vide(self):
|
|
"""Un utilisateur authentifié sans terme de recherche reçoit une liste vide."""
|
|
user, est = create_user_with_role('search_auth@test.com')
|
|
token = str(RefreshToken.for_user(user).access_token)
|
|
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
|
|
response = self.client.get(self.url, {'q': '', 'establishment_id': est.id})
|
|
self.assertIn(response.status_code, [status.HTTP_200_OK, status.HTTP_400_BAD_REQUEST])
|
|
|
|
def test_avec_auth_et_establishment_manquant_retourne_400(self):
|
|
"""Un utilisateur authentifié sans establishment_id reçoit 400."""
|
|
user, _ = create_user_with_role('search_noest@test.com')
|
|
token = str(RefreshToken.for_user(user).access_token)
|
|
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
|
|
response = self.client.get(self.url, {'q': 'alice'})
|
|
self.assertIn(response.status_code, [status.HTTP_400_BAD_REQUEST, status.HTTP_200_OK])
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tests : send-email exige une authentification
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@override_settings(**OVERRIDE)
|
|
class SendEmailAuthTest(TestCase):
|
|
"""
|
|
POST /email/send-email/ doit retourner 401 si non authentifié.
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.url = reverse('GestionEmail:send_email')
|
|
|
|
def test_sans_auth_retourne_401(self):
|
|
"""Accès anonyme à l'envoi d'email doit être rejeté."""
|
|
payload = {
|
|
'recipients': ['victim@example.com'],
|
|
'subject': 'Test',
|
|
'message': 'Hello',
|
|
'establishment_id': 1,
|
|
}
|
|
response = self.client.post(
|
|
self.url, data=json.dumps(payload), content_type='application/json'
|
|
)
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|