I have an app that manages all of its users inside one entity (USER), implementing the UserInterface, as recommended.
Linked to it, I got the CUSTOMER and the EMPLOYEE entities: each one storing specific infos about the user.
You may ask why I'm doing like this: an EMPLOYEE can be a CUSTOMER in many WORKPLACES and may work in many WORKPLACES. In order to avoid repetition, the common info got centralized in USER and the attribute Roles in USER is always blank in db.
The goal here is to load my roles based on specific data stored in another entity (WORKPLACE) when an EMPLOYEE logs in.
My great question may live in the UserRepository: when symfony calls the repository looking for the user entered on the login form, doctrine delivers it with no roles. I put my roles and return the User to the Authenticator (the vanilla one, I havent touched it yet). After the end of every requery, Symfony checks for the user but then doctrine loads the ROLE_CLIENT (in other words - no privileges).
What I already tried and failed
- Make another authenticator supporting the routes that need those specific rules (as seen here https://symfony.com/doc/current/security/guard_authentication.html )
- Use the
UserLoaderInterfaceinsideUserRepository(as seen here https://symfony.com/doc/master/security/user_provider.html#using-a-custom-query-to-load-the-user ) - Voters (I didnt see a way to code them to my needs)
The entities
class User implements UserInterface
{
/**
* @ORM\Id()
*/
private $cpf;
/**
* @ORM\Column
*
*/
private $email;
/**
* @ORM\Column
*/
private $nome;
/**
* @var string
*
* @ORM\Column
*/
private $telefone;
/**
* @var \DateTime|null
*
* @ORM\Column
*/
private $nascimento;
/**
* @var \DateTime|null
*
* @ORM\Column
*/
private $ultimoLogin;
/**
* @var string|null
*
* @ORM\Column
*/
private $endereco;
/**
* @var string|null
*
* @ORM\Column
*/
private $cidade;
/**
* @var string|null
*
* @ORM\Column
*/
private $uf;
/**
* @var int|null
*
* @ORM\Column
*/
private $cep;
/**
* @ORM\Column(name="Roles", type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORM\Column(name="password", type="string")
*/
private $password;
//vanilla getters and setters
Workplace entity
The booleans store the privileges i want to get
class LocalTrabalho
{
/**
* @var Configuracao
*
* @ORM\ManyToOne(targetEntity=Configuracao::class, inversedBy="localTrabalho")
* @ORM\JoinColumn(name="CNPJ", referencedColumnName="CNPJ", nullable=false)
* @ORM\Id
* the company unique code
*/
private $cnpj;
/**
* @var Funcionario
*
* @ORM\ManyToOne(targetEntity=Funcionario::class, inversedBy="localTrabalho")
* @ORM\JoinColumn(name="CPF_Funcionario", referencedColumnName="CPF", nullable=false)
* @ORM\Id
* the user-employee unique code
*/
private $cpfFuncionario;
/**
* @var bool
*
* @ORM\Column
* is this employee is active?
*/
private $ativo = 1;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioCaixa = 0;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioPrestador = 1;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioRecepcao = 0;
/**
* @var bool
*
* @ORM\Column
*/
private $privilegioAdministracao = 0;
Employee Entity
class Funcionario
{
/**
* @var int
*
* @ORM\Column
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $cpf;
/**
* @var string|null
*
* @ORM\Column
*/
private $ctps;
/**
* @var string|null
*
* @ORM\Column
*/
private $foto;
An example USER tuple from db
# CodPFis, email, password, Roles, Nome, Telefone, Nascimento, Ultimo_login, Endereco, Cidade, UF, CEP
'89038252099', 'sophiejenniferteresinhaoliveira__sophiejenniferteresinhaoliveira@grupomozue.com.br', '$argon2id$v=19$m=65536,t=4,p=1$WEn7b64I9744kRJICEpaLA$jcYLDvh2bZsZPakMDGsncpbfIZwR6lN0QcgJOOSerK0', NULL, 'João da Silva', '', NULL, NULL, NULL, NULL, NULL, NULL
My last resource is asking here, after some long and wasted work hours, what should I do (or what i did wrong)?
I've seen some other threads asking similar questions, but they're outdated (im using the version 5): Dynamic roles in symfony Symfony 2 - Loading roles from database Symfony2 - Dynamic Role Management How to update roles in security token in Symfony 4 without re-logging in Symfony User Logout After Role Change
PS: Someone tried this approach (https://github.com/symfony/symfony/issues/12025#issuecomment-562004005) and got success in symfony5?
rolescolumn is not a requirement ofUserInterface, only the getter is. What I'm getting at is that you can crawl those relations and build theRolesarray in thegetRolesfunction in the entity. I can't give a more detailed explanation since you didn't tell exactly howUserandFuncionarioare 'linked', you could do it directly if they are modelled as relations or you might need some collaborators... - msgFormLoginAuthenticator, but for the next requests, i get no clue how to keep doing this manipulation because symfony asks doctrine for a fresh copy of the user from db and get no rules - Igor PereiraUseris where I keep credentials and general info about the user. If this user works somewhere, the brazilian laws require some more attributes to be stored. The link between these entities is the cpf - so in the db thefuncionariois a "child table" ofuser. I will check out about the relations you said - Igor Pereira