Passed
Push — master ( a717b5...dd05c8 )
by Florian
03:07 queued 01:19
created

HttpBasicAuthenticator::checkServerParams()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 7
ccs 7
cts 7
cp 1
rs 9.2222
c 0
b 0
f 0
cc 6
nc 6
nop 1
crap 6
1
<?php
2
declare(strict_types=1);
3
/**
4
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
5
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
 * @link          http://cakephp.org CakePHP(tm) Project
13
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
 */
15
namespace Phauthentic\Authentication\Authenticator;
16
17
use ArrayAccess;
18
use Phauthentic\Authentication\Authenticator\Exception\UnauthorizedException;
19
use Phauthentic\Authentication\Identifier\IdentifierInterface;
20
use Psr\Http\Message\ServerRequestInterface;
21
22
/**
23
 * HttpBasic Authenticator
24
 *
25
 * Provides Basic HTTP authentication support.
26
 */
27
class HttpBasicAuthenticator extends AbstractAuthenticator implements StatelessInterface
28
{
29
30
    use CredentialFieldsTrait;
31
32
    /**
33
     * Realm
34
     *
35
     * @var string|null
36
     */
37
    protected $realm;
38
39
    /**
40
     * Sets the realm
41
     *
42
     * @param string|null $realm Realm
43
     * @return $this
44
     */
45 42
    public function setRealm(?string $realm): self
46
    {
47 42
        $this->realm = $realm;
48
49 42
        return $this;
50
    }
51
52
    /**
53
     * Authenticate a user using HTTP auth. Will use the configured User model and attempt a
54
     * login using HTTP auth.
55
     *
56
     * @param \Psr\Http\Message\ServerRequestInterface $request The request to authenticate with.
57
     * @return \Phauthentic\Authentication\Authenticator\ResultInterface
58
     */
59 21
    public function authenticate(ServerRequestInterface $request): ResultInterface
60
    {
61 21
        $user = $this->getUser($request);
62
63 21
        if (empty($user)) {
64 15
            return new Result(null, Result::FAILURE_CREDENTIALS_MISSING);
65
        }
66
67 6
        return new Result($user, Result::SUCCESS);
68
    }
69
70
    /**
71
     * Checks for the user and password in the server request params
72
     *
73
     * @param array $serverParams Server params from \Psr\Http\Message\ServerRequestInterface::getServerParams()
74
     * @return bool
75
     */
76 21
    protected function checkServerParams(array $serverParams): bool {
77 21
        return !isset($serverParams['PHP_AUTH_USER'])
78 15
            || !isset($serverParams['PHP_AUTH_PW'])
79 12
            || !is_string($serverParams['PHP_AUTH_USER'])
80 12
            || $serverParams['PHP_AUTH_USER'] === ''
81 12
            || !is_string($serverParams['PHP_AUTH_PW'])
82 21
            || $serverParams['PHP_AUTH_PW'] === '';
83
    }
84
85
    /**
86
     * Get a user based on information in the request. Used by cookie-less auth for stateless clients.
87
     *
88
     * @param \Psr\Http\Message\ServerRequestInterface $request Request object.
89
     * @return \ArrayAccess|null User entity or null on failure.
90
     */
91 21
    public function getUser(ServerRequestInterface $request): ?ArrayAccess
92
    {
93 21
        $serverParams = $request->getServerParams();
94 21
        if ($this->checkServerParams($serverParams)) {
95 9
            return null;
96
        }
97
98 12
        return $this->identifier->identify([
99 12
            IdentifierInterface::CREDENTIAL_USERNAME => $serverParams['PHP_AUTH_USER'],
100 12
            IdentifierInterface::CREDENTIAL_PASSWORD => $serverParams['PHP_AUTH_PW'],
101
        ]);
102
    }
103
104
    /**
105
     * Create a challenge exception for basic auth challenge.
106
     *
107
     * @param \Psr\Http\Message\ServerRequestInterface $request A request object.
108
     * @return void
109
     * @throws \Phauthentic\Authentication\Authenticator\Exception\UnauthorizedException
110
     */
111 15
    public function unauthorizedChallenge(ServerRequestInterface $request): void
112
    {
113 15
        throw new UnauthorizedException($this->loginHeaders($request), '');
114
    }
115
116
    /**
117
     * Generate the login headers
118
     *
119
     * @param \Psr\Http\Message\ServerRequestInterface $request Request object.
120
     * @return array Headers for logging in.
121
     */
122 6
    protected function loginHeaders(ServerRequestInterface $request): array
123
    {
124 6
        $server = $request->getServerParams();
125 6
        $realm = $this->realm ?: $server['SERVER_NAME'];
126
127 6
        return ['WWW-Authenticate' => sprintf('Basic realm="%s"', $realm)];
128
    }
129
}
130