Skip to content
Advertisement

logged user does not have all fields filled up

I’m using Symfony 2.8 and Doctrine and I have security.yml configured to point to the User class which implements UserInterface. My ORM schema is in YAML.

The problem:

  • In database the user has also specified “email” field, Symfony for LOGGED USER is not filling up that field and also “password” field is empty.

screenshot

When I do $this->get('doctrine.orm.entity_manager')->clear(User::class); then the entity manager is fetching correctly the entity. But when the entity is COMING FROM SESSION, then it’s incorrect.

The problem is also that when I try to fetch a fresh entity from database using find() on a repository then, the incorrect element from session is fetched when I will not use the $em->clear(User::class)

How to tell Symfony/Doctrine to construct my entity in that way that it will have all fields filled up, so it will become persistable?

<?php

namespace XXXAppBundleModelEntity;

use XXXAppBundleModelEntityServerLogging;
use DoctrineORMMapping as ORM;
use SymfonyComponentSecurityCoreUserUserInterface;

/**
 * User
 */
class User implements UserInterface
{
    /**
     * @var integer $id
     */
    protected $id;

    /**
     * @var string $username
     */
    protected $username;

    /**
     * @var string $email
     */
    protected $email;

    /**
     * @var string $password
     */
    protected $password;

    /**
     * @var array $roles
     */
    protected $roles = array();

    /**
     * @var DoctrineCommonCollectionsCollection $logEvents
     */
    protected $logEvents;

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

    /**
     * {@inheritdoc}
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * @param string $username
     * @return $this
     */
    public function setUsername($username)
    {
        $this->username = $username;
        return $this;
    }

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

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

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

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

    /**
     * Returns the roles or permissions granted to the user for security.
     */
    public function getRoles()
    {
        $roles = $this->roles;

        // guarantees that a user always has at least one role for security
        if (empty($roles)) {
            $roles[] = 'ROLE_USER';
        }

        return array_unique($roles);
    }

    public function setRoles(array $roles)
    {
        $this->roles = $roles;
    }

    /**
     * Returns the salt that was originally used to encode the password.
     */
    public function getSalt()
    {
        // See "Do you need to use a Salt?" at http://symfony.com/doc/current/cookbook/security/entity_provider.html
        // we're using bcrypt in security.yml to encode the password, so
        // the salt value is built-in and you don't have to generate one

        return;
    }

    /**
     * Removes sensitive data from the user.
     */
    public function eraseCredentials()
    {
        $this->password = null;
        $this->email    = null;
    }

    /**
     * Appends an entry to administration log
     *
     * @param XXXAppBundleModelEntityServerLogging $logEvent
     * @return $this
     */
    public function appendLog(ServerLogging $logEvent)
    {
        if (!$this->logEvents->contains($logEvent))
        {
            $this->logEvents->add($logEvent);
        }

        return $this;
    }

    /**
     * Remove a log entry from the history
     *
     * @param XXXAppBundleModelEntityServerLogging $logEvent
     * @return $this
     */
    public function clearLogEntry(ServerLogging $logEvent)
    {
        $this->logEvents->removeElement($logEvent);

        return $this;
    }
}

And ORM configuration:

XXXAppBundleModelEntityUser:
    type: entity
    table: users
    repositoryClass: XXXAppBundleModelRepositoryUserRepository
    id:
        id:
            type: integer
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
            id: true
            generator:
                strategy: IDENTITY
    fields:
        username:
            type: string
            scale: 0
            length: null
            unique: true
            nullable: false
            precision: 0
        email:
            type: string
            scale: 0
            length: null
            unique: true
            nullable: false
            precision: 0
        password:
            type: string
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
        roles:
            type: json_array
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
    oneToMany:
        logEvents:
            targetEntity: XXXAppBundleModelEntityServerLogging
            cascade:
                - remove
                - persist
            fetch: LAZY
            mappedBy: author
            inversedBy: null
            orphanRemoval: false
            orderBy: null
    lifecycleCallbacks: {  }

Advertisement

Answer

You implemented the UserInterface::eraseCredentials() method in a way that it unsets the email and the password:

public function eraseCredentials()
{
    $this->password = null;
    $this->email    = null;
}

Symfony will invoke this method before serializing the object to save it in the session.

The UserInterface::eraseCredentials() is meant to remove sensitive data from the user object so it does not end up in for example the session files, but there is no real need to remove the email, like you are doing. A better example would be if you are storing the plaintext version of the user’s password somewhere on this object, this is something you would never want to end up in session files.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement