BasicAuthenticator::getAuthenticateHeader()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * AppserverIo\Authenticator\BasicAuthenticator
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\Psr\HttpMessage\Protocol;
25
use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface;
26
use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface;
27
use AppserverIo\Http\Authentication\AuthenticationException;
28
29
/**
30
 * An authenticator implementation providing HTTP basic authentication.
31
 *
32
 * @author    Tim Wagner <[email protected]>
33
 * @copyright 2016 TechDivision GmbH <[email protected]>
34
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
35
 * @link      https://github.com/appserver-io/authenticator
36
 * @link      http://www.appserver.io
37
 */
38
class BasicAuthenticator extends AbstractAuthenticator
39
{
40
41
    /**
42
     * Defines the auth type which should match the client request type definition
43
     *
44
     * @var string AUTH_TYPE
45
     */
46
    const AUTH_TYPE = 'Basic';
47
48
    /**
49
     * The password to authenticate the user with.
50
     *
51
     * @var string
52
     */
53
    protected $password;
54
55
    /**
56
     * Try to authenticate the user making this request, based on the specified login configuration.
57
     *
58
     * Return TRUE if any specified constraint has been satisfied, or FALSE if we have created a response
59
     * challenge already.
60
     *
61
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The servlet request instance
62
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance
63
     *
64
     * @return boolean TRUE if authentication has already been processed on a request before, else FALSE
65
     * @throws \AppserverIo\Http\Authentication\AuthenticationException Is thrown if the request can't be authenticated
66
     */
67
    public function authenticate(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
68
    {
69
70
        // check if auth header is not set in coming request headers
71
        if ($servletRequest->hasHeader(Protocol::HEADER_AUTHORIZATION) === false) {
72
            // stop processing immediately
73
            $servletRequest->setDispatched(true);
74
            $servletResponse->setStatusCode(401);
75
            $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader());
76
            return false;
77
        }
78
79
        // load the raw login credentials
80
        $rawAuthData = $servletRequest->getHeader(Protocol::HEADER_AUTHORIZATION);
81
82
        // set auth hash got from auth data request header and check if username and password has been passed
83
        if (strstr($credentials = base64_decode(trim(strstr($rawAuthData, " "))), ':') === false) {
0 ignored issues
show
Bug introduced by
It seems like $rawAuthData can also be of type null; however, parameter $haystack of strstr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

83
        if (strstr($credentials = base64_decode(trim(strstr(/** @scrutinizer ignore-type */ $rawAuthData, " "))), ':') === false) {
Loading history...
84
            // stop processing immediately
85
            $servletRequest->setDispatched(true);
86
            $servletResponse->setStatusCode(401);
87
            $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader());
88
            return false;
89
        }
90
91
        // get out username and password
92
        list ($username, $password) = explode(':', $credentials);
93
94
        // query whether or not a username and a password has been passed
95
        if (($password === null) || ($username === null)) {
96
            // stop processing immediately
97
            $servletRequest->setDispatched(true);
98
            $servletResponse->setStatusCode(401);
99
            $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader());
100
            return false;
101
        }
102
103
        // set username and password
104
        $this->username = new String($username);
105
        $this->password = new String($password);
106
107
        // load the realm to authenticate this request for
108
        /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */
109
        $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName());
110
111
        // authenticate the request and initialize the user principal
112
        $userPrincipal = $realm->authenticate($this->getUsername(), $this->getPassword());
113
114
        // query whether or not the realm returned an authenticated user principal
115
        if ($userPrincipal == null) {
116
            // stop processing immediately
117
            $servletRequest->setDispatched(true);
118
            $servletResponse->setStatusCode(401);
119
            $servletResponse->setBodyStream('Unauthorized');
0 ignored issues
show
Bug introduced by
'Unauthorized' of type string is incompatible with the type resource expected by parameter $bodyStream of AppserverIo\Psr\Servlet\...erface::setBodyStream(). ( Ignorable by Annotation )

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

119
            $servletResponse->setBodyStream(/** @scrutinizer ignore-type */ 'Unauthorized');
Loading history...
120
            $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader());
121
            return false;
122
        }
123
124
        // add the user principal and the authentication type to the request
125
        $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

125
        $servletRequest->/** @scrutinizer ignore-call */ 
126
                         setUserPrincipal($userPrincipal);
Loading history...
126
        $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

126
        $servletRequest->/** @scrutinizer ignore-call */ 
127
                         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...
127
        return true;
128
    }
129
130
    /**
131
     * Returns the authentication header for response to set
132
     *
133
     * @return string
134
     */
135
    public function getAuthenticateHeader()
136
    {
137
        return sprintf('%s realm="%s"', $this->getAuthType(), $this->getRealmName());
0 ignored issues
show
Bug Best Practice introduced by
The expression return sprintf('%s realm... $this->getRealmName()) returns the type string which is incompatible with the documented return type AppserverIo\Lang\String.
Loading history...
138
    }
139
140
    /**
141
     * Returns the parsed password
142
     *
143
     * @return string
144
     */
145
    public function getPassword()
146
    {
147
        return isset($this->password) ? $this->password : null;
148
    }
149
}
150