From a959c3e1d7a0902ef3b67e80d439700f28289444 Mon Sep 17 00:00:00 2001
From: Argann Bonneau <argann.b@hotmail.fr>
Date: Fri, 24 Feb 2017 17:26:53 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20cr=C3=A9ation=20de=20compte?=
 =?UTF-8?q?=20+=20messages=20d'erreurs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/Resources/views/security/login.html.twig  | 19 +++--
 app/Resources/views/security/signin.html.twig | 82 +++++++++++--------
 .../views/theme/form_errors.html.twig         |  9 ++
 app/config/config.yml                         |  2 +
 app/config/security.yml                       |  1 +
 .../Controller/SecurityController.php         | 30 ++++++-
 src/AppBundle/Entity/Utilisateur.php          | 34 +++++++-
 src/AppBundle/Entity/Utilisateur.php~         | 29 +++++--
 src/AppBundle/Form/UtilisateurType.php        | 40 +++++++++
 9 files changed, 191 insertions(+), 55 deletions(-)
 create mode 100644 app/Resources/views/theme/form_errors.html.twig
 create mode 100644 src/AppBundle/Form/UtilisateurType.php

diff --git a/app/Resources/views/security/login.html.twig b/app/Resources/views/security/login.html.twig
index 30e461a..6f65238 100644
--- a/app/Resources/views/security/login.html.twig
+++ b/app/Resources/views/security/login.html.twig
@@ -8,7 +8,7 @@
 
     {% if error %}
         <div class="row">
-            <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
+            <div class="col-md-offset-4 col-md-4 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
                 <div class="alert alert-danger" role="alert">
                     {{ error.messageKey|trans(error.messageData, 'security') }}
                 </div>
@@ -16,6 +16,16 @@
         </div>
     {% endif %}
 
+    {% if success %}
+        <div class="row">
+            <div class="col-md-offset-4 col-md-4 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
+                <div class="alert alert-success" role="alert">
+                    Votre compte est désormais créé. Vous pouvez vous connecter en tapant vos identifiants.
+                </div>
+            </div>
+        </div>
+    {% endif %}
+
 
     <div class="row">
         <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
@@ -26,18 +36,17 @@
                 <div class="panel-body">
                     <form action="{{ path("login") }}" method="post">
                         <div class="form-group">
-                            <label for="username">Username:</label>
+                            <label for="username">Pseudonyme:</label>
                             <input type="text" id="username" name="_username" value="{{ last_username }}" />
                         </div>
                         <div class="form-group">
-                            <label for="password">Password:</label>
+                            <label for="password">Mot de passe:</label>
                             <input type="password" id="password" name="_password" />
                         </div>
                         <div class="form-group">
                             <input type="checkbox" id="remember_me" name="_remember_me" checked />
                             <label for="remember_me">Se souvenir de moi</label>
                         </div>
-                        <input type="hidden" name="_target_path" value="/profil" />
                         <input class="btn btn-primary" type="submit" value="Se connecter">
                     </form>
                 </div>
@@ -48,7 +57,7 @@
 
     <div class="row">
         <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
-            <a href="/signin" class="btn btn-default">Se créer un compte</a>
+            <a href="{{ path("signin") }}" class="btn btn-default">Se créer un compte</a>
         </div>
     </div>
 
diff --git a/app/Resources/views/security/signin.html.twig b/app/Resources/views/security/signin.html.twig
index 36740a7..dc0c975 100644
--- a/app/Resources/views/security/signin.html.twig
+++ b/app/Resources/views/security/signin.html.twig
@@ -1,45 +1,55 @@
 {% extends "base.html.twig" %}
 
+{% use 'navbars/public-navbar.html.twig' %}
+
+{% block title %}Créer un compte{% endblock %}
+
 {% block body %}
-    <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
-        <label>Création de compte</label>
-        <div class="form-group">
-            <label for="identifiant">Identifiant</label>
-            <input type="text" class="form-control" id="identifiant" placeholder="Identifiant">
-        </div>
-        <div class="form-group">
-            <label for="prenom">Prénom</label>
-            <input type="text" class="form-control" id="prenom" placeholder="Prénom">
-        </div>
-        <div class="form-group">
-            <label for="nom">Nom</label>
-            <input type="text" class="form-control" id="nom" placeholder="Nom">
-        </div>
-        <div class="form-group">
-            <label for="date-naissance">Date de naissance</label>
-            <input type="datetime" class="form-control" id="date-naissance" placeholder="Date de naissance">
-        </div>
-        <div class="form-group">
-            <label for="email">Adresse e-mail</label>
-            <input type="email" class="form-control" id="email" placeholder="Email">
-        </div>
+    {{ form_start(form) }}
 
-        <div class="form-group">
-            <label for="password">Mot de passe</label>
-            <input type="password" class="form-control" id="password" placeholder="Mot de passe">
+    {% if not form.vars.valid %}
+    <div class="row">
+        <div class="col-md-offset-4 col-md-4 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
+            <div class="alert alert-danger" role="alert">
+                Il y a quelques erreurs dans le formulaire : {{ form_errors(form) }}
+            </div>
         </div>
-        <div class="form-group">
-            <label for="password-check">Confirmer le mot de passe</label>
-            <input type="password" class="form-control" id="password-check" placeholder="Mot de passe">
-        </div>
-        <div class="form-group">
-            <label for="entreprise">Entreprise</label>
-            <input type="text" class="form-control" id="entreprise" placeholder="Entreprise">
+    </div>
+    {% endif %}
+
+    <div class="row">
+        <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
+            <div class="panel panel-default">
+                <div class="panel-heading">
+                    <h3>Créer un compte</h3>
+                </div>
+                <div class="panel-body">
+                    <div class="form-group">
+                        {{ form_errors(form.pseudonyme) }}
+                        {{ form_label(form.pseudonyme, 'Pseudonyme') }}
+                        {{ form_widget(form.pseudonyme) }}
+                    </div>
+                    <div class="form-group">
+                        {{ form_errors(form.motDePasseEnClair.first) }}
+                        {{ form_label(form.motDePasseEnClair.first, 'Mot de passe') }}
+                        {{ form_widget(form.motDePasseEnClair.first) }}
+                    </div>
+                    <div class="form-group">
+                        {{ form_errors(form.motDePasseEnClair.second) }}
+                        {{ form_label(form.motDePasseEnClair.second) }}
+                        {{ form_widget(form.motDePasseEnClair.second) }}
+                    </div>
+                    {{ form_widget(form.creer, {'attr': {'class': 'btn btn-primary'}}) }}
+                </div>
+            </div>
         </div>
-        <div class="form-group">
-            <label for="profession">Profession</label>
-            <input type="text" class="form-control" id="profession" placeholder="Profession">
+    </div>
+    {{ form_end(form) }}
+
+
+    <div class="row">
+        <div class="col-md-offset-5 col-md-2 col-sm-offset-3 col-sm-4 col-xs-8 col-xs-offset-2 text-center">
+            <a href="{{ path("login") }}" class="btn btn-default">Se connecter</a>
         </div>
-        <input class="btn btn-default" type="submit" value="Créer le compte">
     </div>
 {% endblock %}
diff --git a/app/Resources/views/theme/form_errors.html.twig b/app/Resources/views/theme/form_errors.html.twig
new file mode 100644
index 0000000..6ff11f9
--- /dev/null
+++ b/app/Resources/views/theme/form_errors.html.twig
@@ -0,0 +1,9 @@
+{% block form_errors %}
+    {% spaceless %}
+        {% if errors|length > 0 %}
+            {% for error in errors %}
+                <p><span class="label label-danger">{{ error.message }}</span></p>
+            {% endfor %}
+        {% endif %}
+    {% endspaceless %}
+{% endblock form_errors %}
\ No newline at end of file
diff --git a/app/config/config.yml b/app/config/config.yml
index cfb0391..db3f1bc 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -36,6 +36,8 @@ framework:
 
 # Twig Configuration
 twig:
+    form_themes:
+        - 'theme/form_errors.html.twig'
     debug:            "%kernel.debug%"
     strict_variables: "%kernel.debug%"
 
diff --git a/app/config/security.yml b/app/config/security.yml
index 70afeb9..2c65f27 100644
--- a/app/config/security.yml
+++ b/app/config/security.yml
@@ -32,6 +32,7 @@ security:
             form_login:
                 login_path: login
                 check_path: login
+                default_target_path: profil
 
     access_control:
         # require ROLE_ADMIN for /admin*
diff --git a/src/AppBundle/Controller/SecurityController.php b/src/AppBundle/Controller/SecurityController.php
index af973fe..e9d894a 100644
--- a/src/AppBundle/Controller/SecurityController.php
+++ b/src/AppBundle/Controller/SecurityController.php
@@ -2,6 +2,8 @@
 
 namespace AppBundle\Controller;
 
+use AppBundle\Entity\Utilisateur;
+use AppBundle\Form\UtilisateurType;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@@ -13,7 +15,7 @@ class SecurityController extends Controller
     */
     public function loginAction(Request $request){
 
-        //TODO : Load Users from Database (http://symfony.com/doc/current/security/entity_provider.html)
+        $success = $request->query->get("ac") == "1" ? true : null;
 
         $authenticationUtils = $this->get('security.authentication_utils');
 
@@ -26,6 +28,7 @@ class SecurityController extends Controller
         return $this->render('security/login.html.twig', array(
             'last_username' => $lastUsername,
             'error'         => $error,
+            'success'       => $success,
         ));
     }
     
@@ -33,8 +36,27 @@ class SecurityController extends Controller
     * @Route("/signin", name="signin")
     */
     public function signinAction(Request $request){
-        
-        
-        return $this->render('security/signin.html.twig');
+        $user = new Utilisateur();
+
+        $form = $this->createForm(UtilisateurType::class, $user);
+
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+
+            $password = $this->get('security.password_encoder')
+                ->encodePassword($user, $user->getMotDePasseEnClair());
+            $user->setMotDePasse($password);
+
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($user);
+            $em->flush();
+
+            return $this->redirectToRoute('login', array('ac' => "1"));
+        }
+
+        return $this->render('security/signin.html.twig', array(
+            'form' => $form->createView(),
+        ));
     }
 }
diff --git a/src/AppBundle/Entity/Utilisateur.php b/src/AppBundle/Entity/Utilisateur.php
index 601a73d..012cc56 100644
--- a/src/AppBundle/Entity/Utilisateur.php
+++ b/src/AppBundle/Entity/Utilisateur.php
@@ -4,12 +4,17 @@ namespace AppBundle\Entity;
 
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
 
 /**
  * Utilisateur
  *
  * @ORM\Table(name="utilisateur")
  * @ORM\Entity(repositoryClass="AppBundle\Repository\UtilisateurRepository")
+ * @UniqueEntity("pseudonyme",
+ *     message="Ce pseudonyme existe déjà."
+ * )
  */
 class Utilisateur implements UserInterface, \Serializable
 {
@@ -26,16 +31,43 @@ class Utilisateur implements UserInterface, \Serializable
      * @var string
      *
      * @ORM\Column(name="pseudonyme", type="string", length=25, unique=true)
+     * @Assert\NotBlank(
+     *     message = "Vous devez renseigner un pseudonyme."
+     * )
      */
     private $pseudonyme;
 
     /**
      * @var string
      *
-     * @ORM\Column(name="motDePasse", type="string", length=255)
+     * @ORM\Column(name="motDePasse", type="string", length=64)
      */
     private $motDePasse;
 
+    /**
+     * @Assert\NotBlank(
+     *     message = "Vous devez renseigner un mot de passe."
+     * )
+     * @Assert\Length(max=4096)
+     */
+    private $motDePasseEnClair;
+
+    /**
+     * @return mixed
+     */
+    public function getMotDePasseEnClair()
+    {
+        return $this->motDePasseEnClair;
+    }
+
+    /**
+     * @param mixed $motDePasseEnClair
+     */
+    public function setMotDePasseEnClair($motDePasseEnClair)
+    {
+        $this->motDePasseEnClair = $motDePasseEnClair;
+    }
+
     /**
      * @ORM\OneToMany(targetEntity="UtilisateurReponse", mappedBy="utilisateur")
      */
diff --git a/src/AppBundle/Entity/Utilisateur.php~ b/src/AppBundle/Entity/Utilisateur.php~
index d9a7733..938be6d 100644
--- a/src/AppBundle/Entity/Utilisateur.php~
+++ b/src/AppBundle/Entity/Utilisateur.php~
@@ -4,6 +4,7 @@ namespace AppBundle\Entity;
 
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * Utilisateur
@@ -26,16 +27,34 @@ class Utilisateur implements UserInterface, \Serializable
      * @var string
      *
      * @ORM\Column(name="pseudonyme", type="string", length=25, unique=true)
+     * @Assert\NotBlank(
+     *     message = "Vous devez renseigner un pseudonyme."
+     * )
+     * @Assert\NotNull(
+     *     message = "Vous devez renseigner un pseudonyme."
+     * )
      */
     private $pseudonyme;
 
     /**
      * @var string
      *
-     * @ORM\Column(name="motDePasse", type="string", length=255)
+     * @ORM\Column(name="motDePasse", type="string", length=64)
+     * @Assert\NotBlank(
+     *     message = "Vous devez renseigner un mot de passe."
+     * )
+     * @Assert\NotNull(
+     *     message = "Vous devez renseigner un mot de passe."
+     * )
      */
     private $motDePasse;
 
+    /**
+     * @Assert\NotBlank()
+     * @Assert\Length(max=4096)
+     */
+    private $motDePasseEnClair;
+
     /**
      * @ORM\OneToMany(targetEntity="UtilisateurReponse", mappedBy="utilisateur")
      */
@@ -147,8 +166,6 @@ class Utilisateur implements UserInterface, \Serializable
 
     public function getSalt()
     {
-        // you *may* need a real salt depending on your encoder
-        // see section on salt below
         return null;
     }
 
@@ -173,9 +190,6 @@ class Utilisateur implements UserInterface, \Serializable
             $this->id,
             $this->motDePasse,
             $this->pseudonyme,
-            $this->reponses,
-            // see section on salt below
-            // $this->salt,
         ));
     }
 
@@ -186,9 +200,6 @@ class Utilisateur implements UserInterface, \Serializable
             $this->id,
             $this->motDePasse,
             $this->pseudonyme,
-            $this->reponses,
-            // see section on salt below
-            // $this->salt
             ) = unserialize($serialized);
     }
 }
diff --git a/src/AppBundle/Form/UtilisateurType.php b/src/AppBundle/Form/UtilisateurType.php
new file mode 100644
index 0000000..9df5cda
--- /dev/null
+++ b/src/AppBundle/Form/UtilisateurType.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace AppBundle\Form;
+
+use AppBundle\Entity\Utilisateur;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\PasswordType;
+use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class UtilisateurType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('pseudonyme',TextType::class, array('required' => true))
+            ->add('motDePasseEnClair', RepeatedType::class, array(
+                'type' => PasswordType::class,
+                'first_options'  => array('label' => 'Mot de Passe'),
+                'second_options' => array('label' => 'Répétez le Mot de Passe'),
+                'invalid_message' => 'Mots de passe différents.'
+            ))
+            ->add('creer', SubmitType::class);
+    }
+
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults(array(
+           'data_class' => Utilisateur::class,
+        ));
+    }
+
+    public function getName()
+    {
+        return 'app_bundle_utilisateur_type';
+    }
+}
-- 
GitLab