FormAuthenticator::matchRequest()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 28
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 10
c 1
b 0
f 0
dl 0
loc 28
ccs 0
cts 10
cp 0
rs 9.6111
cc 5
nc 5
nop 1
crap 30
1
<?php
2
3
/**
4
 * AppserverIo\Authenticator\FormAuthenticator
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/authenticator
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Authenticator;
22
23
use AppserverIo\Lang\String;
24
use AppserverIo\Lang\Boolean;
25
use AppserverIo\Collections\ArrayList;
26
use AppserverIo\Psr\Auth\RealmInterface;
27
use AppserverIo\Psr\HttpMessage\Protocol;
28
use AppserverIo\Authenticator\Utils\FormKeys;
29
use AppserverIo\Authenticator\Utils\FormPageUtil;
30
use AppserverIo\Psr\Security\Auth\Subject;
31
use AppserverIo\Psr\Servlet\ServletException;
32
use AppserverIo\Psr\Security\Utils\Constants;
33
use AppserverIo\Psr\Security\SecurityException;
34
use AppserverIo\Psr\Security\PrincipalInterface;
35
use AppserverIo\Psr\Servlet\Utils\RequestHandlerKeys;
36
use AppserverIo\Psr\Servlet\Http\HttpSessionInterface;
37
use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface;
38
use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface;
39
use AppserverIo\Http\Authentication\AuthenticationException;
40
use AppserverIo\Psr\Auth\LoginConfigurationInterface;
41
use AppserverIo\Psr\Auth\AuthenticationManagerInterface;
42
use AppserverIo\Appserver\Core\Api\Node\AuthenticatorNodeInterface;
0 ignored issues
show
Bug introduced by
The type AppserverIo\Appserver\Co...henticatorNodeInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
43
44
/**
45
 * A form based authenticator implementation.
46
 *
47
 * @author    Tim Wagner <[email protected]>
48
 * @copyright 2016 TechDivision GmbH <[email protected]>
49
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
50
 * @link      https://github.com/appserver-io/authenticator
51
 * @link      http://www.appserver.io
52
 */
53
class FormAuthenticator extends AbstractAuthenticator
54
{
55
56
    /**
57
     * Defines the auth type which should match the client request type definition
58
     *
59
     * @var string AUTH_TYPE
60
     */
61
    const AUTH_TYPE = 'Form';
62
63
    /**
64
     * The password to authenticate the user with.
65
     *
66
     * @var string
67
     */
68
    protected $password;
69
70
    /**
71
     * The utility instance to handle SSO functionality.
72
     *
73
     * @var \AppserverIo\Authenticator\Utils\FormPageUtilInterface
74
     */
75
    protected $formPageUtil;
76
77
    /**
78
     * Constructs the authentication type.
79
     *
80
     * @param \AppserverIo\Psr\Auth\LoginConfigurationInterface               $configData                 The configuration data for auth type instance
81
     * @param \AppserverIo\Psr\Auth\AuthenticationManagerInterface            $authenticationManager      The authentication manager instance
82
     * @param \AppserverIo\Appserver\Core\Api\Node\AuthenticatorNodeInterface $authenticatorConfiguration The authenticator configuration instance
83
     */
84
    public function __construct(
85
        LoginConfigurationInterface $configData,
86
        AuthenticationManagerInterface $authenticationManager,
87
        AuthenticatorNodeInterface $authenticatorConfiguration
88
    ) {
89
90
        // initialize the form page utility
91
        $this->formPageUtil = new FormPageUtil();
92
93
        // pass the instances to the parent constructor
94
        parent::__construct($configData, $authenticationManager, $authenticatorConfiguration);
95
    }
96
97
    /**
98
     * Return's the location for the 307 redirect to the login page.
99
     *
100
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
101
     *
102
     * @return string The location for the 307 redirect
103
     */
104
    protected function getLoginPage(HttpServletRequestInterface $servletRequest)
105
    {
106
        return $this->formPageUtil->getLoginPage($servletRequest, $this->getConfigData());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->formPageUt...$this->getConfigData()) returns the type string which is incompatible with the documented return type AppserverIo\Lang\String.
Loading history...
107
    }
108
109
    /**
110
     * Try to authenticate the user making this request, based on the specified login configuration.
111
     *
112
     * Return TRUE if any specified constraint has been satisfied, or FALSE if we have created a response
113
     * challenge already.
114
     *
115
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
116
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
117
     *
118
     * @return boolean TRUE if authentication has already been processed on a request before, else FALSE
119
     * @throws \AppserverIo\Http\Authentication\AuthenticationException Is thrown if the request can't be authenticated
120
     */
121
    public function authenticate(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
122
    {
123
124
        // start the session, if not already done
125
        /** @var \AppserverIo\Psr\Servlet\Http\HttpSessionInterface $session */
126
        $session = $servletRequest->getSession(true);
127
        // start the session if not already done
128
        if ($session->isStarted() === false) {
129
            $session->start();
130
        }
131
132
        // try to load the principal from the session if available
133
        if ($session->hasKey(Constants::PRINCIPAL)) {
134
            if ($session->getData(Constants::PRINCIPAL) instanceof PrincipalInterface) {
135
                // invoke the onCache callback and return
136
                $this->onCache($servletRequest, $servletResponse);
137
                return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
138
            }
139
        }
140
141
        // is this the re-submit of the original request URI after successful
142
        // authentication? If so, forward the *original* request instead
143
        if ($this->matchRequest($servletRequest)) {
144
            // invoke the onRestore callback and return
145
            $this->onResubmit($servletRequest, $servletResponse);
146
            return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
147
        }
148
149
        // is this the action request from the login page?
150
        if (FormKeys::FORM_ACTION !== pathinfo($servletRequest->getRequestUri(), PATHINFO_FILENAME)) {
151
            // invoke the onLogin callback and redirect to the login page
152
            $this->onLogin($servletRequest, $servletResponse);
153
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
154
        }
155
156
        // invoke the onCredentials callback to load the credentials from the request
157
        $this->onCredentials($servletRequest, $servletResponse);
158
159
        // load the realm to authenticate this request for
160
        /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */
161
        $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName());
162
163
        // authenticate the request and initialize the user principal
164
        $userPrincipal = call_user_func_array(array($realm, 'authenticate'), $this->getCredentials());
165
166
        // query whether or not the realm returned an authenticated user principal
167
        if ($userPrincipal == null) {
168
            // invoke the onFailure callback and forward the user to the error page
169
            $this->onFailure($realm, $servletRequest, $servletResponse);
170
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
171
        }
172
173
        // renew the session identifier to mitigate session fixation
174
        $session->renewId();
175
176
        // invoke the onSuccess callback and redirect the user to the original page
177
        $this->onSuccess($userPrincipal, $servletRequest, $servletResponse);
178
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
179
    }
180
181
    /**
182
     * Return's the array with the login credentials.
183
     *
184
     * @return \AppserverIo\Lang\String[] The array with the login credentials
185
     */
186
    protected function getCredentials()
187
    {
188
        return array($this->getUsername(), $this->getPassword());
0 ignored issues
show
Bug Best Practice introduced by
The expression return array($this->getU..., $this->getPassword()) returns an array which contains values of type string which are incompatible with the documented value type AppserverIo\Lang\String.
Loading history...
189
    }
190
191
    /**
192
     * Register's the user principal and the authenticytion in the request and session.
193
     *
194
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
195
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
196
     * @param \AppserverIo\Psr\Security\PrincipalInterface               $userPrincipal   The actual user principal
197
     *
198
     * @return void
199
     */
200
    protected function register(
201
        HttpServletRequestInterface $servletRequest,
202
        HttpServletResponseInterface $servletResponse,
0 ignored issues
show
Unused Code introduced by
The parameter $servletResponse is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

202
        /** @scrutinizer ignore-unused */ HttpServletResponseInterface $servletResponse,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
203
        PrincipalInterface $userPrincipal
204
    ) {
205
206
        // add the user principal and the authentication type to the request
207
        $servletRequest->setUserPrincipal($userPrincipal);
0 ignored issues
show
Bug introduced by
The method setUserPrincipal() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. It seems like you code against a sub-type of AppserverIo\Psr\Servlet\...ServletRequestInterface such as AppserverIo\Authenticato...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

207
        $servletRequest->/** @scrutinizer ignore-call */ 
208
                         setUserPrincipal($userPrincipal);
Loading history...
208
        $servletRequest->setAuthType($this->getAuthType());
0 ignored issues
show
Bug introduced by
The method setAuthType() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

208
        $servletRequest->/** @scrutinizer ignore-call */ 
209
                         setAuthType($this->getAuthType());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
209
210
        // set username and password in the session
211
        if ($session = $servletRequest->getSession()) {
212
            $session->putData(Constants::PRINCIPAL, $userPrincipal);
213
        }
214
    }
215
216
    /**
217
     * Forward's the request to the stored one or, if the user has not been on
218
     * any page before, the application's base URL.
219
     *
220
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
221
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
222
     *
223
     * @return void
224
     */
225
    protected function forwardToFormRequest(
226
        HttpServletRequestInterface $servletRequest,
227
        HttpServletResponseInterface $servletResponse
228
    ) {
229
230
        // load the session from the request
231
        $session = $servletRequest->getSession();
232
233
        // initialize the location to redirect to
234
        $location = '/';
235
236
        // prepend the base modifier if available
237
        if ($baseModifier = $servletRequest->getBaseModifier()) {
238
            $location = $baseModifier;
239
        }
240
241
        // query whether or not we found the original request to redirect to
242
        if ($session && $session->hasKey(Constants::FORM_REQUEST)) {
243
            // load the original request
244
            $req = $session->getData(Constants::FORM_REQUEST);
245
246
            // initialize the location to redirect to
247
            $location = $req->requestUri;
248
249
            // prepare URI + query string to redirect to
250
            if ($queryString = $req->queryString) {
251
                $location .= '?' . $queryString;
252
            }
253
        }
254
255
        // redirect to the original location
256
        $servletRequest->setDispatched(true);
257
        $servletResponse->setStatusCode(303);
258
        $servletResponse->addHeader(Protocol::HEADER_LOCATION, $location);
259
    }
260
261
    /**
262
     * Forward's the request to the configured login page.
263
     *
264
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
265
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
266
     *
267
     * @return void
268
     */
269
    protected function forwardToLoginPage(
270
        HttpServletRequestInterface $servletRequest,
271
        HttpServletResponseInterface $servletResponse
272
    ) {
273
274
        try {
275
            // load the location for the login page
276
            $location = $this->getLoginPage($servletRequest);
277
            // redirect to the configured login page
278
            $servletRequest->setDispatched(true);
279
            $servletResponse->setStatusCode(307);
280
            $servletResponse->addHeader(Protocol::HEADER_LOCATION, $location);
281
        } catch (SecurityException $se) {
282
            // redirect to the default error page
283
            $servletRequest->setAttribute(
0 ignored issues
show
Bug introduced by
The method setAttribute() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
            $servletRequest->/** @scrutinizer ignore-call */ 
284
                             setAttribute(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
284
                RequestHandlerKeys::ERROR_MESSAGE,
285
                $se->getMessage()
286
            );
287
            $servletRequest->setDispatched(true);
288
            $servletResponse->setStatusCode(500);
289
        }
290 1
    }
291
292
    /**
293
     * Forward's the request to the configured error page.
294
     *
295
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
296
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
297
     *
298 1
     * @return void
299
     */
300
    protected function forwardToErrorPage(
301 1
        HttpServletRequestInterface $servletRequest,
302
        HttpServletResponseInterface $servletResponse
303
    ) {
304 1
305
        // query whether or not we've an error page configured
306
        if ($formLoginConfig = $this->getConfigData()->getFormLoginConfig()) {
307
            if ($formErrorPage = $formLoginConfig->getFormErrorPage()) {
308
                // initialize the location to redirect to
309 1
                $location = $formErrorPage->__toString();
310
                if ($baseModifier = $servletRequest->getBaseModifier()) {
311
                    $location = $baseModifier . $location;
312
                }
313
314
                // redirect to the configured error page
315
                $servletRequest->setDispatched(true);
316
                $servletResponse->setStatusCode(307);
317
                $servletResponse->addHeader(Protocol::HEADER_LOCATION, $location);
318
                return;
319
            }
320
        }
321
322
        // redirect to the default error page
323
        $servletRequest->setAttribute(
324
            RequestHandlerKeys::ERROR_MESSAGE,
325
            'Please configure a form-error-page when using auth-method \'Form\' in the login-config of your application\'s web.xml'
326
        );
327
        $servletRequest->setDispatched(true);
328
        $servletResponse->setStatusCode(500);
329
    }
330
331
    /**
332
     * Tries the login the passed username/password combination for the login configuration.
333
     *
334
     * @param \AppserverIo\Lang\String                                  $username       The username used to login
335
     * @param \AppserverIo\Lang\String                                  $password       The password used to authenticate the user
336
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
337
     *
338
     * @return \AppserverIo\Psr\Security\PrincipalInterface The authenticated user principal
339
     */
340
    public function login(
341
        String $username,
342
        String $password,
343
        HttpServletRequestInterface $servletRequest
344
    ) {
345
346
        // load the realm to authenticate this request for
347
        /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */
348
        $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName());
349
350
        // authenticate the request and initialize the user principal
351
        $userPrincipal = $realm->authenticate($username, $password);
352
353
        // query whether or not we can authenticate the user
354
        if ($userPrincipal == null) {
355
            throw new ServletException(sprintf('Can\'t authenticate user %s', $username));
356
        }
357
358
        // add the user principal and the authentication type to the request
359
        $servletRequest->setUserPrincipal($userPrincipal);
360
        $servletRequest->setAuthType($this->getAuthType());
361
362
        // set username and password in the session
363
        if ($session = $servletRequest->getSession()) {
364
            $session->putData(Constants::PRINCIPAL, $userPrincipal);
365
        }
366
367
        // return's the user principal
368
        return $userPrincipal;
369
    }
370
371
    /**
372
     * Logout the actual user from the session.
373
     *
374
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
375
     *
376
     * @return void
377
     */
378
    public function logout(HttpServletRequestInterface $servletRequest)
379
    {
380
381
        // remove user principal and authentication method from request
382
        $servletRequest->setUserPrincipal();
383
        $servletRequest->setAuthType();
384
385
        // destroy the session explicit
386
        if ($session = $servletRequest->getSession()) {
387
            $session->destroy('Explicit logout by user!');
388
        }
389
    }
390
391
    /**
392
     * Does this request match the saved one, so that it must be the redirect we signaled after
393
     * successful authentication?
394
     *
395
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
396
     *
397
     * @return boolean TRUE if the request matches the saved one, else FALSE
398
     */
399
    protected function matchRequest(HttpServletRequestInterface $servletRequest)
400
    {
401
402
        // load the session from the request
403
        $session = $servletRequest->getSession();
404
405
        // query wheter or not a session is available
406
        if ($session == null) {
407
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
408
        }
409
410
        // query whether or not we can find the original request data
411
        if ($session->hasKey(Constants::FORM_REQUEST) === false) {
412
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
413
        }
414
415
        // if yes, compare the request URI and check for a valid princial
416
        if ($req = $session->getData(Constants::FORM_REQUEST)) {
417
            // query whether or not we've a valid princial
418
            if (isset($req->principal) === false) {
419
                return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
420
            }
421
            // compare the request URI
422
            return $servletRequest->getRequestUri() === $req->requestUri;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $servletRequest->...() === $req->requestUri returns the type boolean which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
423
        }
424
425
        // return FALSE if the request doesn't match
426
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type AppserverIo\Lang\Boolean.
Loading history...
427
    }
428
429
    /**
430
     * Stores the data of the passed request in the also passed session.
431
     *
432
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
433
     * @param \AppserverIo\Psr\Servlet\Http\HttpSessionInterface        $session        The session instance
434
     *
435
     * @return void
436
     */
437
    protected function saveRequest(
438
        HttpServletRequestInterface $servletRequest,
439
        HttpSessionInterface $session
440
    ) {
441
442
        // initialize an empty instance
443
        $req = new \stdClass();
444
445
        // set the data of the passed request
446
        $req->requestUri = $servletRequest->getRequestUri();
447
        $req->method = $servletRequest->getMethod();
448
        $req->queryString = $servletRequest->getQueryString();
449
        $req->documentRoot = $servletRequest->getDocumentRoot();
0 ignored issues
show
Bug introduced by
The method getDocumentRoot() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

449
        /** @scrutinizer ignore-call */ 
450
        $req->documentRoot = $servletRequest->getDocumentRoot();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
450
        $req->serverName = $servletRequest->getServerName();
451
        $req->bodyContent = $servletRequest->getBodyContent();
452
        $req->cookies = $servletRequest->getCookies();
0 ignored issues
show
Bug introduced by
The method getCookies() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. Did you maybe mean getCookie()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

452
        /** @scrutinizer ignore-call */ 
453
        $req->cookies = $servletRequest->getCookies();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
453
        $req->headers = $servletRequest->getHeaders();
454
        $req->principal = $servletRequest->getUserPrincipal();
0 ignored issues
show
Bug introduced by
The method getUserPrincipal() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

454
        /** @scrutinizer ignore-call */ 
455
        $req->principal = $servletRequest->getUserPrincipal();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
455
        $req->requestUrl = $servletRequest->getRequestUrl();
456
457
        // store the data in the session
458
        $session->putData(Constants::FORM_REQUEST, $req);
459
    }
460
461
    /**
462
     * Populates the passed request with the request data of the original request
463
     * found in the also passed session.
464
     *
465
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance
466
     * @param \AppserverIo\Psr\Servlet\Http\HttpSessionInterface        $session        The session instance
467
     *
468
     * @return void
469
     */
470
    protected function restoreRequest(
471
        HttpServletRequestInterface $servletRequest,
472
        HttpSessionInterface $session
473
    ) {
474
475
        // query whether or not we can find the original request in the session
476
        if ($session->hasKey(Constants::FORM_REQUEST)) {
477
            // load the origin request from the session
478
            $req = $session->getData(Constants::FORM_REQUEST);
479
480
            // restore the original request data
481
            $servletRequest->setHeaders($req->headers);
482
            $servletRequest->setCookies($req->cookies);
0 ignored issues
show
Bug introduced by
The method setCookies() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

482
            $servletRequest->/** @scrutinizer ignore-call */ 
483
                             setCookies($req->cookies);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
483
            $servletRequest->setUserPrincipal($req->userPrincipal);
484
            $servletRequest->setServerName($req->serverName);
0 ignored issues
show
Bug introduced by
The method setServerName() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

484
            $servletRequest->/** @scrutinizer ignore-call */ 
485
                             setServerName($req->serverName);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
485
            $servletRequest->setQueryString($req->queryString);
0 ignored issues
show
Bug introduced by
The method setQueryString() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

485
            $servletRequest->/** @scrutinizer ignore-call */ 
486
                             setQueryString($req->queryString);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
486
            $servletRequest->setRequestUri($req->requestUri);
0 ignored issues
show
Bug introduced by
The method setRequestUri() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

486
            $servletRequest->/** @scrutinizer ignore-call */ 
487
                             setRequestUri($req->requestUri);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
487
            $servletRequest->setDocumentRoot($req->documentRoot);
0 ignored issues
show
Bug introduced by
The method setDocumentRoot() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

487
            $servletRequest->/** @scrutinizer ignore-call */ 
488
                             setDocumentRoot($req->documentRoot);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
488
            $servletRequest->setRequestUrl($req->requestUrl);
0 ignored issues
show
Bug introduced by
The method setRequestUrl() does not exist on AppserverIo\Psr\Servlet\...ServletRequestInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

488
            $servletRequest->/** @scrutinizer ignore-call */ 
489
                             setRequestUrl($req->requestUrl);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
489
490
            // set the body content if we can find one
491
            if ($servletRequest->getHeader(Protocol::HEADER_CONTENT_LENGTH) > 0) {
492
                $servletRequest->setBodyStream($req->bodyContent);
493
            }
494
        }
495
    }
496
497
    /**
498
     * Will be invoked to load the credentials from the request.
499
     *
500
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
501
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
502
     *
503
     * @return void
504
     */
505
    protected function onCredentials(
506
        HttpServletRequestInterface $servletRequest,
507
        HttpServletResponseInterface $servletResponse
508
    ) {
509
510
        // try to load username and password from the request instead
511
        if ($servletRequest->hasParameter(FormKeys::USERNAME) &&
512
            $servletRequest->hasParameter(FormKeys::PASSWORD)
513
        ) {
514
            // load username/password from the request
515
            $this->username = new String($servletRequest->getParameter(FormKeys::USERNAME));
516
            $this->password = new String($servletRequest->getParameter(FormKeys::PASSWORD, FILTER_UNSAFE_RAW));
517
        }
518
    }
519
520
    /**
521
     * Will be invoked to handle a cached authentication request.
522
     *
523
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
524
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
525
     *
526
     * @return void
527
     */
528
    protected function onCache(
529
        HttpServletRequestInterface $servletRequest,
530
        HttpServletResponseInterface $servletResponse
531
    ) {
532
533
        // load the session from the request
534
        if ($session = $servletRequest->getSession()) {
535
            // add the user principal and the authentication type to the request
536
            $this->register($servletRequest, $servletResponse, $session->getData(Constants::PRINCIPAL));
537
        }
538
    }
539
540
    /**
541
     * Will be invoked when login fails for some reasons.
542
     *
543
     * @param \AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm           The realm instance containing the exception stack
0 ignored issues
show
Bug introduced by
The type AppserverIo\Appserver\Se...Security\RealmInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
544
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface    $servletRequest  The servlet request instance
545
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface   $servletResponse The servlet response instance
546
     *
547
     * @return void
548
     */
549
    protected function onFailure(
550
        RealmInterface $realm,
551
        HttpServletRequestInterface $servletRequest,
552
        HttpServletResponseInterface $servletResponse
553
    ) {
554
555
        // load the session from the request
556
        if ($session = $servletRequest->getSession()) {
557
            // prepare the ArrayList for the login errors
558
            $formErrors = new ArrayList();
559
560
            // transform the realm's exception stack into simple error messages
561
            foreach ($realm->getExceptionStack() as $e) {
562
                $formErrors->add($e->getMessage());
563
            }
564
565
            // add the error messages to the session
566
            $session->putData(Constants::FORM_ERRORS, $formErrors);
567
        }
568
569
        // forward to the configured error page
570
        $this->forwardToErrorPage($servletRequest, $servletResponse);
571
    }
572
573
    /**
574
     * Will be invoked on a successfull login.
575
     *
576
     * @param \AppserverIo\Psr\Security\PrincipalInterface               $userPrincipal   The user principal logged into the system
577
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
578
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
579
     *
580
     * @return void
581
     */
582
    protected function onSuccess(
583
        PrincipalInterface $userPrincipal,
584
        HttpServletRequestInterface $servletRequest,
585
        HttpServletResponseInterface $servletResponse
586
    ) {
587
588
        // add the user principal and the authentication type to the request
589
        $this->register($servletRequest, $servletResponse, $userPrincipal);
590
591
        // forward to the stored request
592
        $this->forwardToFormRequest($servletRequest, $servletResponse);
593
    }
594
595
    /**
596
     * Will be invoked to request authentication.
597
     *
598
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
599
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
600
     *
601
     * @return void
602
     */
603
    protected function onLogin(
604
        HttpServletRequestInterface $servletRequest,
605
        HttpServletResponseInterface $servletResponse
606
    ) {
607
608
        // load the session from the request
609
        if ($session = $servletRequest->getSession()) {
610
            // save the request (to redirect after a successful login)
611
            $this->saveRequest($servletRequest, $session);
612
        }
613
614
        // forward the user to the login page
615
        $this->forwardToLoginPage($servletRequest, $servletResponse);
616
    }
617
618
    /**
619
     * Will be invoked when login will be re-submitted.
620
     *
621
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
622
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
623
     *
624
     * @return void
625
     */
626
    protected function onResubmit(
627
        HttpServletRequestInterface $servletRequest,
628
        HttpServletResponseInterface $servletResponse
0 ignored issues
show
Unused Code introduced by
The parameter $servletResponse is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

628
        /** @scrutinizer ignore-unused */ HttpServletResponseInterface $servletResponse

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
629
    ) {
630
631
        // load the session from the request
632
        if ($session = $servletRequest->getSession()) {
633
            // restore the old request from the session
634
            $this->restoreRequest($servletRequest, $session);
635
        }
636
    }
637
638
    /**
639
     * Returns the parsed password.
640
     *
641
     * @return \AppserverIo\Lang\String The password
642
     */
643
    public function getPassword()
644
    {
645
        return $this->password ? $this->password : null;
646
    }
647
}
648