Skip to content

Instantly share code, notes, and snippets.

@SDiniz
Created October 11, 2016 22:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SDiniz/299a19977325adf7aa3eeac9a402e0b1 to your computer and use it in GitHub Desktop.
Save SDiniz/299a19977325adf7aa3eeac9a402e0b1 to your computer and use it in GitHub Desktop.
User with multiple accounts
<?php
namespace AppBundle\Security;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterface;
class CustomAuthenticator implements SimpleFormAuthenticatorInterface
{
/**
* Holds the password encoder ( it's the default one )
*
* @var UserPasswordEncoderInterface
*/
private $encoder;
/**
* Holds the entity manager so we can update the users and stuff
*
* @var EntityManager
*/
private $em;
/**
* The constructor
*
* @param UserPasswordEncoderInterface $encoder The encoder
* @param EntityManager $em The entity manager because of changing the user
*/
public function __construct(UserPasswordEncoderInterface $encoder, EntityManager $em)
{
$this->encoder = $encoder;
$this->em = $em;
}
/**
* Authenticates the user
*
* @param TokenInterface $token The login token
* @param UserProviderInterface $userProvider The user provider ( repository )
* @param Mixed $providerKey The provider key
*
* @return UsernamePasswordToken
*/
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
try {
$user = $userProvider->loadUserByUsername($token->getUsername());
} catch (UsernameNotFoundException $e) {
// CAUTION: this message will be returned to the client
// (so don't put any un-trusted messages / error strings here)
throw new CustomUserMessageAuthenticationException('Invalid username or password');
}
// We need to check what type of password we are working with
$passwordValid = false;
// Is it an old login? If yes than it means we are usign the MD5 value
if ( $user->getOldLogin() ) {
// Use the md5 encoder
$passwordValid = hash_equals(md5($token->getCredentials()), $user->getPassword());
// Is the password valid?
if ( $passwordValid ) {
// Let's encode the password the user entered and encoded it with our new enconder
$passwordEncoded = $this->encoder->encodePassword($user, $token->getCredentials());
// And then let's save it
$user->setPassword($passwordEncoded);
$user->setOldLogin(false);
$this->em->persist($user);
$this->em->flush();
}
} else {
// Normal method to authenticate the user
$passwordValid = $this->encoder->isPasswordValid($user, $token->getCredentials());
}
/**
* @todo If the password is not valid, check for temporary passwords for this user if they exist
*/
if ($passwordValid) {
return new UsernamePasswordToken(
$user,
$user->getPassword(),
$providerKey,
$user->getRoles()
);
}
// CAUTION: this message will be returned to the client
// (so don't put any un-trusted messages / error strings here)
throw new CustomUserMessageAuthenticationException('Invalid username or password');
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof UsernamePasswordToken
&& $token->getProviderKey() === $providerKey;
}
public function createToken(Request $request, $username, $password, $providerKey)
{
return new UsernamePasswordToken($username, $password, $providerKey);
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* @var int
*
* @ORM\Column(name="language_id", type="integer")
*/
private $languageId;
/**
* @var bool
*
* @ORM\Column(name="old_login", type="boolean")
*/
private $oldLogin;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* 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's the language id
*
* @param integer $languageId The language id
*/
public function setLanguageId($languageId) {
$this->languageId = $languageId;
return $this;
}
/**
* Get language id
*
* @return integer
*/
public function getLanguageId() {
return $this->languageId;
}
/**
* @return mixed
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt,
));
}
/**
* @param string $serialized
*
* @return mixed
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
/**
* @return mixed
*/
public function getRoles() {
// This must be returned by the account and sub account
// For now all of them have the role user
return array('ROLE_USER');
}
/**
* @return mixed
*/
public function getSalt()
{
return null;
}
/**
* @return mixed
*/
public function getUsername()
{
return $this->getEmail();
}
/**
* @return mixed
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
/**
* Set oldLogin
*
* @param boolean $oldLogin
*
* @return User
*/
public function setOldLogin($oldLogin)
{
$this->oldLogin = $oldLogin;
return $this;
}
/**
* Get oldLogin
*
* @return boolean
*/
public function getOldLogin()
{
return $this->oldLogin;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment