Skip to content

[Validator] New PasswordStrength constraint #49789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 26, 2023

Conversation

Spomky
Copy link
Contributor

@Spomky Spomky commented Mar 23, 2023

Q A
Branch? 6.3
Bug fix? no
New feature? yes
Deprecations? no
Tickets none
License MIT
Doc PR symfony/symfony-docs#18124

This PR adds a new constraint PasswordStrength. This constraint is able to determine if the password strength (or any other string) fulfils with the minimum requirement.
It leverages on bjeavons/zxcvbn-php which is required when this constraint is used.

Example:

<?php

declare(strict_types=1);

namespace App\Form;

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\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PasswordStrength;

final class ChangePasswordFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $restrictedData = $options['restrictedData'] ?? [];

        $builder
            ->add('plainPassword', RepeatedType::class, [
                'type' => PasswordType::class,
                'options' => [
                    'attr' => [
                        'autocomplete' => 'new-password',
                    ],
                ],
                'first_options' => [
                    'constraints' => [
                        new NotBlank(),
                        new PasswordStrength(['restrictedData' => $restrictedData])
                    ],
                    'label' => 'New password',
                ],
                'second_options' => [
                    'label' => 'Repeat the new password',
                ],
                'mapped' => false,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'restrictedData' => [],
        ])
            ->setAllowedTypes('restrictedData', 'string[]')
        ;
    }
}

Then from e.g. a controller

$form = $this->createForm(ChangePasswordFormType::class, null, [
    'restrictedData' => [
        $user->getUsername(),
        $user->getEmail(),
        $user->getGivenName(),
        $user->getFamilyName(),
        'ApplicationName', // Arbitrary data
    ],
]);

It can be added as a property attribute:

<?php

declare(strict_types=1);

namespace App\Form;

use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\PasswordStrength;

final class ChangePasswordFormData
{
    #[NotBlank]
    #[PasswordStrength]
    public string $password = '';
}

Options:

  • lowStrengthMessage: the message in case of a weak password (default: The password strength is too low. Please use a stronger password.)
  • minScore: 0 means a weak password, 4 means a very good password (default: 2)
  • restrictedData: a list of restricted data e.g. user information such as ID, username, email, given name, last name or application information (default: [])
  • restrictedDataMessage: the message in case of the restricted data in the password (default: The password contains at least one restricted data: {{ wordList }}.)

@lyrixx
Copy link
Member

lyrixx commented Mar 23, 2023

We have something really similar in our application, so I think it's a good idea to have this feature in the core

@Spomky Spomky force-pushed the features/validator-password-strength branch from 1fd5fa3 to c6500cb Compare March 23, 2023 23:05
Copy link
Contributor

@94noni 94noni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would definitely use it :)

];
yield [
new PasswordStrength([
'restrictedData' => ['symfony'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very nice
may I ask you to "complete" your PR desc with your usage of dump($userData); with the constraint?
or injecting for example the security user to define the username/email in the list, this would be very valuable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dump statement is a wrong copy/paste.
I will add an example when the form factory is used with user/application data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that will be wonderful for showcasing real usage in the doc repo after :)

@carsonbot carsonbot changed the title New PasswordStrength constraint [Validator] New PasswordStrength constraint Mar 24, 2023
@Spomky Spomky marked this pull request as draft March 24, 2023 14:25
@OskarStark
Copy link
Contributor

I like the proposal 😃💪🏻

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it as well (it has been on my todo list for a long time now, thank you for working on it).

@Spomky Spomky marked this pull request as ready for review March 25, 2023 22:17
@OskarStark OskarStark changed the title [Validator] New PasswordStrength constraint [Validator] New PasswordStrength constraint Mar 26, 2023
@andreybolonin
Copy link
Contributor

We have something really similar in our application, so I think it's a good idea to have this feature in the core

+1

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an entry in the component CHANGELOG file?

@Spomky Spomky force-pushed the features/validator-password-strength branch from 805ed9f to 8eb69fc Compare March 26, 2023 12:44
@Spomky
Copy link
Contributor Author

Spomky commented Mar 26, 2023

Can you add an entry in the component CHANGELOG file?

Yes. Done.

@Spomky Spomky requested a review from alanpoulain March 26, 2023 12:51
@Spomky Spomky requested review from 94noni and removed request for alanpoulain March 26, 2023 12:51
@@ -152,7 +152,8 @@
"symfony/security-acl": "~2.8|~3.0",
"twig/cssinliner-extra": "^2.12|^3",
"twig/inky-extra": "^2.12|^3",
"twig/markdown-extra": "^2.12|^3"
"twig/markdown-extra": "^2.12|^3",
"bjeavons/zxcvbn-php": "^1.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be added in the validator component composer.json as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed I missed it. I have just added it as a dev dependency and in the suggest section as well.

Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#37093 that's a long standing feature 👍
The docs should probably point to the OWASP recommandations to reduce misuses.

@@ -62,6 +63,7 @@
"symfony/yaml": "",
"symfony/config": "",
"egulias/email-validator": "Strict (RFC compliant) email validation",
"bjeavons/zxcvbn-php": "Password strength estimation used by the PasswordStrength constraint",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this one. It's not needed, and discovery happens with docs and/or auto-completion, ... but never via the suggest Composer thingy IMHO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I understand. I removed this line.

@fabpot fabpot force-pushed the features/validator-password-strength branch from 3c0c947 to 1d93f5c Compare March 26, 2023 16:05
@fabpot
Copy link
Member

fabpot commented Mar 26, 2023

Thank you @Spomky.

@fabpot fabpot merged commit c375406 into symfony:6.3 Mar 26, 2023
@Spomky
Copy link
Contributor Author

Spomky commented Mar 26, 2023

Thank you @Spomky.

You are welcome. I am really happy to contribute.

#37093 that's a long standing feature 👍 The docs should probably point to the OWASP recommandations to reduce misuses.

OK I will mention it in the documentation PR with some examples.

@Spomky Spomky deleted the features/validator-password-strength branch March 26, 2023 16:08
@nicolas-grekas
Copy link
Member

Considered for reversion in #49831

OskarStark added a commit to symfony/symfony-docs that referenced this pull request Mar 31, 2023
…omky)

This PR was merged into the 6.3 branch.

Discussion
----------

[Validator] Document `PasswordStrength` constraint

These modifications are proposed as per ~symfony/symfony#49789 => symfony/symfony#49856

Commits
-------

ec51dd2 PasswordStrength Documentation pages
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.