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
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 nextCommentaires
Connectez-vous pour laisser un commentaire