mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-03 16:51:26 +00:00
116 lines
4.6 KiB
Python
116 lines
4.6 KiB
Python
"""
|
|
Tests de sécurité — GestionNotification
|
|
Vérifie :
|
|
- Les notifications sont filtrées par utilisateur (plus d'accès global)
|
|
- Authentification requise
|
|
"""
|
|
|
|
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
|
|
from GestionNotification.models import Notification
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def create_user_with_role(email, name="Ecole Test"):
|
|
user = Profile.objects.create_user(
|
|
username=email, email=email, password="TestPass!123"
|
|
)
|
|
est = Establishment.objects.create(
|
|
name=name, 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
|
|
|
|
|
|
OVERRIDE = dict(
|
|
CACHES={'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}},
|
|
SESSION_ENGINE='django.contrib.sessions.backends.db',
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@override_settings(**OVERRIDE)
|
|
class NotificationAuthTest(TestCase):
|
|
"""Authentification requise sur l'endpoint notifications."""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.url = reverse('GestionNotification:notifications')
|
|
|
|
def test_sans_auth_retourne_401(self):
|
|
response = self.client.get(self.url)
|
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
|
|
|
|
|
@override_settings(**OVERRIDE)
|
|
class NotificationFilterTest(TestCase):
|
|
"""
|
|
Chaque utilisateur ne voit que ses propres notifications.
|
|
Avant la correction, toutes les notifications étaient retournées
|
|
à n'importe quel utilisateur authentifié (IDOR).
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.client = APIClient()
|
|
self.url = reverse('GestionNotification:notifications')
|
|
self.alice = create_user_with_role('alice_notif@test.com', 'Ecole Alice')
|
|
self.bob = create_user_with_role('bob_notif@test.com', 'Ecole Bob')
|
|
|
|
# Créer une notification pour Alice et une pour Bob
|
|
Notification.objects.create(
|
|
user=self.alice, message='Message pour Alice', typeNotification=0
|
|
)
|
|
Notification.objects.create(
|
|
user=self.bob, message='Message pour Bob', typeNotification=0
|
|
)
|
|
|
|
def test_alice_voit_uniquement_ses_notifications(self):
|
|
"""Alice ne doit voir que sa propre notification, pas celle de Bob."""
|
|
token = str(RefreshToken.for_user(self.alice).access_token)
|
|
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
|
|
response = self.client.get(self.url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
data = response.json()
|
|
self.assertEqual(len(data), 1, "Alice doit voir uniquement ses propres notifications")
|
|
self.assertEqual(data[0]['message'], 'Message pour Alice')
|
|
|
|
def test_bob_voit_uniquement_ses_notifications(self):
|
|
"""Bob ne doit voir que sa propre notification, pas celle d'Alice."""
|
|
token = str(RefreshToken.for_user(self.bob).access_token)
|
|
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
|
|
response = self.client.get(self.url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
data = response.json()
|
|
self.assertEqual(len(data), 1, "Bob doit voir uniquement ses propres notifications")
|
|
self.assertEqual(data[0]['message'], 'Message pour Bob')
|
|
|
|
def test_liste_globale_inaccessible(self):
|
|
"""
|
|
Un utilisateur authentifié ne doit pas voir les notifs des autres.
|
|
Vérification croisée : nombre de notifs retournées == 1.
|
|
"""
|
|
carol = create_user_with_role('carol_notif@test.com', 'Ecole Carol')
|
|
token = str(RefreshToken.for_user(carol).access_token)
|
|
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {token}')
|
|
response = self.client.get(self.url)
|
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
data = response.json()
|
|
# Carol n'a aucune notification
|
|
self.assertEqual(len(data), 0,
|
|
"Un utilisateur sans notification ne doit pas voir celles des autres (IDOR)")
|