Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit 2f9775b

Browse files
author
Robin Chalas
committed
Move SecurityUserValueResolver to security-http
1 parent 8999299 commit 2f9775b

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* The `ContextListener::setLogoutOnUserChange()` method is deprecated and will be removed in 5.0.
8+
* added `UserValueResolver`.
89

910
4.0.0
1011
-----

Http/Controller/UserValueResolver.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Controller;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
16+
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
17+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
18+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19+
use Symfony\Component\Security\Core\User\UserInterface;
20+
21+
/**
22+
* Supports the argument type of {@see UserInterface}.
23+
*
24+
* @author Iltar van der Berg <[email protected]>
25+
*/
26+
final class UserValueResolver implements ArgumentValueResolverInterface
27+
{
28+
private $tokenStorage;
29+
30+
public function __construct(TokenStorageInterface $tokenStorage)
31+
{
32+
$this->tokenStorage = $tokenStorage;
33+
}
34+
35+
public function supports(Request $request, ArgumentMetadata $argument)
36+
{
37+
// only security user implementations are supported
38+
if (UserInterface::class !== $argument->getType()) {
39+
return false;
40+
}
41+
42+
$token = $this->tokenStorage->getToken();
43+
if (!$token instanceof TokenInterface) {
44+
return false;
45+
}
46+
47+
$user = $token->getUser();
48+
49+
// in case it's not an object we cannot do anything with it; E.g. "anon."
50+
return $user instanceof UserInterface;
51+
}
52+
53+
public function resolve(Request $request, ArgumentMetadata $argument)
54+
{
55+
yield $this->tokenStorage->getToken()->getUser();
56+
}
57+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Tests\Controller;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
17+
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
18+
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
19+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
20+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
21+
use Symfony\Component\Security\Core\User\UserInterface;
22+
use Symfony\Component\Security\Http\Controller\UserValueResolver;
23+
24+
class UserValueResolverTest extends TestCase
25+
{
26+
public function testResolveNoToken()
27+
{
28+
$tokenStorage = new TokenStorage();
29+
$resolver = new UserValueResolver($tokenStorage);
30+
$metadata = new ArgumentMetadata('foo', UserInterface::class, false, false, null);
31+
32+
$this->assertFalse($resolver->supports(Request::create('/'), $metadata));
33+
}
34+
35+
public function testResolveNoUser()
36+
{
37+
$mock = $this->getMockBuilder(UserInterface::class)->getMock();
38+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
39+
$tokenStorage = new TokenStorage();
40+
$tokenStorage->setToken($token);
41+
42+
$resolver = new UserValueResolver($tokenStorage);
43+
$metadata = new ArgumentMetadata('foo', get_class($mock), false, false, null);
44+
45+
$this->assertFalse($resolver->supports(Request::create('/'), $metadata));
46+
}
47+
48+
public function testResolveWrongType()
49+
{
50+
$tokenStorage = new TokenStorage();
51+
$resolver = new UserValueResolver($tokenStorage);
52+
$metadata = new ArgumentMetadata('foo', null, false, false, null);
53+
54+
$this->assertFalse($resolver->supports(Request::create('/'), $metadata));
55+
}
56+
57+
public function testResolve()
58+
{
59+
$user = $this->getMockBuilder(UserInterface::class)->getMock();
60+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
61+
$token->expects($this->any())->method('getUser')->willReturn($user);
62+
$tokenStorage = new TokenStorage();
63+
$tokenStorage->setToken($token);
64+
65+
$resolver = new UserValueResolver($tokenStorage);
66+
$metadata = new ArgumentMetadata('foo', UserInterface::class, false, false, null);
67+
68+
$this->assertTrue($resolver->supports(Request::create('/'), $metadata));
69+
$this->assertSame(array($user), iterator_to_array($resolver->resolve(Request::create('/'), $metadata)));
70+
}
71+
72+
public function testIntegration()
73+
{
74+
$user = $this->getMockBuilder(UserInterface::class)->getMock();
75+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
76+
$token->expects($this->any())->method('getUser')->willReturn($user);
77+
$tokenStorage = new TokenStorage();
78+
$tokenStorage->setToken($token);
79+
80+
$argumentResolver = new ArgumentResolver(null, array(new UserValueResolver($tokenStorage)));
81+
$this->assertSame(array($user), $argumentResolver->getArguments(Request::create('/'), function (UserInterface $user) {}));
82+
}
83+
84+
public function testIntegrationNoUser()
85+
{
86+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
87+
$tokenStorage = new TokenStorage();
88+
$tokenStorage->setToken($token);
89+
90+
$argumentResolver = new ArgumentResolver(null, array(new UserValueResolver($tokenStorage), new DefaultValueResolver()));
91+
$this->assertSame(array(null), $argumentResolver->getArguments(Request::create('/'), function (UserInterface $user = null) {}));
92+
}
93+
}
94+
95+
abstract class DummyUser implements UserInterface
96+
{
97+
}
98+
99+
abstract class DummySubUser extends DummyUser
100+
{
101+
}

0 commit comments

Comments
 (0)