Skip to content

Commit 60d6ce1

Browse files
bug symfony#50813 [DoctrineBridge] Load refreshed user proxy (MatTheCat)
This PR was merged into the 5.4 branch. Discussion ---------- [DoctrineBridge] Load refreshed user proxy | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix symfony#50758 | License | MIT | Doc PR | N/A When [exiting impersonation](https://github.com/symfony/symfony/blob/529973b88db84aee4e962b2ba8bb1838bbbe6a38/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php#L210), the impersonator get refreshed in the original token. Problem is, the refreshed user can be a proxy if it is referenced by the impersonated. In that case, all its properties (except identifiers) will be `null` when it is unserialised by the `ContextListener`. The refreshed user data will be needed anyways, so loading proxies in `EntityUserProvider::refreshUser` should not impact performance. Commits ------- 6f53d54 [DoctrineBridge] Load refreshed user proxy
2 parents 9c1dedb + 6f53d54 commit 60d6ce1

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\Persistence\Mapping\ClassMetadata;
1616
use Doctrine\Persistence\ObjectManager;
1717
use Doctrine\Persistence\ObjectRepository;
18+
use Doctrine\Persistence\Proxy;
1819
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
1920
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
2021
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
@@ -117,6 +118,10 @@ public function refreshUser(UserInterface $user)
117118
}
118119
}
119120

121+
if ($refreshedUser instanceof Proxy && !$refreshedUser->__isInitialized()) {
122+
$refreshedUser->__load();
123+
}
124+
120125
return $refreshedUser;
121126
}
122127

src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Doctrine\Persistence\ManagerRegistry;
1717
use Doctrine\Persistence\ObjectManager;
1818
use Doctrine\Persistence\ObjectRepository;
19+
use Doctrine\Persistence\Proxy;
1920
use PHPUnit\Framework\TestCase;
2021
use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider;
2122
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
@@ -197,6 +198,27 @@ public function testPasswordUpgrades()
197198
$provider->upgradePassword($user, 'foobar');
198199
}
199200

201+
public function testRefreshedUserProxyIsLoaded()
202+
{
203+
$em = DoctrineTestHelper::createTestEntityManager();
204+
$this->createSchema($em);
205+
206+
$user = new User(1, 1, 'user1');
207+
208+
$em->persist($user);
209+
$em->flush();
210+
$em->clear();
211+
212+
// store a proxy in the identity map
213+
$em->getReference(User::class, ['id1' => 1, 'id2' => 1]);
214+
215+
$provider = new EntityUserProvider($this->getManager($em), User::class);
216+
$refreshedUser = $provider->refreshUser($user);
217+
218+
$this->assertInstanceOf(Proxy::class, $refreshedUser);
219+
$this->assertTrue($refreshedUser->__isInitialized());
220+
}
221+
200222
private function getManager($em, $name = null)
201223
{
202224
$manager = $this->createMock(ManagerRegistry::class);

0 commit comments

Comments
 (0)