Commit 8de2384f authored by Mat's avatar Mat

User: remplace token_key par un tableau sérialisé pouvant contenir plusieurs tokens

* il faut alors vérifier lorsqu'on génère un token, qu'il n'y en n'a pas déjà un pour cette offre
* et il faut que le security.provider fasse une requête custom pour voir si le token est bon
parent 89739faa
......@@ -13,7 +13,8 @@ security:
my_tokenkey_provider: #2
entity:
class: PotageBundle:User
property: tokenKey
#property: tokenKey
# je ne peux me référer à une simple propriété puisque c'est un tableau qui peut contenir plusieurs tokens
firewalls:
main:
......
......@@ -49,9 +49,10 @@ class User extends BaseUser
private $utilisateur;
/**
* @ORM\Column(type="string", unique=true, length=50)
* @ORM\Column(type="array", unique=false, length=255, nullable=true)
*/
private $tokenKey;
/**
* User constructor.
......@@ -60,7 +61,7 @@ class User extends BaseUser
{
parent::__construct();
$this->tokenKey = bin2hex(random_bytes(20));
$this->tokenKey = array();
}
/**
......@@ -82,7 +83,7 @@ class User extends BaseUser
*
* @return User
*/
public function setUtilisateur(\PotageBundle\Entity\Utilisateur $utilisateur = null)
public function setUtilisateur(Utilisateur $utilisateur = null)
{
$this->utilisateur = $utilisateur;
......@@ -109,25 +110,23 @@ class User extends BaseUser
return parent::getUsername() . ' ( ' . parent::getEmail() . ' )';
}
/**
* Set tokenKey
*
* @return User
* @return mixed
*/
public function setTokenKey()
public function getTokenKey()
{
$this->tokenKey = bin2hex(random_bytes(20));
return $this;
return $this->tokenKey;
}
/**
* Get tokenKey
*
* @return string
* @param mixed $tokenKey
* @return User
*/
public function getTokenKey()
public function addTokenKey($tokenKey)
{
return $this->tokenKey;
$this->tokenKey[] = $tokenKey;
return $this;
}
}
<?php
namespace PotageBundle\Repository;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* UserRepository
......@@ -8,7 +10,7 @@ namespace PotageBundle\Repository;
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends \Doctrine\ORM\EntityRepository
class UserRepository extends \Doctrine\ORM\EntityRepository implements UserLoaderInterface
{
/**
* @param $id_utilisateur
......@@ -23,4 +25,22 @@ class UserRepository extends \Doctrine\ORM\EntityRepository
->setParameter(':id', $id_utilisateur);
return $qb->getQuery()->getOneOrNullResult();
}
/**
* Dans security, je ne peux me référer à une propriété, puisque token_key est un array sérialisé
* cfr. https://symfony.com/doc/3.4/security/entity_provider.html#using-a-custom-query-to-load-the-user
*
* @param $tokenkey
* @return UserInterface|null
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function loadUserByUsername($tokenkey)
{
return $this->createQueryBuilder('u')
->where('u.tokenKey LIKE :tokenkey')
->setParameter('tokenkey', '%'.$tokenkey.'%')
->getQuery()
->getOneOrNullResult();
}
}
......@@ -3,7 +3,6 @@
namespace PotageBundle\Security;
use PotageBundle\Services\LettreToken;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
......@@ -16,19 +15,6 @@ use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
class TokenAuthenticator extends AbstractGuardAuthenticator
{
private $lettreToken;
/**
* TokenAuthenticator constructor.
*
* @param LettreToken $lettreToken
*/
public function __construct(LettreToken $lettreToken)
{
$this->lettreToken = $lettreToken;
}
/**
* Called on every request to decide if this authenticator should be
* used for the request. Returning false will cause this authenticator
......@@ -95,11 +81,8 @@ class TokenAuthenticator extends AbstractGuardAuthenticator
*/
public function getCredentials(Request $request)
{
$tokenEncoded = $request->query->get('token');
$tokenDecoded = $this->lettreToken->decodePotageAccess($tokenEncoded);
return array(
'token_key' => $tokenDecoded['token_key'],
'token_key' => $request->query->get('token'),
);
}
......
......@@ -55,14 +55,43 @@ class LettreToken
->findOneByUtilisateur($id_utilisateur); //dump($user);
if ($user !== null) {
/**
* Vérifie d'abord qu'aucun token pour cette offre n'existe pour cet utilisateur.
* Pour cela on va parcourir le tableau, récupérer l'offre, et la retourner si elle existe
*/
$newOffre = $lettre->getOffre()->getId();
$userTokenKeys = $user->getTokenKey();
foreach ($userTokenKeys as $uTokenKey)
{
$uOffre = intval($this->decodePotageAccess($uTokenKey)['offre_id']);
if ($uOffre === $newOffre)
{
return $uTokenKey;
}
}
/**
* Génère un nouveau tokenKey
*/
$newKey = bin2hex(random_bytes(15));
// TODO ici une recette secrète, hors dépôt GIT !!!
$token = $user->getTokenKey()
$token = $newKey
.'_'. $lettre->getOffre()->getId()
.'_'. $lettre->getOffre()->getReference();
$tokenKey = base64_encode($token);
return base64_encode($token);
/**
* Persiste le nouveau token dans le tableau token_key du user
*/
$em = $this->container->get('doctrine')->getManager();
$user->addTokenKey($tokenKey);
$em->persist($user);
$em->flush();
return $tokenKey;
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment