This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | declare(strict_types = 1); |
||
3 | |||
4 | /** |
||
5 | * Micro |
||
6 | * |
||
7 | * @author Raffael Sahli <[email protected]> |
||
8 | * @copyright Copyright (c) 2017 gyselroth GmbH (https://gyselroth.com) |
||
9 | * @license MIT https://opensource.org/licenses/MIT |
||
10 | */ |
||
11 | |||
12 | namespace Micro; |
||
13 | |||
14 | use \Micro\Auth\Exception; |
||
0 ignored issues
–
show
|
|||
15 | use \Micro\Auth\Adapter\AdapterInterface; |
||
16 | use \Micro\Auth\Identity; |
||
17 | use \Psr\Log\LoggerInterface; |
||
18 | use \Micro\Auth\AttributeMap; |
||
19 | use \Micro\Container\AdapterAwareInterface; |
||
20 | |||
21 | class Auth implements AdapterAwareInterface |
||
22 | { |
||
23 | /** |
||
24 | * Adapter |
||
25 | * |
||
26 | * @var array |
||
27 | */ |
||
28 | protected $adapter = []; |
||
29 | |||
30 | |||
31 | /** |
||
32 | * Identity |
||
33 | * |
||
34 | * @var Identity |
||
35 | */ |
||
36 | protected $identity; |
||
37 | |||
38 | |||
39 | /** |
||
40 | * Logger |
||
41 | * |
||
42 | * @var Logger |
||
43 | */ |
||
44 | protected $logger; |
||
45 | |||
46 | |||
47 | /** |
||
48 | * Identity class |
||
49 | * |
||
50 | * @var string |
||
51 | */ |
||
52 | protected $identity_class = Identity::class; |
||
53 | |||
54 | |||
55 | /** |
||
56 | * Attribute map class |
||
57 | * |
||
58 | * @var string |
||
59 | */ |
||
60 | protected $attribute_map_class = AttributeMap::class; |
||
61 | |||
62 | |||
63 | /** |
||
64 | * Initialize |
||
65 | * |
||
66 | * @param LoggerInterface $logger |
||
67 | * @param Iterable $config |
||
68 | * @return void |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Adding a
@return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.
Adding a Please refer to the PHP core documentation on constructors. ![]() |
|||
69 | */ |
||
70 | public function __construct(LoggerInterface $logger, ? Iterable $config = null) |
||
71 | { |
||
72 | $this->logger = $logger; |
||
0 ignored issues
–
show
It seems like
$logger of type object<Psr\Log\LoggerInterface> is incompatible with the declared type object<Micro\Logger> of property $logger .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
73 | $this->setOptions($config); |
||
74 | } |
||
75 | |||
76 | |||
77 | /** |
||
78 | * Set options |
||
79 | * |
||
80 | * @param Iterable $config |
||
81 | * @return Auth |
||
82 | */ |
||
83 | public function setOptions(? Iterable $config = null) : Auth |
||
84 | { |
||
85 | if ($config === null) { |
||
86 | return $this; |
||
87 | } |
||
88 | |||
89 | foreach ($config as $option => $value) { |
||
90 | switch ($option) { |
||
91 | case 'identity_class': |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
92 | case 'attribute_map_class': |
||
93 | $this->{$option} = (string)$value; |
||
94 | break; |
||
95 | case 'adapter': |
||
96 | foreach($value as $name => $adapter) { |
||
97 | $this->injectAdapter($name, $adapter); |
||
98 | } |
||
99 | break; |
||
100 | default: |
||
101 | throw new Exception('invalid option '.$option.' given'); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | return $this; |
||
106 | } |
||
107 | |||
108 | |||
109 | /** |
||
110 | * {@inheritDoc} |
||
111 | */ |
||
112 | public function hasAdapter(string $name): bool |
||
113 | { |
||
114 | return isset($this->adapter[$name]); |
||
115 | } |
||
116 | |||
117 | |||
118 | /** |
||
119 | * {@inheritDoc} |
||
120 | */ |
||
121 | public function getDefaultAdapter(): array |
||
122 | { |
||
123 | return []; |
||
124 | } |
||
125 | |||
126 | |||
127 | /** |
||
128 | * {@inheritDoc} |
||
129 | */ |
||
130 | public function injectAdapter($adapter, ?string $name=null) : AdapterAwareInterface |
||
131 | { |
||
132 | if(!($adapter instanceof AdapterInterface)) { |
||
133 | throw new Exception('adapter needs to implement AdapterInterface'); |
||
134 | } |
||
135 | |||
136 | if($name === null) { |
||
137 | $name = get_class($adapter); |
||
138 | } |
||
139 | |||
140 | $this->logger->debug('inject auth adapter ['.$name.'] of type ['.get_class($adapter).']', [ |
||
141 | 'category' => get_class($this) |
||
142 | ]); |
||
143 | |||
144 | if ($this->hasAdapter($name)) { |
||
145 | throw new Exception('auth adapter '.$name.' is already registered'); |
||
146 | } |
||
147 | |||
148 | $this->adapter[$name] = $adapter; |
||
149 | return $this; |
||
150 | } |
||
151 | |||
152 | |||
153 | /** |
||
154 | * {@inheritDoc} |
||
155 | */ |
||
156 | public function getAdapter(string $name) |
||
157 | { |
||
158 | if (!$this->hasAdapter($name)) { |
||
159 | throw new Exception('auth adapter '.$name.' is not registered'); |
||
160 | } |
||
161 | |||
162 | return $this->adapter[$name]; |
||
163 | } |
||
164 | |||
165 | |||
166 | /** |
||
167 | * {@inheritDoc} |
||
168 | */ |
||
169 | public function getAdapters(array $adapters = []): array |
||
170 | { |
||
171 | if (empty($adapter)) { |
||
0 ignored issues
–
show
The variable
$adapter does not exist. Did you mean $adapters ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references. ![]() |
|||
172 | return $this->adapter; |
||
173 | } else { |
||
174 | $list = []; |
||
175 | foreach ($adapter as $name) { |
||
176 | if (!$this->hasAdapter($name)) { |
||
177 | throw new Exception('auth adapter '.$name.' is not registered'); |
||
178 | } |
||
179 | $list[$name] = $this->adapter[$name]; |
||
180 | } |
||
181 | |||
182 | return $list; |
||
183 | } |
||
184 | } |
||
185 | |||
186 | |||
187 | /** |
||
188 | * Create identity |
||
189 | * |
||
190 | * @param AdapterInterface $adapter |
||
191 | * @return Identity |
||
192 | */ |
||
193 | protected function createIdentity(AdapterInterface $adapter): Identity |
||
194 | { |
||
195 | $map = new $this->attribute_map_class($adapter->getAttributeMap(), $this->logger); |
||
196 | $this->identity = new $this->identity_class($adapter, $map, $this->logger); |
||
197 | return $this->identity; |
||
198 | } |
||
199 | |||
200 | |||
201 | /** |
||
202 | * Authenticate |
||
203 | * |
||
204 | * @return bool |
||
205 | */ |
||
206 | public function requireOne(): bool |
||
207 | { |
||
208 | $result = false; |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
209 | |||
210 | foreach ($this->adapter as $name => $adapter) { |
||
211 | try { |
||
212 | if ($adapter->authenticate()) { |
||
213 | $this->createIdentity($adapter); |
||
214 | |||
215 | $this->logger->info("identity [{$this->identity->getIdentifier()}] authenticated over adapter [{$name}]", [ |
||
216 | 'category' => get_class($this) |
||
217 | ]); |
||
218 | $_SERVER['REMOTE_USER'] = $this->identity->getIdentifier(); |
||
219 | |||
220 | return true; |
||
221 | } |
||
222 | } catch (\Exception $e) { |
||
223 | $this->logger->error("failed authenticate user, unexcepted exception was thrown", [ |
||
224 | 'category' => get_class($this), |
||
225 | 'exception'=> $e |
||
226 | ]); |
||
227 | } |
||
228 | |||
229 | $this->logger->debug("auth adapter [{$name}] failed", [ |
||
230 | 'category' => get_class($this) |
||
231 | ]); |
||
232 | } |
||
233 | |||
234 | $this->logger->warning("all authentication adapter have failed", [ |
||
235 | 'category' => get_class($this) |
||
236 | ]); |
||
237 | |||
238 | return false; |
||
239 | } |
||
240 | |||
241 | |||
242 | /** |
||
243 | * Get identity |
||
244 | * |
||
245 | * @return Identity |
||
246 | */ |
||
247 | public function getIdentity(): Identity |
||
248 | { |
||
249 | if (!$this->isAuthenticated()) { |
||
250 | throw new Exception('no valid authentication yet'); |
||
251 | } else { |
||
252 | return $this->identity; |
||
253 | } |
||
254 | } |
||
255 | |||
256 | |||
257 | /** |
||
258 | * Check if valid identity exists |
||
259 | * |
||
260 | * @return bool |
||
261 | */ |
||
262 | public function isAuthenticated(): bool |
||
263 | { |
||
264 | return ($this->identity instanceof Identity); |
||
265 | } |
||
266 | } |
||
267 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: