1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace SixtyEightPublishers\User\DoctrineIdentity; |
6
|
|
|
|
7
|
|
|
use Nette\SmartObject; |
8
|
|
|
use Nette\Security\IIdentity; |
9
|
|
|
use Nette\Security\IUserStorage; |
10
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
11
|
|
|
use Doctrine\Persistence\Mapping\MappingException; |
12
|
|
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; |
13
|
|
|
use SixtyEightPublishers\User\DoctrineIdentity\Event\IdentityNotFoundEvent; |
14
|
|
|
use SixtyEightPublishers\User\DoctrineIdentity\Exception\UnimplementedMethodException; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @method void onIdentityNotFound(IdentityReference $identityReference) |
18
|
|
|
*/ |
19
|
|
|
final class UserStorageProxy implements IUserStorage |
20
|
|
|
{ |
21
|
|
|
use SmartObject; |
22
|
|
|
|
23
|
|
|
/** @var \Nette\Security\IUserStorage */ |
24
|
|
|
private $userStorage; |
25
|
|
|
|
26
|
|
|
/** @var \Doctrine\ORM\EntityManagerInterface */ |
27
|
|
|
private $em; |
28
|
|
|
|
29
|
|
|
/** @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface */ |
30
|
|
|
private $eventDispatcher; |
31
|
|
|
|
32
|
|
|
/** @var \Nette\Security\Identity|NULL|bool */ |
33
|
|
|
private $currentIdentity = FALSE; |
34
|
|
|
|
35
|
|
|
/** @var callable[] */ |
36
|
|
|
public $onIdentityNotFound = []; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @param \Nette\Security\IUserStorage $userStorage |
40
|
|
|
* @param \Doctrine\ORM\EntityManagerInterface $em |
41
|
|
|
* @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher |
42
|
|
|
*/ |
43
|
|
|
public function __construct(IUserStorage $userStorage, EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher) |
44
|
|
|
{ |
45
|
|
|
$this->userStorage = $userStorage; |
46
|
|
|
$this->em = $em; |
47
|
|
|
$this->eventDispatcher = $eventDispatcher; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* For compatibility with default implementation Nette\Http\UserStorage |
52
|
|
|
* |
53
|
|
|
* @param string $namespace |
54
|
|
|
* |
55
|
|
|
* @return \SixtyEightPublishers\User\DoctrineIdentity\UserStorageProxy |
56
|
|
|
* @throws \SixtyEightPublishers\User\DoctrineIdentity\Exception\UnimplementedMethodException |
57
|
|
|
*/ |
58
|
|
|
public function setNamespace(string $namespace): self |
59
|
|
|
{ |
60
|
|
|
if (!is_callable([$this->userStorage, 'setNamespace'])) { |
61
|
|
|
throw UnimplementedMethodException::unimplementedMethod(get_class($this->userStorage), 'setNamespace'); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$this->userStorage->setNamespace($namespace); |
65
|
|
|
|
66
|
|
|
return $this; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* For compatibility with default implementation Nette\Http\UserStorage |
71
|
|
|
* |
72
|
|
|
* @return string |
73
|
|
|
* @throws \SixtyEightPublishers\User\DoctrineIdentity\Exception\UnimplementedMethodException |
74
|
|
|
*/ |
75
|
|
|
public function getNamespace(): string |
76
|
|
|
{ |
77
|
|
|
if (!is_callable([$this->userStorage, 'getNamespace'])) { |
78
|
|
|
throw Exception\UnimplementedMethodException::unimplementedMethod(get_class($this->userStorage), 'getNamespace'); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
return $this->userStorage->getNamespace(); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/************ interface \Nette\Security\IUserStorage ************/ |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* {@inheritdoc} |
88
|
|
|
*/ |
89
|
|
|
public function setAuthenticated($state): self |
90
|
|
|
{ |
91
|
|
|
$this->userStorage->setAuthenticated($state); |
92
|
|
|
|
93
|
|
|
return $this; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* {@inheritdoc} |
98
|
|
|
*/ |
99
|
|
|
public function isAuthenticated(): bool |
100
|
|
|
{ |
101
|
|
|
# Get the identity as first. If the entity is not found then the user can't be authenticated. |
102
|
|
|
$this->getIdentity(); |
103
|
|
|
|
104
|
|
|
return $this->userStorage->isAuthenticated(); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* {@inheritdoc} |
109
|
|
|
*/ |
110
|
|
|
public function setIdentity(?IIdentity $identity = NULL): self |
111
|
|
|
{ |
112
|
|
|
if (NULL !== $identity) { |
113
|
|
|
try { |
114
|
|
|
$metadata = $this->em->getMetadataFactory()->getMetadataFor(get_class($identity)); |
115
|
|
|
|
116
|
|
|
$identity = new IdentityReference( |
117
|
|
|
$metadata->getName(), |
118
|
|
|
$metadata->getIdentifierValues($identity) |
119
|
|
|
); |
120
|
|
|
} catch (MappingException $e) { |
|
|
|
|
121
|
|
|
# an empty catch block because we can't test if the MetadataFactory contains a metadata for identity's classname. |
122
|
|
|
# The classname can be a Doctrine Proxy and the method `MetadataFactory::hasMetadataFor()` doesn't convert Proxy's classname into real classname. |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
$this->userStorage->setIdentity($identity); |
127
|
|
|
$this->currentIdentity = FALSE; |
128
|
|
|
|
129
|
|
|
return $this; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* {@inheritdoc} |
134
|
|
|
*/ |
135
|
|
|
public function getIdentity(): ?IIdentity |
136
|
|
|
{ |
137
|
|
|
if (FALSE !== $this->currentIdentity) { |
138
|
|
|
return $this->currentIdentity; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
$identityReference = $this->userStorage->getIdentity(); |
142
|
|
|
|
143
|
|
|
if (!$identityReference instanceof IdentityReference) { |
144
|
|
|
return $identityReference; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$identity = $this->em->find($identityReference->getClassName(), $identityReference->getId()); |
148
|
|
|
|
149
|
|
|
if (!$identity instanceof IIdentity) { |
|
|
|
|
150
|
|
|
$identity = NULL; |
151
|
|
|
|
152
|
|
|
$this->setAuthenticated(FALSE); |
153
|
|
|
$this->setIdentity($identity); |
154
|
|
|
|
155
|
|
|
$namespace = $this->getNamespace(); |
156
|
|
|
|
157
|
|
|
$this->eventDispatcher->dispatch(new IdentityNotFoundEvent($identityReference, empty($namespace) ? NULL : $namespace), IdentityNotFoundEvent::NAME); |
158
|
|
|
$this->onIdentityNotFound($identityReference); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
return $this->currentIdentity = $identity; |
|
|
|
|
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* {@inheritdoc} |
166
|
|
|
*/ |
167
|
|
|
public function setExpiration($time, $flags = 0): self |
168
|
|
|
{ |
169
|
|
|
$this->userStorage->setExpiration($time, $flags); |
170
|
|
|
|
171
|
|
|
return $this; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* {@inheritdoc} |
176
|
|
|
*/ |
177
|
|
|
public function getLogoutReason(): ?int |
178
|
|
|
{ |
179
|
|
|
return $this->userStorage->getLogoutReason(); |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.