Skip to content

Commit 79b804f

Browse files
Merge branch '3.4' into 4.0
* 3.4: [VarDumper] Fix dumping ArrayObject and ArrayIterator instances [ProxyManagerBridge] Fixed support of private services [Cache] Fix typo in comment. Fix bad method call with guard authentication + session migration
2 parents b7d04a8 + be700ae commit 79b804f

File tree

12 files changed

+173
-33
lines changed

12 files changed

+173
-33
lines changed

src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode =
5454
$instantiation = 'return';
5555

5656
if ($definition->isShared()) {
57-
$instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() || !method_exists(ContainerBuilder::class, 'addClassResource') ? 'services' : 'privates', $id);
57+
$instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', $id);
5858
}
5959

6060
if (null === $factoryCode) {

src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,34 @@ public function testGetProxyFactoryCode()
8080
);
8181
}
8282

83+
/**
84+
* @dataProvider getPrivatePublicDefinitions
85+
*/
86+
public function testCorrectAssigning(Definition $definition, $access)
87+
{
88+
$definition->setLazy(true);
89+
90+
$code = $this->dumper->getProxyFactoryCode($definition, 'foo', '$this->getFoo2Service(false)');
91+
92+
$this->assertStringMatchesFormat('%A$this->'.$access.'[\'foo\'] = %A', $code);
93+
}
94+
95+
public function getPrivatePublicDefinitions()
96+
{
97+
return array(
98+
array(
99+
(new Definition(__CLASS__))
100+
->setPublic(false),
101+
'privates',
102+
),
103+
array(
104+
(new Definition(__CLASS__))
105+
->setPublic(true),
106+
'services',
107+
),
108+
);
109+
}
110+
83111
/**
84112
* @expectedException \InvalidArgumentException
85113
* @expectedExceptionMessage Missing factory code to construct the service "foo".

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class SecurityExtension extends Extension
4444
private $factories = array();
4545
private $userProviderFactories = array();
4646
private $expressionLanguage;
47+
private $statelessFirewallKeys = array();
4748

4849
public function __construct()
4950
{
@@ -103,6 +104,9 @@ public function load(array $configs, ContainerBuilder $container)
103104
$this->createAuthorization($config, $container);
104105
$this->createRoleHierarchy($config, $container);
105106

107+
$container->getDefinition('security.authentication.guard_handler')
108+
->replaceArgument(2, $this->statelessFirewallKeys);
109+
106110
if ($config['encoders']) {
107111
$this->createEncoders($config['encoders'], $container);
108112
}
@@ -274,6 +278,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
274278
$listeners[] = new Reference($this->createContextListener($container, $contextKey));
275279
$sessionStrategyId = 'security.authentication.session_strategy';
276280
} else {
281+
$this->statelessFirewallKeys[] = $id;
277282
$sessionStrategyId = 'security.authentication.session_strategy_noop';
278283
}
279284
$container->setAlias(new Alias('security.authentication.session_strategy.'.$id, false), $sessionStrategyId);

src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
>
1313
<argument type="service" id="security.token_storage" />
1414
<argument type="service" id="event_dispatcher" on-invalid="null" />
15+
<argument /> <!-- stateless firewall keys -->
16+
<call method="setSessionAuthenticationStrategy">
17+
<argument type="service" id="security.authentication.session_strategy" />
18+
</call>
1519
</service>
1620

1721
<service id="Symfony\Component\Security\Guard\GuardAuthenticatorHandler" alias="security.authentication.guard_handler" />

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,35 @@ public function testDisableRoleHierarchyVoter()
123123
$this->assertFalse($container->hasDefinition('security.access.role_hierarchy_voter'));
124124
}
125125

126+
public function testGuardHandlerIsPassedStatelessFirewalls()
127+
{
128+
$container = $this->getRawContainer();
129+
130+
$container->loadFromExtension('security', array(
131+
'providers' => array(
132+
'default' => array('id' => 'foo'),
133+
),
134+
135+
'firewalls' => array(
136+
'some_firewall' => array(
137+
'pattern' => '^/admin',
138+
'http_basic' => null,
139+
'logout_on_user_change' => true,
140+
),
141+
'stateless_firewall' => array(
142+
'pattern' => '/.*',
143+
'stateless' => true,
144+
'http_basic' => null,
145+
'logout_on_user_change' => true,
146+
),
147+
),
148+
));
149+
150+
$container->compile();
151+
$definition = $container->getDefinition('security.authentication.guard_handler');
152+
$this->assertSame(array('stateless_firewall'), $definition->getArgument(2));
153+
}
154+
126155
public function testSwitchUserNotStatelessOnStatelessFirewall()
127156
{
128157
$container = $this->getRawContainer();

src/Symfony/Component/Cache/Traits/RedisTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ protected function doHave($id)
197197
protected function doClear($namespace)
198198
{
199199
// When using a native Redis cluster, clearing the cache is done by versioning in AbstractTrait::clear().
200-
// This means old keys are not really removed until they expire and may need gargage collection.
200+
// This means old keys are not really removed until they expire and may need garbage collection.
201201

202202
$cleared = true;
203203
$hosts = array($this->redis);

src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ private function executeGuardAuthenticator($uniqueGuardKey, AuthenticatorInterfa
126126
}
127127

128128
// sets the token on the token storage, etc
129-
$this->guardHandler->authenticateWithToken($token, $request);
129+
$this->guardHandler->authenticateWithToken($token, $request, $this->providerKey);
130130
} catch (AuthenticationException $e) {
131131
// oh no! Authentication failed!
132132

src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,28 @@ class GuardAuthenticatorHandler
3737
private $tokenStorage;
3838
private $dispatcher;
3939
private $sessionStrategy;
40+
private $statelessProviderKeys;
4041

41-
public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher = null)
42+
/**
43+
* @param array $statelessProviderKeys An array of provider/firewall keys that are "stateless" and so do not need the session migrated on success
44+
*/
45+
public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher = null, array $statelessProviderKeys = array())
4246
{
4347
$this->tokenStorage = $tokenStorage;
4448
$this->dispatcher = $eventDispatcher;
49+
$this->statelessProviderKeys = $statelessProviderKeys;
4550
}
4651

4752
/**
4853
* Authenticates the given token in the system.
54+
*
55+
* @param string $providerKey The name of the provider/firewall being used for authentication
4956
*/
50-
public function authenticateWithToken(TokenInterface $token, Request $request)
57+
public function authenticateWithToken(TokenInterface $token, Request $request/*, string $providerKey */)
5158
{
52-
$this->migrateSession($request, $token);
59+
$providerKey = \func_num_args() > 2 ? func_get_arg(2) : null;
60+
61+
$this->migrateSession($request, $token, $providerKey);
5362
$this->tokenStorage->setToken($token);
5463

5564
if (null !== $this->dispatcher) {
@@ -86,7 +95,7 @@ public function authenticateUserAndHandleSuccess(UserInterface $user, Request $r
8695
// create an authenticated token for the User
8796
$token = $authenticator->createAuthenticatedToken($user, $providerKey);
8897
// authenticate this in the system
89-
$this->authenticateWithToken($token, $request);
98+
$this->authenticateWithToken($token, $request, $providerKey);
9099

91100
// return the success metric
92101
return $this->handleAuthenticationSuccess($token, $request, $authenticator, $providerKey);
@@ -121,9 +130,9 @@ public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyIn
121130
$this->sessionStrategy = $sessionStrategy;
122131
}
123132

124-
private function migrateSession(Request $request, TokenInterface $token)
133+
private function migrateSession(Request $request, TokenInterface $token, $providerKey)
125134
{
126-
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) {
135+
if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession() || \in_array($providerKey, $this->statelessProviderKeys, true)) {
127136
return;
128137
}
129138

src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@ public function testSessionStrategyIsCalled()
144144
$handler->authenticateWithToken($this->token, $this->request);
145145
}
146146

147+
public function testSessionStrategyIsNotCalledWhenStateless()
148+
{
149+
$this->configurePreviousSession();
150+
151+
$this->sessionStrategy->expects($this->never())
152+
->method('onAuthentication');
153+
154+
$handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher, array('some_provider_key'));
155+
$handler->setSessionAuthenticationStrategy($this->sessionStrategy);
156+
$handler->authenticateWithToken($this->token, $this->request, 'some_provider_key');
157+
}
158+
147159
protected function setUp()
148160
{
149161
$this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();

src/Symfony/Component/VarDumper/Caster/SplCaster.php

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,12 @@ class SplCaster
2929

3030
public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested)
3131
{
32-
$prefix = Caster::PREFIX_VIRTUAL;
33-
$class = $stub->class;
34-
$flags = $c->getFlags();
35-
36-
$b = array(
37-
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
38-
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
39-
$prefix.'iteratorClass' => new ClassStub($c->getIteratorClass()),
40-
$prefix.'storage' => $c->getArrayCopy(),
41-
);
42-
43-
if ('ArrayObject' === $class) {
44-
$a = $b;
45-
} else {
46-
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
47-
$c->setFlags(\ArrayObject::STD_PROP_LIST);
48-
$a = Caster::castObject($c, $class);
49-
$c->setFlags($flags);
50-
}
51-
52-
$a += $b;
53-
}
32+
return self::castSplArray($c, $a, $stub, $isNested);
33+
}
5434

55-
return $a;
35+
public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, $isNested)
36+
{
37+
return self::castSplArray($c, $a, $stub, $isNested);
5638
}
5739

5840
public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested)
@@ -186,7 +168,7 @@ public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $s
186168

187169
$clone = clone $c;
188170
foreach ($clone as $obj) {
189-
$storage[spl_object_hash($obj)] = array(
171+
$storage[] = array(
190172
'object' => $obj,
191173
'info' => $clone->getInfo(),
192174
);
@@ -205,4 +187,27 @@ public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub
205187

206188
return $a;
207189
}
190+
191+
private static function castSplArray($c, array $a, Stub $stub, $isNested)
192+
{
193+
$prefix = Caster::PREFIX_VIRTUAL;
194+
$class = $stub->class;
195+
$flags = $c->getFlags();
196+
197+
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
198+
$c->setFlags(\ArrayObject::STD_PROP_LIST);
199+
$a = Caster::castObject($c, $class);
200+
$c->setFlags($flags);
201+
}
202+
$a += array(
203+
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
204+
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
205+
);
206+
if ($c instanceof \ArrayObject) {
207+
$a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass());
208+
}
209+
$a[$prefix.'storage'] = $c->getArrayCopy();
210+
211+
return $a;
212+
}
208213
}

0 commit comments

Comments
 (0)