|
<?php |
|
|
|
namespace Acme\ApiBundle\Security; |
|
|
|
use Doctrine\Common\Persistence\ManagerRegistry; |
|
use Symfony\Component\Filesystem\Filesystem; |
|
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; |
|
use Symfony\Component\Security\Core\User\UserProviderInterface; |
|
use Symfony\Component\Security\Core\User\UserInterface; |
|
|
|
/** |
|
* Custom file system based user provider. |
|
*/ |
|
class UserProvider implements UserProviderInterface |
|
{ |
|
/** |
|
* @var string Filesystem path to the user dump. |
|
*/ |
|
private $cacheFile; |
|
|
|
/** |
|
* @var Filesystem |
|
*/ |
|
private $fs; |
|
|
|
/** |
|
* @var UserInterface[] Array of users loaded from the filesystem cache. |
|
*/ |
|
private $users; |
|
|
|
/** |
|
* @var ManagerRegistry |
|
*/ |
|
private $doctrine; |
|
|
|
/** |
|
* @param string $cacheFile Path to the user dump file |
|
* @param Filesystem $fs The filesystem service |
|
* @param ManagerRegistry $doctrine Registry to get the repository from. |
|
*/ |
|
public function __construct($cacheFile, Filesystem $fs, ManagerRegistry $doctrine) |
|
{ |
|
$this->cacheFile = $cacheFile; |
|
$this->fs = $fs; |
|
$this->doctrine = $doctrine; |
|
} |
|
|
|
/** |
|
* {@inheritDoc} |
|
*/ |
|
public function loadUserByUsername($username) |
|
{ |
|
$users = $this->getUsers(); |
|
|
|
if (isset($users[$username])) { |
|
return $users[$username]; |
|
} |
|
|
|
throw new UsernameNotFoundException(); |
|
} |
|
|
|
/** |
|
* We don't do sessions so this method is not used. |
|
* |
|
* @param UserInterface $user The user. |
|
* |
|
* @return UserInterface |
|
*/ |
|
public function refreshUser(UserInterface $user) |
|
{ |
|
return $user; |
|
} |
|
|
|
/** |
|
* Dump the users into the filesystem cache. |
|
* |
|
* @param array $users List of UserInterface. |
|
* |
|
* @return void |
|
*/ |
|
public function dumpUsers(array $users) |
|
{ |
|
$indexedUsers = array(); |
|
foreach ($users as $user) { |
|
$indexedUsers[$user->getUsername()] = $user; |
|
} |
|
$this->users = $indexedUsers; |
|
|
|
$this->fs->dumpFile($this->cacheFile, '<?php return ' . var_export($indexedUsers, true) . ';'); |
|
} |
|
|
|
/** |
|
* Get the users list, loading it from the cache file if necessary. |
|
* |
|
* @return UserInterface[] indexed by the username. |
|
*/ |
|
private function getUsers() |
|
{ |
|
if (null === $this->users) { |
|
if (!$this->fs->exists($this->cacheFile)) { |
|
$this->warmup(); |
|
} |
|
$this->users = require($this->cacheFile); |
|
} |
|
|
|
return $this->users; |
|
} |
|
|
|
/** |
|
* Warm up the cache file. |
|
* |
|
* @return void |
|
*/ |
|
private function warmup() |
|
{ |
|
$users = $this->doctrine |
|
->getRepository('AcmeApiBundle:ApiUser') |
|
->findAll() |
|
; |
|
|
|
$this->dumpUsers($users); |
|
} |
|
|
|
/** |
|
* We can support whatever. |
|
* |
|
* @param string $class Class |
|
* |
|
* @return boolean |
|
*/ |
|
public function supportsClass($class) |
|
{ |
|
return true; |
|
} |
|
} |