Skip to content

Commit 20e21ef

Browse files
wouterjchalasr
authored andcommitted
[Security] Rename UserInterface::getUsername() to getUserIdentifier()
1 parent ab98b0a commit 20e21ef

38 files changed

+543
-269
lines changed

Authentication/AuthenticationProviderManager.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Security\Core\Exception\AuthenticationException;
2222
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
2323
use Symfony\Component\Security\Core\Exception\ProviderNotFoundException;
24+
use Symfony\Component\Security\Core\User\UserInterface;
2425
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2526

2627
// Help opcache.preload discover always-needed symbols
@@ -105,6 +106,11 @@ public function authenticate(TokenInterface $token)
105106
$this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($result), AuthenticationEvents::AUTHENTICATION_SUCCESS);
106107
}
107108

109+
// @deprecated since 5.3
110+
if ($user = $result->getUser() instanceof UserInterface && !method_exists($result->getUser(), 'getUserIdentifier')) {
111+
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($result->getUser()));
112+
}
113+
108114
return $result;
109115
}
110116

Authentication/Provider/DaoAuthenticationProvider.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
1717
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
1818
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
19-
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
19+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
2020
use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface;
2121
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
2222
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
@@ -108,23 +108,30 @@ protected function checkAuthentication(UserInterface $user, UsernamePasswordToke
108108
/**
109109
* {@inheritdoc}
110110
*/
111-
protected function retrieveUser(string $username, UsernamePasswordToken $token)
111+
protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token)
112112
{
113113
$user = $token->getUser();
114114
if ($user instanceof UserInterface) {
115115
return $user;
116116
}
117117

118118
try {
119-
$user = $this->userProvider->loadUserByUsername($username);
119+
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
120+
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
121+
$user = $this->userProvider->loadUserByIdentifier($userIdentifier);
122+
} else {
123+
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
124+
125+
$user = $this->userProvider->loadUserByUsername($userIdentifier);
126+
}
120127

121128
if (!$user instanceof UserInterface) {
122129
throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
123130
}
124131

125132
return $user;
126-
} catch (UsernameNotFoundException $e) {
127-
$e->setUsername($username);
133+
} catch (UserNotFoundException $e) {
134+
$e->setUserIdentifier($userIdentifier);
128135
throw $e;
129136
} catch (\Exception $e) {
130137
$e = new AuthenticationServiceException($e->getMessage(), 0, $e);

Authentication/Provider/LdapBindAuthenticationProvider.php

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
1717
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1818
use Symfony\Component\Security\Core\Exception\LogicException;
19-
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
19+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
2020
use Symfony\Component\Security\Core\User\UserCheckerInterface;
2121
use Symfony\Component\Security\Core\User\UserInterface;
2222
use Symfony\Component\Security\Core\User\UserProviderInterface;
@@ -38,7 +38,7 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
3838
private $searchDn;
3939
private $searchPassword;
4040

41-
public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, LdapInterface $ldap, string $dnString = '{username}', bool $hideUserNotFoundExceptions = true, string $searchDn = '', string $searchPassword = '')
41+
public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, LdapInterface $ldap, string $dnString = '{user_identifier}', bool $hideUserNotFoundExceptions = true, string $searchDn = '', string $searchPassword = '')
4242
{
4343
parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
4444

@@ -50,7 +50,7 @@ public function __construct(UserProviderInterface $userProvider, UserCheckerInte
5050
}
5151

5252
/**
53-
* Set a query string to use in order to find a DN for the username.
53+
* Set a query string to use in order to find a DN for the user identifier.
5454
*/
5555
public function setQueryString(string $queryString)
5656
{
@@ -60,21 +60,29 @@ public function setQueryString(string $queryString)
6060
/**
6161
* {@inheritdoc}
6262
*/
63-
protected function retrieveUser(string $username, UsernamePasswordToken $token)
63+
protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token)
6464
{
65-
if (AuthenticationProviderInterface::USERNAME_NONE_PROVIDED === $username) {
66-
throw new UsernameNotFoundException('Username can not be null.');
65+
if (AuthenticationProviderInterface::USERNAME_NONE_PROVIDED === $userIdentifier) {
66+
throw new UserNotFoundException('User identifier can not be null.');
6767
}
6868

69-
return $this->userProvider->loadUserByUsername($username);
69+
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
70+
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
71+
return $this->userProvider->loadUserByIdentifier($userIdentifier);
72+
} else {
73+
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
74+
75+
return $this->userProvider->loadUserByUsername($userIdentifier);
76+
}
7077
}
7178

7279
/**
7380
* {@inheritdoc}
7481
*/
7582
protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
7683
{
77-
$username = $token->getUsername();
84+
// @deprecated since 5.3, change to $token->getUserIdentifier() in 6.0
85+
$userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
7886
$password = $token->getCredentials();
7987

8088
if ('' === (string) $password) {
@@ -88,17 +96,17 @@ protected function checkAuthentication(UserInterface $user, UsernamePasswordToke
8896
} else {
8997
throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.');
9098
}
91-
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_FILTER);
92-
$query = str_replace('{username}', $username, $this->queryString);
99+
$userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_FILTER);
100+
$query = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->queryString);
93101
$result = $this->ldap->query($this->dnString, $query)->execute();
94102
if (1 !== $result->count()) {
95103
throw new BadCredentialsException('The presented username is invalid.');
96104
}
97105

98106
$dn = $result[0]->getDn();
99107
} else {
100-
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_DN);
101-
$dn = str_replace('{username}', $username, $this->dnString);
108+
$userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_DN);
109+
$dn = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->dnString);
102110
}
103111

104112
$this->ldap->bind($dn, $password);

Authentication/Provider/PreAuthenticatedAuthenticationProvider.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* This authentication provider will not perform any checks on authentication
2525
* requests, as they should already be pre-authenticated. However, the
2626
* UserProviderInterface implementation may still throw a
27-
* UsernameNotFoundException, for example.
27+
* UserNotFoundException, for example.
2828
*
2929
* @author Fabien Potencier <[email protected]>
3030
*/
@@ -54,7 +54,15 @@ public function authenticate(TokenInterface $token)
5454
throw new BadCredentialsException('No pre-authenticated principal found in request.');
5555
}
5656

57-
$user = $this->userProvider->loadUserByUsername($user);
57+
$userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
58+
// @deprecated since 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0
59+
if (method_exists($this->userProvider, 'loadUserByIdentifier')) {
60+
$user = $this->userProvider->loadUserByIdentifier($userIdentifier);
61+
} else {
62+
trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider));
63+
64+
$user = $this->userProvider->loadUserByUsername($userIdentifier);
65+
}
5866

5967
$this->userChecker->checkPostAuth($user);
6068

Authentication/Provider/RememberMeAuthenticationProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function authenticate(TokenInterface $token)
5151

5252
$user = $token->getUser();
5353

54-
if (!$token->getUser() instanceof UserInterface) {
54+
if (!$user instanceof UserInterface) {
5555
throw new LogicException(sprintf('Method "%s::getUser()" must return a "%s" instance, "%s" returned.', get_debug_type($token), UserInterface::class, get_debug_type($user)));
5656
}
5757

Authentication/Provider/UserAuthenticationProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Symfony\Component\Security\Core\Exception\AuthenticationException;
1818
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
1919
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
20-
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
20+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
2121
use Symfony\Component\Security\Core\User\UserCheckerInterface;
2222
use Symfony\Component\Security\Core\User\UserInterface;
2323

@@ -55,18 +55,18 @@ public function authenticate(TokenInterface $token)
5555
throw new AuthenticationException('The token is not supported by this authentication provider.');
5656
}
5757

58-
$username = $token->getUsername();
58+
$username = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
5959
if ('' === $username || null === $username) {
6060
$username = AuthenticationProviderInterface::USERNAME_NONE_PROVIDED;
6161
}
6262

6363
try {
6464
$user = $this->retrieveUser($username, $token);
65-
} catch (UsernameNotFoundException $e) {
65+
} catch (UserNotFoundException $e) {
6666
if ($this->hideUserNotFoundExceptions) {
6767
throw new BadCredentialsException('Bad credentials.', 0, $e);
6868
}
69-
$e->setUsername($username);
69+
$e->setUserIdentifier($username);
7070

7171
throw $e;
7272
}

Authentication/RememberMe/InMemoryTokenProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function updateToken(string $series, string $tokenValue, \DateTime $lastU
4545

4646
$token = new PersistentToken(
4747
$this->tokens[$series]->getClass(),
48-
$this->tokens[$series]->getUsername(),
48+
method_exists($this->tokens[$series], 'getUserIdentifier') ? $this->tokens[$series]->getUserIdentifier() : $this->tokens[$series]->getUsername(),
4949
$series,
5050
$tokenValue,
5151
$lastUsed

Authentication/RememberMe/PersistentToken.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@
1919
final class PersistentToken implements PersistentTokenInterface
2020
{
2121
private $class;
22-
private $username;
22+
private $userIdentifier;
2323
private $series;
2424
private $tokenValue;
2525
private $lastUsed;
2626

27-
public function __construct(string $class, string $username, string $series, string $tokenValue, \DateTime $lastUsed)
27+
public function __construct(string $class, string $userIdentifier, string $series, string $tokenValue, \DateTime $lastUsed)
2828
{
2929
if (empty($class)) {
3030
throw new \InvalidArgumentException('$class must not be empty.');
3131
}
32-
if ('' === $username) {
33-
throw new \InvalidArgumentException('$username must not be empty.');
32+
if ('' === $userIdentifier) {
33+
throw new \InvalidArgumentException('$userIdentifier must not be empty.');
3434
}
3535
if (empty($series)) {
3636
throw new \InvalidArgumentException('$series must not be empty.');
@@ -40,7 +40,7 @@ public function __construct(string $class, string $username, string $series, str
4040
}
4141

4242
$this->class = $class;
43-
$this->username = $username;
43+
$this->userIdentifier = $userIdentifier;
4444
$this->series = $series;
4545
$this->tokenValue = $tokenValue;
4646
$this->lastUsed = $lastUsed;
@@ -59,7 +59,14 @@ public function getClass(): string
5959
*/
6060
public function getUsername(): string
6161
{
62-
return $this->username;
62+
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
63+
64+
return $this->userIdentifier;
65+
}
66+
67+
public function getUserIdentifier(): string
68+
{
69+
return $this->userIdentifier;
6370
}
6471

6572
/**

Authentication/RememberMe/PersistentTokenInterface.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* Interface to be implemented by persistent token classes (such as
1616
* Doctrine entities representing a remember-me token).
1717
*
18+
* @method string getUserIdentifier() returns the identifier used to authenticate (e.g. their e-mailaddress or username)
19+
*
1820
* @author Johannes M. Schmitt <[email protected]>
1921
*/
2022
interface PersistentTokenInterface
@@ -26,13 +28,6 @@ interface PersistentTokenInterface
2628
*/
2729
public function getClass();
2830

29-
/**
30-
* Returns the username.
31-
*
32-
* @return string
33-
*/
34-
public function getUsername();
35-
3631
/**
3732
* Returns the series.
3833
*

Authentication/Token/AbstractToken.php

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,32 @@ public function getRoleNames(): array
5151
/**
5252
* {@inheritdoc}
5353
*/
54-
public function getUsername()
54+
public function getUsername(/* $legacy = true */)
5555
{
56+
if (1 === func_num_args() && false === func_get_arg(0)) {
57+
return null;
58+
}
59+
60+
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__);
61+
62+
if ($this->user instanceof UserInterface) {
63+
return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername();
64+
}
65+
66+
return (string) $this->user;
67+
}
68+
69+
public function getUserIdentifier(): string
70+
{
71+
// method returns "null" in non-legacy mode if not overriden
72+
$username = $this->getUsername(false);
73+
if (null !== $username) {
74+
trigger_deprecation('symfony/security-core', '5.3', 'Method "%s::getUsername()" is deprecated, override "getUserIdentifier()" instead.', get_debug_type($this));
75+
}
76+
5677
if ($this->user instanceof UserInterface) {
57-
return $this->user->getUsername();
78+
// @deprecated since 5.3, change to $user->getUserIdentifier() in 6.0
79+
return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername();
5880
}
5981

6082
return (string) $this->user;
@@ -234,7 +256,7 @@ public function __toString()
234256
$roles[] = $role;
235257
}
236258

237-
return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUsername(), json_encode($this->authenticated), implode(', ', $roles));
259+
return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUserIdentifier(), json_encode($this->authenticated), implode(', ', $roles));
238260
}
239261

240262
/**
@@ -283,7 +305,11 @@ private function hasUserChanged(UserInterface $user): bool
283305
return true;
284306
}
285307

286-
if ($this->user->getUsername() !== $user->getUsername()) {
308+
// @deprecated since Symfony 5.3, drop getUsername() in 6.0
309+
$userIdentifier = function ($user) {
310+
return method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername();
311+
};
312+
if ($userIdentifier($this->user) !== $userIdentifier($user)) {
287313
return true;
288314
}
289315

0 commit comments

Comments
 (0)