Skip to content

Commit

Permalink
Merge pull request #789 from MTES-MCT/feature/788-form-logement-const…
Browse files Browse the repository at this point in the history
…raint-1

[Sécurité] Contrôle des entrées du formulaire "Dans mon logement" pour les champs ajouté via le SignalementFrontType
  • Loading branch information
hmeneuvrier authored Sep 27, 2024
2 parents 2fd35ce + e550d8e commit 140d5f3
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 70 deletions.
4 changes: 2 additions & 2 deletions assets/controllers/form_signalement_front.js
Original file line number Diff line number Diff line change
Expand Up @@ -849,9 +849,9 @@ class PunaisesFrontSignalementController {
self.refreshStep(nbStep);
},
error: function (xhr, desc, err) {
console.log(xhr);
if (xhr.responseJSON != undefined) {
alert("Erreur lors de l'ajout du signalement (" + xhr.responseJSON.errors[0].message + ")");
const errorValues = Object.values(xhr.responseJSON.errors);
alert("Erreur lors de l'ajout du signalement (" + errorValues[0].errors[0] + ")");
} else {
alert("Erreur lors de l'ajout du signalement");
}
Expand Down
27 changes: 12 additions & 15 deletions src/Controller/Front/SignalementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Manager\SignalementManager;
use App\Repository\EntrepriseRepository;
use App\Repository\TerritoireRepository;
use App\Service\FormHelper;
use App\Service\Mailer\MailerProvider;
use App\Service\Signalement\GeolocateService;
use App\Service\Signalement\ReferenceGenerator;
Expand Down Expand Up @@ -65,11 +66,10 @@ public function save(
GeolocateService $geolocateService,
): Response {
$signalement = new Signalement();
$form = $this->createForm(SignalementFrontType::class, $signalement, ['validation_groups' => 'front_add_signalement_logement']);
$form = $this->createForm(SignalementFrontType::class, $signalement);
$form->handleRequest($request);

$submittedToken = $request->request->get('_csrf_token');
if ($form->isValid() && $this->isCsrfTokenValid('front-add-signalement', $submittedToken)) {
if ($form->isValid()) {
$signalement
->setType(SignalementType::TYPE_LOGEMENT)
->setReference($referenceGenerator->generate())
Expand All @@ -79,19 +79,15 @@ public function save(
$filesPosted = $request->files->get('file-upload');
$filesToSave = $uploadHandlerService->handleUploadFilesRequest($filesPosted);
$signalement->setPhotos($filesToSave);
$geolocateService->geolocate($signalement);

if ([] === $signalement->getGeoloc()) {
$geolocateService->geolocate($signalement);
}
if (null !== $signalement->getCodePostal()) {
$zipCode = $zipCodeService->getByCodePostal($signalement->getCodePostal());
$territoire = $territoireRepository->findOneBy(['zip' => $zipCode]);
$signalement->setTerritoire($territoire);

$signalementManager->save($signalement);
} else {
return $this->json(['response' => 'error', 'errors' => 'code postal null'], Response::HTTP_BAD_REQUEST);
$zipCode = $zipCodeService->getByCodePostal($signalement->getCodePostal());
$territoire = $territoireRepository->findOneBy(['zip' => $zipCode]);
if (!$territoire) {
return $this->json(['response' => 'error', 'errors' => 'territoire introuvable sur le code postal '.$signalement->getCodePostal()], Response::HTTP_BAD_REQUEST);
}
$signalement->setTerritoire($territoire);
$signalementManager->save($signalement);

if ($signalement->isAutotraitement()) {
if ($signalement->getTerritoire()->isActive()) {
Expand Down Expand Up @@ -123,7 +119,8 @@ public function save(

return $this->json(['response' => 'success']);
}
$errors = FormHelper::getErrorsFromForm($form);

return $this->json(['response' => 'error', 'errors' => $form->getErrors(true)], Response::HTTP_BAD_REQUEST);
return $this->json(['response' => 'error', 'errors' => $errors], Response::HTTP_BAD_REQUEST);
}
}
52 changes: 51 additions & 1 deletion src/Entity/Signalement.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,30 @@ class Signalement
private ?string $uuid = null;

#[ORM\Column(length: 255, nullable: true)]
#[Assert\Length(max: 255)]
#[Assert\NotBlank(
message: 'Veuillez renseigner une adresse.',
groups: ['front_add_signalement_logement']
)]
private ?string $adresse = null;

#[ORM\Column(length: 10)]
#[Assert\NotBlank(
message: 'Veuillez renseigner le code postal.',
groups: ['front_add_signalement_logement']
)]
#[Assert\Regex(
pattern: '/^[0-9]{5}$/',
message: 'Veuillez utiliser un code postal valide',
)]
private ?string $codePostal = null;

#[ORM\Column(length: 255, nullable: true)]
#[Assert\Length(max: 255)]
#[Assert\NotBlank(
message: 'Veuillez renseigner la ville.',
groups: ['front_add_signalement_logement']
)]
private ?string $ville = null;

#[ORM\Column(length: 20, nullable: true)]
Expand All @@ -47,13 +65,15 @@ class Signalement
private ?bool $construitAvant1948 = null;

#[ORM\Column(length: 50, nullable: true)]
#[Assert\Length(max: 50)]
#[Assert\NotBlank(
message: 'Veuillez renseigner votre nom.',
groups: ['front_add_signalement_logement', 'back_add_signalement_logement']
)]
private ?string $nomOccupant = null;

#[ORM\Column(length: 50, nullable: true)]
#[Assert\Length(max: 50)]
#[Assert\NotBlank(
message: 'Veuillez renseigner votre prenom.',
groups: ['front_add_signalement_logement', 'back_add_signalement_logement']
Expand All @@ -66,11 +86,20 @@ class Signalement
match: true,
message: 'Merci de saisir le numéro de téléphone au bon format'
)]
#[Assert\NotBlank(
message: 'Veuillez renseigner votre numéro de téléphone.',
groups: ['front_add_signalement_logement']
)]
private ?string $telephoneOccupant = null;

#[ORM\Column(length: 100, nullable: true)]
#[Assert\Length(max: 100)]
#[Assert\Email]
#[Assert\NotBlank(message: 'Veuillez renseigner votre email.', groups: ['front_add_signalement_logement'])]
#[Assert\NotBlank(message: 'Veuillez renseigner votre e-mail.', groups: ['front_add_signalement_logement'])]
#[Assert\Email(
message: 'Veuillez renseigner une adresse e-mail valide.',
groups: ['front_add_signalement_logement']
)]
private ?string $emailOccupant = null;

#[ORM\Column(length: 30, nullable: true)]
Expand All @@ -80,6 +109,16 @@ class Signalement
private ?\DateTimeInterface $dateIntervention = null;

#[ORM\Column(type: Types::SMALLINT, nullable: true)]
#[Assert\Range(
min: 0,
max: 4,
notInRangeMessage: 'Le niveau d\'infestation doit être compris entre 1 et 4.',
groups: ['front_add_signalement_logement']
)]
#[Assert\NotBlank(
message: 'Veuillez renseigner un niveau d\'infestation.',
groups: ['front_add_signalement_logement']
)]
private ?int $niveauInfestation = null;

#[ORM\Column(type: Types::JSON, nullable: true)]
Expand Down Expand Up @@ -113,6 +152,7 @@ class Signalement
private ?string $localisationDansImmeuble = null;

#[ORM\Column(length: 10, nullable: true)]
#[Assert\Regex(pattern: '/^[0-9][0-9A-Za-z][0-9]{3}$/', message: 'Le code insee doit être composé de 5 caractères.')]
private ?string $codeInsee = null;

#[ORM\ManyToOne(inversedBy: 'signalements')]
Expand All @@ -128,6 +168,14 @@ class Signalement
private ?bool $autotraitement = null;

#[ORM\Column(type: Types::SMALLINT, nullable: true)]
#[Assert\NotBlank(
message: 'Veuillez renseigner une superficie.',
groups: ['front_add_signalement_logement']
)]
#[Assert\Regex(
pattern: '/^[0-9]{1,5}$/',
message: 'Veuillez renseigner une superficie valide',
)]
private ?int $superficie = null;

#[ORM\Column(length: 20, nullable: true)]
Expand Down Expand Up @@ -164,6 +212,7 @@ class Signalement
private ?bool $locataire = null;

#[ORM\Column(length: 100, nullable: true)]
#[Assert\Length(max: 100)]
private ?string $nomProprietaire = null;

#[ORM\Column(nullable: true)]
Expand All @@ -173,6 +222,7 @@ class Signalement
private ?bool $allocataire = null;

#[ORM\Column(length: 50, nullable: true)]
#[Assert\Length(max: 50)]
private ?string $numeroAllocataire = null;

#[ORM\Column(nullable: true)]
Expand Down
45 changes: 2 additions & 43 deletions src/Form/SignalementFrontType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use App\Entity\Signalement;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
Expand All @@ -15,8 +14,6 @@
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\Email;

class SignalementFrontType extends AbstractType
{
Expand Down Expand Up @@ -56,10 +53,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
],
'label' => 'La superficie de mon logement est de…',
'required' => true,
'constraints' => [
new Assert\NotBlank(message: 'Veuillez renseigner une superficie'),
new Assert\Regex('/[0-9]{5}/', 'Veuillez renseigner une superficie valide'),
],
])
->add('adresse', TextType::class, [
'attr' => [
Expand Down Expand Up @@ -89,10 +82,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'class' => 'fr-hint-text',
],
'required' => true,
'constraints' => [
new Assert\NotBlank(message: 'Veuillez renseigner le code postal'),
new Assert\Regex('/[0-9]{5}/', 'Veuillez utiliser un code postal valide'),
],
])
->add('codeInsee', HiddenType::class, [
'attr' => [
Expand All @@ -117,8 +106,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'class' => 'fr-hidden',
],
'required' => false,
'mapped' => false,
])

// Step info_locataire
->add('locataire', ChoiceType::class, [
'attr' => [
Expand Down Expand Up @@ -323,9 +312,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'class' => 'fr-hint-text',
],
'required' => false,
'constraints' => [
new Assert\Regex('/[0-9]{10}/', 'Veuillez renseigner un numéro de téléphone valide'),
],
])
->add('emailOccupant', EmailType::class, [
'attr' => [
Expand All @@ -342,12 +328,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'class' => 'fr-hint-text',
],
'required' => false,
'constraints' => [
new Email(
mode: Email::VALIDATION_MODE_STRICT,
message: 'Veuillez renseigner un email valide.'
),
],
])
->add('autotraitement', HiddenType::class, [
'attr' => [
Expand All @@ -356,27 +336,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'empty_data' => false,
])
;
$builder->get('geoloc')->addModelTransformer(new CallbackTransformer(
function ($tagsAsArray) {
// transform the array to a string
if (!empty($tagsAsArray)) {
return $tagsAsArray[0].'|'.$tagsAsArray[1];
}

return '';
},
function ($tagsAsString) {
// transform the string back to an array
if (!empty($tagsAsString)) {
$coord = explode('|', $tagsAsString);

return ['lat' => $coord[0], 'lng' => $coord[1]];
}

return [];
}
));

$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
/** @var Signalement $signalement */
$signalement = $event->getData();
Expand Down Expand Up @@ -404,8 +363,8 @@ public function configureOptions(OptionsResolver $resolver): void
$resolver->setDefaults([
'data_class' => Signalement::class,
'allow_extra_fields' => true,
'csrf_protection' => false,
'validation_groups' => ['Default', 'front_add_signalement_logement'],
'csrf_token_id' => 'signalement_front',
]);
}

Expand Down
31 changes: 31 additions & 0 deletions src/Service/FormHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Service;

use Symfony\Component\Form\FormInterface;

class FormHelper
{
public static function getErrorsFromForm(FormInterface $form, $recursive = false): array
{
$errors = [];
foreach ($form->getErrors() as $error) {
if ($recursive) {
$errors[] = $error->getMessage();
} else {
$errors['__nopath__']['errors'][] = $error->getMessage();
}
}
foreach ($form->all() as $childForm) {
if ($childForm instanceof FormInterface) {
if ($childErrors = self::getErrorsFromForm($childForm, true)) {
foreach ($childErrors as $childError) {
$errors[$childForm->getName()]['errors'][] = $childError;
}
}
}
}

return $errors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<span class="fr-text--bold">Étape suivante :</span> Durée de l'infestation
</p>
</div>

{{ form_widget(form._token) }}
{{ forms.radio_choice(form.typeLogement, 'Veuillez renseigner le type de logement.') }}

<div class="fr-form-group">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@

{{ form_widget(form.autotraitement) }}

<input type="hidden" name="_csrf_token" value="{{ csrf_token('front-add-signalement') }}">

<div class="if-logement-social">
{% include 'front_signalement/_partial_signalement_navigation_container.html.twig' with {'next': 'Recevoir le protocole', 'previous': 'Retour' } %}
</div>
Expand Down
Loading

0 comments on commit 140d5f3

Please sign in to comment.