Modifier son mot de passe

On va utiliser le groupes de validation. Ainsi on pourra choisir quelles validations vérifier en fonction de ce qu'on envoie dans le payload.

Dans notre entité User on rajoute l'attribut suivant

 *       itemOperations={
 *           "get",
 *           "put"={
 *               "validation_groups"={User::class, "validationGroups"},
 *               "security"="object === user",
 *               "denormalization_context"={"groups"={"user:item:put"}},
 *           },
 *           "delete"
 *      }

On va avoir besoin de put mais j'ai également mis get et delete sinon ils ne sont plus accessible.

Avec la condition object === user on est assuré que seul l'utilisateur connecté peut modifier son mot de passe.

Nous avons crée un nouveau groupe de serialization : user:item:put. On va indiquer les attributs qu'on peut modifier. Dans notre cas ça sera currentPassword et password

  • On a besoin du mot de passe actuel
  • On a besoin du nouveau mot de passe

Toujours dans l'entité User on rajoute l'attribut avec son getter et setter :

/**
 * @Groups("user:item:put")
 * @SecurityAssert\UserPassword(
 *     message = "Votre mot de passe actuel n'est pas correct.",
 *     groups = "update-password"
 * )
 */
private $currentPassword;

// ...

public function getCurrentPassword(): ?string
{
    return $this->currentPassword;
}

public function setCurrentPassword(?string $currentPassword): self
{
    $this->currentPassword = $currentPassword;

    return $this;
}

L'annotation SecurityAssert\UserPassword demande le mot de passe de l'utilisateur. Cette validation est dans le groupe update-password que nous avons déclarer sur la route put

@Groups("user:item:put") indique qu'on peut écrire sur cet attribut uniquement quand on utilise le verbe put

Toujours dans l'entité User on va rajouter la méthode validationGroups qui est appelé quand on fait une opération put

validation groups update password

validationGroups correspond au nom de la méthode (donc vous pouvez en avoir plusieurs sur la même entité) et dans notre cas son attribut self $user correspond à l'entité sur laquelle nous somme

class User implements UserInterface
{
    public static function validationGroups(self $user)
    {
        if ($user->getCurrentPassword() !== null || $user->getPlainPassword() !== null) {
            return ["update-password"];
        }

        return [""];
    }

Cette méthode surveille si on envoie currentPassword ou password (qui est plainPassword car on utilise @SerializedName("password")) dans notre payload. Si c'est le cas on est dans le groupe de validation update-password.

Il nous reste à adapter plainPassword: on indique qu'on peut écrire quand on est sur POST /users et sur PUT /users/{id} pour ça on utilise @Groups({"user:write", "user:item:put"}) On indique également le groupe de validation @Assert\NotBlank(groups={"Default", "update-password"}) (à ne pas confondre avec le groupe precedent qui est le groupe de serialization)

/**
 * @SerializedName("password")
 * @Groups({"user:write", "user:item:put"})
 * @Assert\NotBlank(groups={"Default", "update-password"})
 * @Assert\Length(
 *       min = 8,
 *       max = 32,
 *       minMessage = "Your password must be at least {{ limit }} characters long",
 *       maxMessage = "Your password cannot be longer than {{ limit }} characters"
 *  )
 * @Assert\Regex(
 *      "/^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/",
 *      message = "Your password needs an uppercase, a lowercase, a digit and a special character"
 *  )
 */
private $plainPassword;

Vous pouvez maintenant modifier votre mot de passe sur PUT api/users/{id} quand vous êtes connecté. Veuillez vous assurer d'être sur l'id qui correspond à votre utilisateur. (Il est retourné lors du login)

Maintenant vous pouvez tester la validation en envoyant un mot de passe faible ou un ommetre password ou currentPassword pour vérifier que si vous en envoyez un, l'autre est demandé.

La route reste accessible pour la modification des autres attributs de l'utilisateur

prev next

Commentaires

Connectez-vous pour laisser un commentaire