'Symfony Password validation regex (Call to member function null)

Pretty new to the Symfony community but trying my best and I'm having a hard time on "how to validate password" topic.

When my user is connecting for the first time, he's redirected on a new page to change it to a stronger one. I check if it's strong enough with a regex and it's working but only if the user match the strong password policies on the first try. Otherwise he is disconnected and I get a "Call to a member function GetPassword() on null" error which I think I understand, I mean I get the why but don't know how to correct it.

I tried my regex on both the entity and on the symfony form (separately) but the same error occurs.

Thanks for your feedback (and kindness)

Here's my entity :

#[Assert\Regex('#^\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$#', message: 'Mot de passe trop faible')]
#[ORM\Column(type:'string')]
private $password;

And here is my controller :

#[Route("/", name:"")]
class LoginController extends AbstractController
{
    #[Route(path: '/login', name: 'app_login')]
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        // if ($this->getUser()) {
        //     return $this->redirectToRoute('target_path');
        // }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
    }

    #[Route(path: '/logout', name: 'app_logout')]
    public function logout(): void
    {
        throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
    }

    #[Route('/check', name: 'check')]
    public function check(
        UserRepository $repoUser
    ): Response

    {
        $user = $this->getUser();

        $isPassword1234 = password_verify('1234',$user->getPassword());


        if($isPassword1234){
            return $this->redirectToRoute('mdp');
        }
        return $this->redirectToRoute('home');
    }

    #[Route('/mdp', name: 'mdp')]
    public function changeMdp(
        UserRepository $repository,
        EntityManagerInterface $entityManager,
        Request $request,
        UserPasswordHasherInterface $passwordHasher
    ): Response {

        $user = $this->getUser();
        $form = $this->createForm(MdpType::class, $user );
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $user = $this->getUser();
            $mdpSimple = $user->GetPassword();
            $vraiMdp = $passwordHasher->hashPassword($user,$mdpSimple);
            $user->setPassword($vraiMdp);
            $entityManager->persist($user);
            $entityManager->flush();
            return $this->redirectToRoute('home');
        }

        $this->addFlash('error', ' Les deux mots de passes ne correspondent pas !');
        return $this->renderForm('home/mdp.html.twig', compact('form', 'user'));
    }

}

My security.yaml :

security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
    Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    App\Entity\User:
        algorithm: auto

# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
    # used to reload user from session & other features (e.g. switch_user)
    app_user_provider:
        entity:
            class: App\Entity\User
            property: email
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        lazy: true
        provider: app_user_provider
        custom_authenticator: App\Security\UserAuthenticator

        logout:
            path: app_logout
            # where to redirect after logout
            target: app_login


        # activate different ways to authenticate
        # https://symfony.com/doc/current/security.html#the-firewall

        # https://symfony.com/doc/current/security/impersonating_user.html
        # switch_user: true

# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used

role_hierarchy:
    ROLE_SECTION: ROLE_USER
    ROLE_UD: ROLE_SECTION
    ROLE_NATIONAL: ROLE_UD
    ROLE_ADMIN: ROLE_NATIONAL

access_control:
     - { path: ^/recap, roles: ROLE_UD }
     - { path: ^/national, roles: ROLE_NATIONAL }
     - { path: ^/admin, roles: ROLE_ADMIN }

when@test: security: password_hashers: # By default, password hashers are resource intensive and take time. This is # important to generate secure password hashes. In tests however, secure hashes # are not important, waste resources and increase test times. The following # reduces the work factor to the lowest possible values. Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: auto cost: 4 # Lowest possible value for bcrypt time_cost: 3 # Lowest possible value for argon memory_cost: 10 # Lowest possible value for argon



Solution 1:[1]

Now that you have shared your security I can tell you that the error is linked to that configuration

add this


access_control:
     - { path: ^/check, roles: ROLE_USER }
     - { path: ^/recap, roles: ROLE_UD }
     - { path: ^/national, roles: ROLE_NATIONAL }
     - { path: ^/admin, roles: ROLE_ADMIN }

If you don't tell symfony that the route needs authentication $this->getUser() in your controller will always returns null

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 R4ncid