From ceaec313e009ed810f4e43e4719c828d6603d18d Mon Sep 17 00:00:00 2001
From: pfleu <pierre.fleutot@audemarspiguet.com>
Date: Mon, 2 Dec 2024 12:23:34 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20fonctionnlait=C3=A9=20modifier=20mot=20?=
 =?UTF-8?q?de=20passe=20depuis=20page=20profil?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/Controller/AppUserController.php    | 41 ++++++++++++++++--
 src/Form/EditPasswordType.php           | 55 +++++++++++++++++++++++++
 templates/user/changePassword.html.twig | 24 +++++++++++
 templates/user/index.html.twig          |  2 +-
 templates/user/showProfile.html.twig    |  9 ++--
 translations/messages+intl-icu.en.yaml  |  1 +
 translations/messages+intl-icu.fr.yaml  |  1 +
 7 files changed, 126 insertions(+), 7 deletions(-)
 create mode 100644 src/Form/EditPasswordType.php
 create mode 100644 templates/user/changePassword.html.twig

diff --git a/src/Controller/AppUserController.php b/src/Controller/AppUserController.php
index 53785dd..754325f 100644
--- a/src/Controller/AppUserController.php
+++ b/src/Controller/AppUserController.php
@@ -4,6 +4,7 @@ namespace App\Controller;
 
 use App\Entity\Entry;
 use App\Entity\User;
+use App\Form\EditPasswordType;
 use App\Form\UserAddFriendType;
 use App\Form\UserProfileFormType;
 use App\Form\UserType;
@@ -15,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Mailer\MailerInterface;
 use Symfony\Component\Mime\Email;
+use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
 use Symfony\Component\Routing\Annotation\Route;
 use Symfony\Component\Serializer\SerializerAwareInterface;
 use Symfony\Component\Serializer\SerializerInterface;
@@ -63,7 +65,7 @@ class AppUserController extends AbstractController
     }
 
     /**
-     * @Route("/edit-profil", name="user_edit_profile")
+     * @Route("/edit-profil", name="app_user_edit_profile")
      */
     public function editProfile(Request $request): Response
     {
@@ -89,13 +91,46 @@ class AppUserController extends AbstractController
     }
 
     /**
-     * @Route("/{id}/edit", name="user_edit", methods={"GET","POST"})
+     * @Route("/modifier-son-mot-de-passe", name="app_user_edit_own_password", methods={"GET","POST"})
+     */
+    public function editOwnPassword(Request $request, UserPasswordHasherInterface $passwordHasher)
+    {
+        $appUser = $this->getUser();
+
+        // On ne passe pas l'user au formulaire sinon quand on fait handleRequest, le mdp de l'user est modifié et ça le déconnecte
+        // Cela oblige à valider l'user à la main
+        $form = $this->createForm(EditPasswordType::class, null, [
+            'action' => $this->generateUrl('app_user_edit_own_password')
+        ]);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $plainPassword = $form->get('password')->getData();
+            $encodedPassword = $passwordHasher->hashPassword($appUser, $plainPassword);
+            $appUser->setPassword($encodedPassword);
+//            $appUser->setMustChangePassword(false);
+
+            $this->doctrine->getManager()->flush();
+            $this->addFlash('success',"Le mot de passe de a été modifié.");
+
+            return $this->redirectToRoute('app_user_profile', ['id' => $this->getUser()->getId()]);
+        }
+
+        return $this->render('user/changePassword.html.twig', [
+            'title' => "Modifier le mot de passe",
+            'user' => $appUser,
+            'form' => $form->createView(),
+        ]);
+    }
+
+    /**
+     * @Route("/{id}/edit", name="app_user_edit", methods={"GET","POST"})
      * @IsGranted("ROLE_ADMIN")
      */
     public function edit(Request $request, User $appUser): Response
     {
         $form = $this->createForm(UserType::class, $appUser, [
-            'action' => $this->generateUrl('user_edit', ['id' => $appUser->getId()])
+            'action' => $this->generateUrl('app_user_edit', ['id' => $appUser->getId()])
         ]);
         $form->handleRequest($request);
 
diff --git a/src/Form/EditPasswordType.php b/src/Form/EditPasswordType.php
new file mode 100644
index 0000000..5606c91
--- /dev/null
+++ b/src/Form/EditPasswordType.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Form;
+
+use App\Entity\User;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Validator\Constraints\Length;
+use Symfony\Bridge\Doctrine\Form\Type\EntityType;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+use Symfony\Component\Form\Extension\Core\Type\PasswordType;
+use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\FormError;
+use Symfony\Component\Form\FormEvent;
+use Symfony\Component\Form\FormEvents;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints\Regex;
+
+class EditPasswordType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('password', RepeatedType::class, [
+                'type' => PasswordType::class,
+                'invalid_message' => 'Les mots de passe ne correspondent pas.',
+                'options' => ['attr' => ['class' => 'password-field']],
+                'required' => true,
+                'first_options'  => ['data' => null, 'attr' => ['autocomplete' => 'new-password'], 'label' => 'Mot de passe'],
+                'second_options' => ['attr' => ['autocomplete' => 'new-password'], 'label' => 'Répétez le mot de passe'],
+                'constraints' => [
+                    new NotBlank(),
+                    new Length(['min' => 8, 'minMessage' => "Votre mot de passe doit comporter au moins 8 caractères"]),
+                    new Regex(['pattern' => "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])/", 'message' => "Votre mot de passe doit comporter au moins une majuscule, une minuscule et un chiffre."]),
+                ],
+            ])
+            ->add('submit', SubmitType::class, array(
+                'label' => 'Enregistrer',
+                'attr' => ['class' => 'btn-primary btn-gradient']
+            ));
+    }
+
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults([
+//            'data_class' => User::class,
+            'attr' => [
+                'novalidate' => 'novalidate',
+                'autocomplete' => 'off',
+            ],
+        ]);
+    }
+}
diff --git a/templates/user/changePassword.html.twig b/templates/user/changePassword.html.twig
new file mode 100644
index 0000000..901a769
--- /dev/null
+++ b/templates/user/changePassword.html.twig
@@ -0,0 +1,24 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}Register{% endblock %}
+
+{% block body %}
+
+    <div class="row justify-content-center mt-5">
+        <div class="col-md-8">
+            <h3 class="card-title">{{"user.edit_password"|trans}}</h3>
+            <div class="card mt-3">
+                <div class="card-body">
+
+                    {{ form_start(form) }}
+                    {{ form_row(form.password) }}
+                    <p class="text-center mt-5">{{ form_widget(form.submit) }}</p>
+                    {{ form_end(form) }}
+
+{#                    <div class="alert alert-warning mt-5">{{ "Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et un chiffre."|trans }}</div>#}
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/templates/user/index.html.twig b/templates/user/index.html.twig
index adfd5c1..9368836 100644
--- a/templates/user/index.html.twig
+++ b/templates/user/index.html.twig
@@ -51,7 +51,7 @@
                                         {% endif %}
                                     </td>
                                     <td class="text-nowrap">
-                                        <a href="#" data-url="{{ path('user_edit', {'id': user.id}) }}" class="btn btn-secondary btn-xs modal-form"><i class="fa fa-pencil"></i></a>
+                                        <a href="#" data-url="{{ path('app_user_edit', {'id': user.id}) }}" class="btn btn-secondary btn-xs modal-form"><i class="fa fa-pencil"></i></a>
                                         <a data-confirm="{{ "Confirmer la suppression ?"|trans }}" data-bs-toggle="modal" data-bs-target="#confirm-dialog"
                                            data-href="{{ path('app_user_delete', {id: user.id}) }}" class="btn btn-xs btn-danger"><i class="bi-x-circle"></i></a>
                                     </td>
diff --git a/templates/user/showProfile.html.twig b/templates/user/showProfile.html.twig
index c57717d..a6652cb 100644
--- a/templates/user/showProfile.html.twig
+++ b/templates/user/showProfile.html.twig
@@ -13,9 +13,12 @@
 
             <h3 class="card-title d-flex justify-content-between">
                 {{ "Profil"|trans }}
-                <a href="{{ path('user_edit_profile') }}" class="btn btn-dark">
-                    {{ "Modifier"|trans }}
-                </a>
+                <div>
+                    <a href="{{ path('app_user_edit_own_password') }}" class="btn btn-primary btn-gradient"> {{ "Modifier mon mon de passe"|trans }}</a>
+                    <a href="{{ path('app_user_edit_profile') }}" class="btn btn-dark">
+                        {{ "Modifier"|trans }}
+                    </a>
+                </div>
             </h3>
             <div class="card mt-3">
                 <div class="card-body">
diff --git a/translations/messages+intl-icu.en.yaml b/translations/messages+intl-icu.en.yaml
index 6588adc..67c9606 100644
--- a/translations/messages+intl-icu.en.yaml
+++ b/translations/messages+intl-icu.en.yaml
@@ -179,6 +179,7 @@ Altruiste: Altruist
 'Nombre de messages écrits dans les discussions de groupe': 'Number of messages written in group discussions'
 'Commentateur sportif': 'Mighty commentator'
 'Nombre de commentaires écrits dans les entrées': 'Number of comments written in entries'
+user.edit_password: Change password
 user_profile.email: Email
 user_profile.native_language: 'Native Language'
 user_profile.app_language: 'App Language'
diff --git a/translations/messages+intl-icu.fr.yaml b/translations/messages+intl-icu.fr.yaml
index 4535b24..dd06869 100644
--- a/translations/messages+intl-icu.fr.yaml
+++ b/translations/messages+intl-icu.fr.yaml
@@ -20,6 +20,7 @@ Pronunciations: Prononciation
 Examples: Exemple
 PartOfSpeech: Nature
 Comments: Commentaire
+user.edit_password: Modifier le mot de passe
 user_profile.email: Email
 user_profile.native_language: 'Langue native'
 user_profile.app_language: 'Langue interface'
-- 
GitLab