Initial commit

This commit is contained in:
Claude Paroz 2024-06-03 16:49:01 +02:00
commit 793bb6a488
182 changed files with 17153 additions and 0 deletions

View file

51
archive/tests/crne_rsa Normal file
View file

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCsGKEEl1oiJgE5o/8CPC+pBAU7WKdUQhWsq6Q8mZvEyMVx4Gsd3VgMxDYnkr0tyqVmcUkufVfAZV8ZIyixEDxU4pqh/8QD2el1D+dw2lNzwa6CrbPRSaxiOvY5eWhm7duQR3OETs1/nAT+zmodDogWfo3IfBJuDqJRWXV34L5Rk1Vdk9rKEAfGyogxBvtr8UKq6xZXSDweY/jFKrtnyACXsGmD94aqcgpWbaLxTR064Ahyuh/jlACfTt7aKZf/YYtJRGseeNlx6VRRYl+UQN02uwWL/fPU9g+E04e/BHtIvPByddnwYSWlwaeIFHS9Ta6sIO0LW3E1oYAGOhao8c+Z3GyqG6Og13x5XG7bQOjR/IqtKcWobNT+cXJ7vtAkzsdQpIIgtFIm9eGNXhGfuq9Tn4KlzzAl3lP9y+RpchnRxcZJTqslflB0tFPTkwj5biDIbNvcxOdr38QyO2lHyejpJgFixxNj+PD0reE1ii7UyMkXXLelRKZwHRpetSqNzVuyHOrtJW+R2gMbPaPRsfI6Rz3gbXIw0m4rrOeoepnMGMT0w90TRF0ohqNACrFx/7dLyFL6529gx8DmBntWLUWIYkGJ/o9F1Iwzlp3s3e0KWvsktMfyadgMbIQtolqXaVS7rpIs4uJBZjR1Ya2+MY/IyFZbNJM+ny3aYxGMvHcUhQ== transit@example.org

BIN
archive/tests/sample-2.msg Normal file

Binary file not shown.

BIN
archive/tests/sample.doc Normal file

Binary file not shown.

BIN
archive/tests/sample.docx Normal file

Binary file not shown.

BIN
archive/tests/sample.msg Normal file

Binary file not shown.

BIN
archive/tests/sample.pdf Normal file

Binary file not shown.

204
archive/tests/tests.py Normal file
View file

@ -0,0 +1,204 @@
import os.path
import subprocess
import tempfile
from datetime import date, timedelta
from pathlib import Path
from django.conf import settings
from django.contrib.auth.models import Group, Permission
from django.core.files import File
from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils.text import slugify
from aemo.models import (
Bilan, Document, Famille, LibellePrestation, Personne, Role, Prestation,
Rapport, Utilisateur
)
from aemo.tests import InitialDataMixin, TempMediaRootMixin
from aemo.utils import format_d_m_Y
from ..models import Archive
public_key_path = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa.pub')
@override_settings(CRNE_RSA_PUBLIC_KEY=public_key_path)
class ArchiveTests(InitialDataMixin, TempMediaRootMixin, TestCase):
def setUp(self) -> None:
self.user = Utilisateur.objects.create_user('user', 'user@example.org', sigle='XX')
self.create_kwargs = {
'nom': 'John Doe',
'unite': 'aemo',
'date_debut': date(2021, 1, 1),
'date_fin': date(2021, 12, 31),
'motif_fin': 'Autre',
'key': '',
'pdf': 'encrypted_data'
}
def _create_archive(self):
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
fam.suivi.date_fin_suivi = date(2019, 1, 1)
fam.suivi.motif_fin_suivi = 'autres'
fam.suivi.save()
for idx, doc_name in enumerate(['sample.docx', 'sample.doc', 'sample.pdf', 'sample.msg']):
doc = Document(famille=fam, titre=f"Test {idx}")
with (Path(__file__).parent / doc_name).open(mode='rb') as fh:
doc.fichier = File(fh, name=doc_name)
doc.save()
self.user.user_permissions.add(Permission.objects.get(codename='can_archive'))
self.client.force_login(self.user)
self.client.post(reverse('archive-add', args=['aemo', fam.pk]))
return Archive.objects.get(nom='Haddock', unite='aemo')
def test_model_creation(self):
arch = Archive.objects.create(**self.create_kwargs)
self.assertEqual(arch.nom, 'John Doe')
self.assertEqual(arch.unite, 'aemo')
self.assertEqual(arch.date_debut, date(2021, 1, 1))
self.assertEqual(arch.date_fin, date(2021, 12, 31))
self.assertEqual(arch.pdf, 'encrypted_data')
def test_sans_permission_d_archiver(self):
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
fam.suivi.date_fin_suivi = date(2019, 1, 1)
fam.suivi.motif_fin_suivi = 'autre'
fam.suivi.save()
self.assertEqual(fam.can_be_archived(self.user), False)
def test_avec_permission_d_archiver(self):
fam = Famille.objects.create_famille(nom='Haddock', equipe='aemo')
fam.suivi.date_fin_suivi = date(2019, 1, 1)
fam.suivi.motif_fin_suivi = 'autre'
fam.suivi.save()
self.user.user_permissions.add(Permission.objects.get(codename='can_archive'))
self.assertEqual(fam.can_be_archived(self.user), True)
def test_archivage_aemo(self):
famille = Famille.objects.create_famille(
nom='Doe', equipe='aemo', rue="Rue du lac", npa='2000', localite='Paris', telephone='012 345 67 89')
famille.suivi.date_fin_suivi = date.today() - timedelta(days=700)
famille.suivi.motif_fin_suivi = 'autre'
famille.suivi.save()
file_paths = []
for idx, doc_name in enumerate(['sample.docx', 'sample.doc', 'sample.pdf', 'sample.msg', 'sample-2.msg']):
doc = Document(famille=famille, titre=f"Test {idx}")
with (Path(__file__).parent / doc_name).open(mode='rb') as fh:
doc.fichier = File(fh, name=doc_name)
doc.save()
file_paths.append(doc.fichier.path)
Personne.objects.create_personne(
famille=famille, prenom='Archibald', nom='Doe', role=Role.objects.get(nom='Père')
)
enfant = Personne.objects.create_personne(
famille=famille, prenom='Gaston', nom='Doe', date_naissance=date.today() - timedelta(days=720),
role=Role.objects.get(nom='Enfant suivi')
)
enfant.formation.creche = 'Les Schtroumpfs'
enfant.formation.save()
Bilan.objects.create(famille=famille, date=date.today())
Rapport.objects.create(famille=famille, date=date.today(), auteur=self.user)
prest = Prestation.objects.create(
famille=famille, auteur=self.user, date_prestation=date.today(), duree=timedelta(hours=2),
lib_prestation=LibellePrestation.objects.first())
prest.intervenants.add(self.user, through_defaults={'role': Role.objects.get(nom='Référent')})
with (Path(__file__).parent / 'sample.pdf').open(mode='rb') as fh:
prest.fichier = File(fh, name=doc_name)
prest.save()
file_paths.append(prest.fichier.path)
grp = Group.objects.get(name='aemo')
self.user.groups.add(grp)
self.user.user_permissions.add(
*list(Permission.objects.filter(codename__in=['view_famille', 'change_famille', 'can_archive']))
)
self.assertTrue(famille.can_be_archived(self.user))
self.client.force_login(self.user)
response = self.client.post(reverse('archive-add', args=['aemo', famille.pk]))
self.assertRedirects(response, reverse('suivis-termines'))
famille.refresh_from_db()
self.assertNotEqual(famille.nom, 'Doe')
self.assertEqual(len(famille.nom), 10)
self.assertEqual(famille.rue, '')
self.assertEqual(famille.npa, '2000')
self.assertEqual(famille.localite, 'Paris'),
self.assertEqual(famille.telephone, '')
self.assertEqual(famille.parents(), [])
enfant.refresh_from_db()
self.assertNotEqual(enfant.nom, 'Doe')
self.assertEqual(len(famille.nom), 10)
self.assertNotEqual(enfant.prenom, 'Gaston')
self.assertEqual(len(famille.nom), 10)
self.assertEqual(enfant.formation.creche, '')
self.assertEqual(famille.documents.count(), 0)
self.assertEqual(famille.bilans.count(), 0)
self.assertEqual(famille.rapports.count(), 0)
for prest in famille.prestations.all():
self.assertEqual(prest.texte, '')
self.assertEqual(prest.duree, timedelta(hours=2))
self.assertEqual(bool(prest.fichier), False)
for path in file_paths:
self.assertFalse(Path(path).exists())
arch = Archive.objects.get(nom='Doe', unite='aemo')
self.assertTrue(os.path.exists(arch.pdf.path))
self.assertIn(f"aemo/doe-{famille.pk}", arch.pdf.name)
self.assertTrue(famille.prestations.exists())
# Cannot be archived a second time:
response = self.client.post(reverse('archive-add', args=['aemo', famille.pk]))
self.assertEqual(response.status_code, 404)
def test_decryptage_access(self):
arch = self._create_archive()
private_key = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa')
anonymous = Utilisateur.objects.create_user('anonymous', email='anonymous@example.org')
self.client.force_login(anonymous)
with open(private_key, 'rb') as f:
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
self.assertEqual(response.status_code, 403)
anonymous.user_permissions.add(Permission.objects.get(codename='can_archive'))
self.client.force_login(anonymous)
with open(private_key, 'rb') as f:
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
self.assertEqual(response.status_code, 200)
def test_decryptage_aemo(self):
arch = self._create_archive()
private_key = os.path.join(settings.BASE_DIR, 'archive/tests/crne_rsa')
self.client.force_login(self.user)
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': ''})
self.assertEqual(response.context['form'].errors, {'file': ['Ce champ est obligatoire.']})
with open(private_key, 'rb') as f:
response = self.client.post(reverse('archive-decrypt', args=[arch.pk]), data={'file': f})
self.assertEqual(
response.get('Content-Disposition'),
f"attachment; filename={slugify(arch.nom)}.pdf"
)
with tempfile.NamedTemporaryFile(delete=True, mode='wb') as fh:
fh.write(response.content)
subprocess.run(['pdftotext', fh.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
with open(f'{fh.name}.txt', 'r') as f:
content = f.read()
self.assertIn('Historique', content)
self.assertIn('Fin du suivi le :\n\n01.01.2019', content)
self.assertIn('Motif de fin de suivi :\n\nAutres', content)
self.assertIn(f"Date d'archivage :\n\n{format_d_m_Y(date.today())}", content)
self.assertIn('Famille Haddock', content)
self.assertIn('Informations', content)
self.assertIn("Fichier docx dexemple", content)
self.assertIn("Exemple de fichier doc", content)
self.assertIn("Fichier pdf dexemple", content)
self.assertIn("Kind regards", content)