Skip to content

Commit

Permalink
working on #113
Browse files Browse the repository at this point in the history
  • Loading branch information
famoser committed Jan 12, 2019
1 parent 663ff34 commit e5c2afe
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Controller/Base/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@
namespace App\Controller\Base;

use App\Entity\ConstructionManager;
use App\Security\Model\UserToken;
use App\Security\Voter\Base\BaseVoter;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\KernelInterface;

class BaseController extends AbstractController
{
public static function getSubscribedServices()
{
return parent::getSubscribedServices() + ['kernel' => KernelInterface::class];
return parent::getSubscribedServices() + ['kernel' => KernelInterface::class, 'registry' => RegistryInterface::class];
}

/**
Expand Down Expand Up @@ -99,12 +101,29 @@ private function displayFlash($type, $message, $link = null)
$this->get('session')->getFlashBag()->set($type, $message);
}

/**
* @var ConstructionManager[]
*/
private $userCache = [];

/**
* @return ConstructionManager
*/
protected function getUser()
{
return parent::getUser();
/** @var UserToken $user */
$user = parent::getUser();

// early return if found in cache
if (isset($this->userCache[$user->getUsername()])) {
return $this->userCache[$user->getUsername()];
}

// load & cache
$constructionManager = $this->get('doctrine')->getRepository('App:ConstructionManager')->findOneBy(['email' => $user->getUsername()]);
$this->userCache[$user->getUsername()] = $constructionManager;

return $constructionManager;
}

/**
Expand Down
100 changes: 100 additions & 0 deletions src/Security/AuthenticationTokenProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

/*
* This file is part of the mangel.io project.
*
* (c) Florian Moser <git@famoser.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Security;

use App\Entity\ConstructionManager;
use App\Security\Base\BaseUserProvider;
use App\Security\Model\UserToken;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;

class AuthenticationTokenProvider extends BaseUserProvider
{
/**
* @var RegistryInterface
*/
private $registry;

/**
* AdminUserProvider constructor.
*
* @param RegistryInterface $registry
*/
public function __construct(RegistryInterface $registry)
{
$this->registry = $registry;
}

/**
* Refreshes the user for the account interface.
*
* It is up to the implementation to decide if the user data should be
* totally reloaded (e.g. from the database), or if the UserInterface
* object can just be merged into some internal array of users / identity
* map.
*
* @param UserInterface $user
*
* @throws UnsupportedUserException if the account is not supported
*
* @return UserInterface
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof UserToken) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', \get_class($user))
);
}

return $this->loadUserByUsername($user->getUsername());
}

/**
* Loads the user for the given username.
*
* This method must throw UsernameNotFoundException if the user is not
* found.
*
* @param string $username The username
*
* @throws UsernameNotFoundException if the user is not found
*
* @return UserInterface
*/
public function loadUserByUsername($username)
{
/** @var ConstructionManager $user */
$user = $this->registry->getRepository('App:ConstructionManager')->findOneBy(['email' => $username]);
if ($user !== null) {
return new UserToken($user);
}

throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist in CustomerUserProvider.', $username)
);
}

/**
* Whether this provider supports the given user class.
*
* @param string $class
*
* @return bool
*/
public function supportsClass($class)
{
return $class === UserToken::class;
}
}
115 changes: 115 additions & 0 deletions src/Security/Model/UserToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

/*
* This file is part of the mangel.io project.
*
* (c) Florian Moser <git@famoser.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace App\Security\Model;

use Symfony\Component\Security\Core\User\UserInterface;

class UserToken implements UserInterface
{
/**
* @var (Role|string)[]
*/
private $roles;

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

/**
* @var string|null
*/
private $salt;

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

/**
* UserToken constructor.
*
* @param UserInterface $user
*/
public function __construct(UserInterface $user)
{
$this->roles = $user->getRoles();
$this->password = $user->getPassword();
$this->salt = $user->getSalt();
$this->username = $user->getUsername();
}

/**
* Returns the roles granted to the user.
*
* public function getRoles()
* {
* return array('ROLE_USER');
* }
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* @return (Role|string)[] The user roles
*/
public function getRoles()
{
return $this->roles;
}

/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* @return string The password
*/
public function getPassword()
{
return $this->password;
}

/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* @return string|null The salt
*/
public function getSalt()
{
return $this->salt;
}

/**
* Returns the username used to authenticate the user.
*
* @return string The username
*/
public function getUsername()
{
return $this->roles;
}

/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// no credentials here; hence do not need to clear
}
}

0 comments on commit e5c2afe

Please sign in to comment.