1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the user Provider class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\MVC\Symfony\Security\User; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\API\Repository\Exceptions\NotFoundException; |
12
|
|
|
use eZ\Publish\API\Repository\Repository; |
13
|
|
|
use eZ\Publish\Core\MVC\Symfony\Security\User; |
14
|
|
|
use eZ\Publish\Core\MVC\Symfony\Security\UserInterface; |
15
|
|
|
use eZ\Publish\Core\MVC\Symfony\Security\ReferenceUserInterface; |
16
|
|
|
use eZ\Publish\API\Repository\Values\User\User as APIUser; |
17
|
|
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; |
18
|
|
|
use Symfony\Component\Security\Core\User\UserInterface as CoreUserInterface; |
19
|
|
|
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; |
20
|
|
|
|
21
|
|
|
class Provider implements APIUserProviderInterface |
22
|
|
|
{ |
23
|
|
|
/** @var \eZ\Publish\API\Repository\Repository */ |
24
|
|
|
protected $repository; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @param \eZ\Publish\API\Repository\Repository $repository |
28
|
|
|
*/ |
29
|
|
|
public function __construct(Repository $repository) |
30
|
|
|
{ |
31
|
|
|
$this->repository = $repository; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Loads the user for the given user ID. |
36
|
|
|
* $user can be either the user ID or an instance of \eZ\Publish\Core\MVC\Symfony\Security\User |
37
|
|
|
* (anonymous user we try to check access via SecurityContext::isGranted()). |
38
|
|
|
* |
39
|
|
|
* @param string|\eZ\Publish\Core\MVC\Symfony\Security\User $user Either the user ID to load an instance of User object. A value of -1 represents an anonymous user. |
40
|
|
|
* |
41
|
|
|
* @return \eZ\Publish\Core\MVC\Symfony\Security\UserInterface |
42
|
|
|
* |
43
|
|
|
* @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException if the user is not found |
44
|
|
|
*/ |
45
|
|
|
public function loadUserByUsername($user) |
46
|
|
|
{ |
47
|
|
|
try { |
48
|
|
|
// SecurityContext always tries to authenticate anonymous users when checking granted access. |
49
|
|
|
// In that case $user is an instance of \eZ\Publish\Core\MVC\Symfony\Security\User. |
50
|
|
|
// We don't need to reload the user here. |
51
|
|
|
if ($user instanceof UserInterface) { |
52
|
|
|
return $user; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
return $this->createSecurityUser( |
56
|
|
|
$this->repository->getUserService()->loadUserByLogin($user) |
57
|
|
|
); |
58
|
|
|
} catch (NotFoundException $e) { |
59
|
|
|
throw new UsernameNotFoundException($e->getMessage(), 0, $e); |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Refreshes the user for the account interface. |
65
|
|
|
* |
66
|
|
|
* It is up to the implementation to decide if the user data should be |
67
|
|
|
* totally reloaded (e.g. from the database), or if the UserInterface |
68
|
|
|
* object can just be merged into some internal array of users / identity |
69
|
|
|
* map. |
70
|
|
|
* |
71
|
|
|
* @param \Symfony\Component\Security\Core\User\UserInterface $user |
72
|
|
|
* |
73
|
|
|
* @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException |
74
|
|
|
* |
75
|
|
|
* @return \Symfony\Component\Security\Core\User\UserInterface |
76
|
|
|
*/ |
77
|
|
|
public function refreshUser(CoreUserInterface $user) |
78
|
|
|
{ |
79
|
|
|
if (!$user instanceof UserInterface) { |
80
|
|
|
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
try { |
84
|
|
|
$refreshedAPIUser = $this->repository->getUserService()->loadUser( |
85
|
|
|
$user instanceof ReferenceUserInterface ? |
86
|
|
|
$user->getAPIUserReference()->getUserId() : |
87
|
|
|
$user->getAPIUser()->id |
88
|
|
|
); |
89
|
|
|
$user->setAPIUser($refreshedAPIUser); |
|
|
|
|
90
|
|
|
$this->repository->setCurrentUser($refreshedAPIUser); |
|
|
|
|
91
|
|
|
|
92
|
|
|
return $user; |
93
|
|
|
} catch (NotFoundException $e) { |
94
|
|
|
throw new UsernameNotFoundException($e->getMessage(), 0, $e); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Whether this provider supports the given user class. |
100
|
|
|
* |
101
|
|
|
* @param string $class |
102
|
|
|
* |
103
|
|
|
* @return bool |
104
|
|
|
*/ |
105
|
|
|
public function supportsClass($class) |
106
|
|
|
{ |
107
|
|
|
$supportedClass = 'eZ\\Publish\\Core\\MVC\\Symfony\\Security\\User'; |
108
|
|
|
|
109
|
|
|
return $class === $supportedClass || is_subclass_of($class, $supportedClass); |
|
|
|
|
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Loads a regular user object, usable by Symfony Security component, from a user object returned by Public API. |
114
|
|
|
* |
115
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\User $apiUser |
116
|
|
|
* |
117
|
|
|
* @return \eZ\Publish\Core\MVC\Symfony\Security\User |
118
|
|
|
*/ |
119
|
|
|
public function loadUserByAPIUser(APIUser $apiUser) |
120
|
|
|
{ |
121
|
|
|
return $this->createSecurityUser($apiUser); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Creates user object, usable by Symfony Security component, from a user object returned by Public API. |
126
|
|
|
* |
127
|
|
|
* @param \eZ\Publish\API\Repository\Values\User\User $apiUser |
128
|
|
|
* |
129
|
|
|
* @return \eZ\Publish\Core\MVC\Symfony\Security\User |
130
|
|
|
*/ |
131
|
|
|
private function createSecurityUser(APIUser $apiUser): User |
132
|
|
|
{ |
133
|
|
|
$isPasswordExpired = $this->repository->getUserService()->getPasswordInfo($apiUser)->isPasswordExpired(); |
134
|
|
|
|
135
|
|
|
return new User( |
136
|
|
|
$apiUser, |
137
|
|
|
['ROLE_USER'], |
138
|
|
|
!$isPasswordExpired |
139
|
|
|
); |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.