0
votes

I am trying to encrypt the passwords of my Users table using the functions provided by Symfony 3.4.

My goal would be as follows:

  1. Generate a random password of 7 characters (including special characters) ==> Done.

  2. Encrypt the password and insert it into the database. ==> Failed

  3. Be able to check when the user enters their password (one that is not encrypted) to authenticate. ==> Failed.

For the 1st step I used this function:

    function generatePassword($nb_caractere = 7)
{
        $mot_de_passe = "";

        $chaine = "abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ023456789@!$?&";
        $longeur_chaine = strlen($chaine);

        for($i = 1; $i <= $nb_caractere; $i++)
        {
            $place_aleatoire = mt_rand(0,($longeur_chaine-1));
            $mot_de_passe .= $chaine[$place_aleatoire];
        }

        return $mot_de_passe;   
}

The password is correctly generated.

For the second step, my idea was to use this:

$encoded = $encoder->encodePassword($user, $user->getPassword());

But I've this error :

Controller "Site\PagesBundle\Controller\UserController::activerUtilisateur()" requires that you provide a value for the "$encoder" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.

I send you the code of my files for more details :

User.php :

<?php

namespace Site\PagesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;


/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\UserRepository")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="identifiant", type="string", length=255, nullable=true)
     */
    private $identifiant;


    /**
     * @var string
     *
     * @ORM\Column(name="nom", type="string", length=255)
     */
    private $nom;

       /**
     * @var string
     *
     * @ORM\Column(name="prenom", type="string", length=255)
     */
    private $prenom;



    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=255)
     */
    private $email;

    /**
     * @var string
     *
     * @ORM\Column(name="password", type="string", length=255, nullable=true)
     */
    private $password;

    /**
     * @var int
     *
     * @ORM\Column(name="nbTelechargementsAuto", type="integer", nullable=true)
     */
    private $nbTelechargementsAuto;

    /**
     * @var bool
     *
     * @ORM\Column(name="isActif", type="boolean")
     */
    private $isActif=0;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     *
     * @var \DateTime
    */
    private $createdAt;


    /**
     * @var bool
     *
     * @ORM\Column(name="isCreated", type="boolean")
     */
    private $isCreated=0;

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     *
     * @return Information
     */
    public function setCreatedAt()
    {
        $this->createdAt = new \DateTimeImmutable();

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set nom
     *
     * @param string $nom
     *
     * @return User
     */
    public function setNom($nom)
    {
        $this->nom = $nom;

        return $this;
    }

    /**
     * Get nom
     *
     * @return string
     */
    public function getNom()
    {
        return $this->nom;
    }

        /**
     * Set nom
     *
     * @param string $identifiant
     *
     * @return User
     */
    public function setIdentifiant($identifiant)
    {
        $this->identifiant = $identifiant;

        return $this;
    }

    /**
     * Get nom
     *
     * @return string
     */
    public function getIdentifiant()
    {
        return $this->identifiant;
    }

        /**
     * Set prenom
     *
     * @param string $prenom
     *
     * @return User
     */
    public function setPrenom($prenom)
    {
        $this->prenom = $prenom;

        return $this;
    }

    /**
     * Get prenom
     *
     * @return string
     */
    public function getPrenom()
    {
        return $this->prenom;
    }

    /**
     * Set email
     *
     * @param string $email
     *
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Get password
     *
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }

    /**
     * Set nbTelechargementsAuto
     *
     * @param integer $nbTelechargementsAuto
     *
     * @return User
     */
    public function setNbTelechargementsAuto($nbTelechargementsAuto)
    {
        $this->nbTelechargementsAuto = $nbTelechargementsAuto;

        return $this;
    }

    /**
     * Get nbTelechargementsAuto
     *
     * @return int
     */
    public function getNbTelechargementsAuto()
    {
        return $this->nbTelechargementsAuto;
    }

    /**
     * Set isActif
     *
     * @param boolean $isActif
     *
     * @return User
     */
    public function setIsActif($isActif)
    {
        $this->isActif = $isActif;

        return $this;
    }

    /**
     * Get isActif
     *
     * @return bool
     */
    public function getIsActif()
    {
        return $this->isActif;
    }


        /**
     * Set isCreated
     *
     * @param boolean $isCreated
     *
     * @return User
     */
    public function setIsCreated($isCreated)
    {
        $this->isCreated = $isCreated;

        return $this;
    }

    /**
     * Get isCreated
     *
     * @return bool
     */
    public function getIsCreated()
    {
        return $this->isCreated;
    }


    /**
     * Activation du compte
     */
    public function activerCompte($nbPackages, $nbHomonymes)
    {

        if($this->getIsCreated() == 0)
        {
            $unIdentifiant = $this->getNom();
            $unIdentifiant .= ".";
            $unIdentifiant .= $this->getPrenom();
            $unIdentifiant = strtolower($unIdentifiant);

            if($nbHomonymes > 0)
            {
                $nbHomonymes++;
                $unIdentifiant .= $nbHomonymes;
            }


            $this->setIdentifiant(strtolower($unIdentifiant));
            $this->setNbTelechargementsAuto($nbPackages);
            $this->setCreatedAt();
            $this->setIsCreated(true);

        }

        $password = $this->generatePassword();

        $this->setPassword($password);
        $this->setIsActif(true);

        return $this;
    }

    public function constructionIdentifiant()
    {
        $unIdentifiant = $this->getNom();
        $unIdentifiant .= ".";
        $unIdentifiant .=$this->getPrenom();

        return $unIdentifiant;
    }

    /**
     * Désactivation du compte
     */
    public function desactiverCompte()
    {
        $this->setIsActif(false);
        $this->setCreatedAt();

        return $this;
    }

    public function registration()
    {
        // Passage Nom 1ère lettre Majuscule le reste minuscule
        $leNom = $this->getNom();
        $leNom = strtolower($leNom);
        $leNom = ucfirst($leNom);

        // Passage Nom 1ère lettre Majuscule le reste minuscule
        $lePrenom = $this->getPrenom();
        $lePrenom = strtolower($lePrenom);
        $lePrenom = ucfirst($lePrenom);

        $this->setNom($leNom);
        $this->setPrenom($lePrenom);
        $this->setCreatedAt();
    }

    /**
     * Génération d'un mot de passe
     * $nb_caractere = nombre de caractère du mdp
     * Pas de caractère qui se ressemble (L minuscule, 1 et i majuscule, Zéro et la lettre o.)
     * Sécurité supplémentaire avec : caractères speciaux: - + = $ % ! @ #
     * Pas d'espace pour éviter les erreurs
     */
    function generatePassword($nb_caractere = 7)
{
        $mot_de_passe = "";

        $chaine = "abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ023456789@!$?&";
        $longeur_chaine = strlen($chaine);

        for($i = 1; $i <= $nb_caractere; $i++)
        {
            $place_aleatoire = mt_rand(0,($longeur_chaine-1));
            $mot_de_passe .= $chaine[$place_aleatoire];
        }

        return $mot_de_passe;   
}


}

Controller :

<?php

namespace Site\PagesBundle\Controller;

use Site\PagesBundle\Entity\User;
use Symfony\Component\HttpFoundation\Request;
use Site\PagesBundle\Utils\Functions as mesFonctions;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * User controller.
 *
 * @Route("utilisateurs")
 */
class UserController extends Controller
{

//... Some functions

     /**
     * Activer le compte d'un utilisateur
     *
     * @Route("/activer/{id}", name="utilisateur_activation")
     * @Method("GET")
     */
    public function activerUtilisateur(UserPasswordEncoderInterface $encoder,Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager(); //Récupération du manager
        $nbPackages = $em->getRepository('PagesBundle:Paquet')->getNombrePackages(); //Récupération du nombre de packages (pour initialiser le nombre de téléchargements offert à l'utilisateur)

        $user = $em->getRepository('PagesBundle:User')->findOneById($id); // Récupération de l'objet User en fonction de l'ID fourni en paramètre

       // $lesUtilisateurs = $em->getRepository('PagesBundle:User')->findAll();

        $nbHomonymes = $em->getRepository('PagesBundle:User')->getHomonymes($user->getNom(),$user->getPrenom()); //Vérification des homonymes pour attribuer un bon identifiant pour l'utilisateur activé

        $user->activerCompte($nbPackages,$nbHomonymes); //Procédure d'activation du compte
        $em->persist($user); //Enregistrement des informations du compte
        $encoded = $encoder->encodePassword($user, $user->getPassword());
        $user->setPassword($encoded);

        $em->flush(); //Validation dans la bDD

        mesFonctions::sendMail($user->getEmail(),"confirmation",$user->getIdentifiant()); //Envoi d'un mail à l'utilisateur sur l'adresse mail qu'il a renseigné lors de sa demande d'inscription



        return $this->redirectToRoute('utilisateurs_index'); //Redirection à la liste des différents utilisateurs


    }

Security.yml: I did not touch this part but I wonder if she has an interest. I do not know too much about symfony.

# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
    encoders:
        PagesBundle\Entity\User: bcrypt

    # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        in_memory: {memory: ~}
        in_database:
            entity:
                class: Site\PagesBundle\Entity\User
                property: email

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: true

            provider: in_database

            form_login:
                login_path: security_login
                check_path: security_login

            logout:
                path: security_logout
                target: informations

            # activate different ways to authenticate

            # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
            #http_basic: ~

            # https://symfony.com/doc/current/security/form_login_setup.html
            #form_login: ~

Thanks !

EDIT:

config :

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en

framework:
    # ...
    templating:
        engines: ['twig']
    #esi: ~
    #translator: { fallbacks: ['%locale%'] }
    secret: '%secret%'
    router:
        resource: '%kernel.project_dir%/app/config/routing.yml'
        strict_requirements: ~
    form: ~
    csrf_protection: ~
    validation: { enable_annotations: true }
    #serializer: { enable_annotations: true }
    default_locale: '%locale%'
    trusted_hosts: ~
    session:
        # https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id: session.handler.native_file
        save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
    fragments: ~
    http_method_override: true
    assets: ~
    php_errors:
        log: true

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    form_themes: ['bootstrap_4_layout.html.twig']


# Doctrine Configuration
doctrine:
    dbal:
        driver: pdo_mysql
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        charset: UTF8
        # if using pdo_sqlite as your database driver:
        #   1. add the path in parameters.yml
        #     e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
        #   2. Uncomment database_path in parameters.yml.dist
        #   3. Uncomment next line:
        #path: '%database_path%'

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true

# Swiftmailer Configuration
swiftmailer:
    transport: '%mailer_transport%'
    host: '%mailer_host%'
    username: '%mailer_user%'
    password: '%mailer_password%'
    spool: { type: memory }

sensio_framework_extra:
   router:
        annotations: false

assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:    [ ]
   #java: /usr/bin/java
    java: C:\Program Files\Java\jdk1.8.0_65\bin\java.exe
    filters:
        cssrewrite: ~
        cssembed:
            jar: "%kernel.root_dir%/Resources/java/cssembed.jar"        
            yui_js:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"
        yui_css:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"
        lessphp:
            file: "%kernel.root_dir%/../vendor/oyejorge/less.php/lessc.inc.php"   
            apply_to: ".less$"
    assets:
        jquery_js:
            inputs:
                - "%kernel.root_dir%/../vendor/components/jquery/jquery.min.js"            
            filters: [?yui_js]
            output: js/jquery.min.js

        bootstrap_css:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/less/bootstrap.less"
            filters:
                - lessphp
                - cssrewrite
            output: css/bootstrap.css            

        bootstrap_js:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/affix.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/alert.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/button.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/carousel.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/collapse.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/dropdown.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/modal.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/tooltip.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/popover.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/scrollspy.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/tab.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/transition.js"
            filters: [?yui_js]
            output: js/bootstrap.js             
        fonts_glyphicons_eot:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.eot"
            output: "fonts/glyphicons-halflings-regular.eot"
        fonts_glyphicons_svg:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.svg"
            output: "fonts/glyphicons-halflings-regular.svg"
        fonts_glyphicons_ttf:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.ttf"
            output: "fonts/glyphicons-halflings-regular.ttf"
        fonts_glyphicons_woff:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.woff"

            output: "fonts/glyphicons-halflings-regular.woff"

stof_doctrine_extensions: 
    orm: 
        default: 
            sluggable: true

vich_uploader:
    db_driver: orm
    twig: true
    storage: file_system

    mappings:
        paquet:
            uri_prefix: fichiers/packages
            upload_destination: '%kernel.root_dir%/../web/fichiers/packages/' 

            inject_on_load: true
            delete_on_update: true
            delete_on_remove: true

        notice:
            uri_prefix: fichiers/notices
            upload_destination: '%kernel.root_dir%/../web/fichiers/notices/' 

            inject_on_load: false
            delete_on_update: true
            delete_on_remove: true

fos_ck_editor:
    configs:
        my_config:
            toolbar: [ ["Source", "-", "Save"], "/", ["Anchor"], "/", ["Maximize"] ]
            uiColor:                "#000000"

services.yml:

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services

    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    twig.extension.intl:
        class: Twig_Extensions_Extension_Intl
        tags:
            - { name: twig.extension }


    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'
1
the encoder should be a controller parameter, you should pull that from the container via $this->get('encode_service_id')->encodePassword(...); - zedling
The problem is that your encoder service isn't injected correctly. Do you have autoconfiguration and autoworing enabled ? Can you add your config/services.yaml file to see how your services are configured by default ? - Florian Hermann
Okay I edited my first post adding config and services ! - Agar io FR
Sorry zedling, I don't understand :/ - Agar io FR
You have to edit your question instead to use the Answer section to add some useful infos. Also if you have resolved the primary question you (or who have it) should add the solution and then open a new question if you will find other problems. But before post other questions please, read one more time the Asking Section of the Help Center. - gp_sflover

1 Answers

0
votes

Ok I get it.

You have multiple bundles based on the UserController namespace (Site\PagesBundle\Controller\UserController). But your services.yaml enable services only for your AppBundle.

you have to duplicate this configuration for all your bundles and adapt it with the right namespace :

#services.yaml file
AppBundle\:
    resource: '../../src/AppBundle/*'
    # you can exclude directories or files
    # but if a service is unused, it's removed anyway
    exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services

AppBundle\Controller\:
    resource: '../../src/AppBundle/Controller'
    public: true
    tags: ['controller.service_arguments']

This will declare all your controllers from your bundles as services in order to enable autowiring service in controllers constructors or in controllers actions.


Edit with example for your bundle:

Site\PagesBundle\:
    resource: '../../src/Site/PagesBundle/*'
    exclude: '../../src/Site/PagesBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services

Site\PagesBundle\Controller\:
    resource: '../../src/Site/PagesBundle/Controller'
    public: true
    tags: ['controller.service_arguments']