-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[DX] Added CurrentUserProvider service #14407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Security\Core\Tests\User; | ||
|
||
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; | ||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | ||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; | ||
use Symfony\Component\Security\Core\User\CurrentUserProvider; | ||
use Symfony\Component\Security\Core\User\User; | ||
|
||
class CurrentUserProviderTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
public function testGetUser() | ||
{ | ||
$user = new User('user', 'pass'); | ||
$token = new UsernamePasswordToken($user, 'pass', 'default', array('ROLE_USER')); | ||
|
||
$service = new CurrentUserProvider($this->getTokenStorage($token)); | ||
|
||
$this->assertSame($service->getUser(), $user); | ||
} | ||
|
||
public function testGetUserAnonymousUserConvertedToNull() | ||
{ | ||
$token = new AnonymousToken('default', 'anon.'); | ||
|
||
$service = new CurrentUserProvider($this->getTokenStorage($token)); | ||
|
||
$this->assertNull($service->getUser()); | ||
} | ||
|
||
public function testGetUserWithEmptyTokenStorage() | ||
{ | ||
$service = new CurrentUserProvider($this->getTokenStorage(null)); | ||
|
||
$this->assertNull($service->getUser()); | ||
} | ||
|
||
/** | ||
* @param $token | ||
* | ||
* @return TokenStorageInterface | ||
*/ | ||
private function getTokenStorage($token = null) | ||
{ | ||
$tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage'); | ||
$tokenStorage | ||
->expects($this->once()) | ||
->method('getToken') | ||
->will($this->returnValue($token)); | ||
|
||
return $tokenStorage; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\Security\Core\User; | ||
|
||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | ||
|
||
/** | ||
* Current User Provider. | ||
* | ||
* This provider gives you the current logged in user. | ||
* | ||
* @author Tobias Nyholm <tobias.nyholm@gmail.com> | ||
*/ | ||
class CurrentUserProvider | ||
{ | ||
/** | ||
* @var TokenStorageInterface tokenStorage | ||
*/ | ||
private $tokenStorage; | ||
|
||
/** | ||
* @param TokenStorageInterface $tokenStorage | ||
*/ | ||
public function __construct(TokenStorageInterface $tokenStorage) | ||
{ | ||
$this->tokenStorage = $tokenStorage; | ||
} | ||
|
||
/** | ||
* Get a user from the Security Token Storage. | ||
* | ||
* @return mixed | ||
* | ||
* @see TokenInterface::getUser() | ||
*/ | ||
public function getUser() | ||
{ | ||
if (null === $token = $this->tokenStorage->getToken()) { | ||
return; | ||
} | ||
|
||
if (!is_object($user = $token->getUser())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 on this logic, even if user is not a string, it should return it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep a user is not necessarily represented by an object, it depend of implementation of token. (for example UsernamePasswordToken accept string representation of user to handle InMemoryUserProvider). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that some user representation might be a string. This PR is a refactor of the FrameworkBundle's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a mistake from FrameworkBundle so, this is why when we retrieve the current user from different way we obtains 'anon.' or null. |
||
// e.g. anonymous authentication | ||
return; | ||
} | ||
|
||
return $user; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's a good idea to add a class just to wrap the TokenStorage.
In my opinion, the token/user shouldn't be called in your application controller, they should only be used to identify the current user and can be used to fetch the information of the current user.
Next to all this, there is already a PR open in the sensio framework-extra-bundle repo regarding a ParamConverter to inject the current user. This is a cleaner solution in my opinion: sensiolabs/SensioFrameworkExtraBundle/pull/327
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not aware of that PR on SensiolabsFrameworkExtraBundle. But that is just for Controllers. This CurrentUserProvider service is meant to make it easier to get the logged in user in your other services.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion you should not bring that state to your services. You'll still need to check if the user is there and act on it. I think it's a far better solution to just inject the user if you need it in the method that you call. If you really need the user in a deep level of your services, then maybe you shouldn't be using the UserInterface for that.
Right now you're adding a class that does nothing more than removing some boiler plating code. It also makes services harder to use on the commandline. The current name
CurrentUserProvider
also implies that the service has a state, which it shouldn't have.I have a very big 👎 for this class as there are already other (better) solutions available.