Passed
Push — master ( 5ed34a...340187 )
by Alexandre
02:40
created

ClientPasswordAuthenticator::authenticate()   C

Complexity

Conditions 12
Paths 19

Size

Total Lines 51
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 16.3945

Importance

Changes 0
Metric Value
dl 0
loc 51
ccs 22
cts 32
cp 0.6875
rs 5.6668
c 0
b 0
f 0
cc 12
eloc 33
nc 19
nop 1
crap 16.3945

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Alexandre
5
 * Date: 07/01/2018
6
 * Time: 14:19
7
 */
8
9
namespace OAuth2\ClientAuthentication\Authenticators;
10
11
12
use OAuth2\Role\Client\Type\ClientPassword;
13
use OAuth2\Role\Client\Type\ConfidentialClient;
14
use OAuth2\Roles\ClientInterface;
15
use OAuth2\Roles\Clients\ConfidentialClientInterface;
16
use OAuth2\Storages\ClientStorageInterface;
17
use Psr\Http\Message\ServerRequestInterface;
18
19
class ClientPasswordAuthenticator implements ClientAuthenticatorInterface
20
{
21
    /**
22
     * @var ClientStorageInterface
23
     */
24
    private $clientStorage;
25
    /**
26
     * @var bool
27
     */
28
    private $supportCredentialsInBody;
29
30
    public function __construct(ClientStorageInterface $clientStorage, ?bool $supportCredentialsInBody = null)
31
    {
32
        $this->clientStorage = $clientStorage;
33
        $this->supportCredentialsInBody = $supportCredentialsInBody;
34
    }
35
36 1
    public function isPasswordAuthentication(): bool
37
    {
38 1
        return true;
39
    }
40
41 1
    public function support(ServerRequestInterface $request): bool
42
    {
43 1
        if ($request->hasHeader('Authorization')) {
44 1
            return true;
45
        }
46
47
        $body = $request->getParsedBody();
48
        return isset($body['client_id'], $body['client_secret']);
49
    }
50
51
    /**
52
     * @param ServerRequestInterface $request
53
     * @return ClientInterface
54
     * @throws \Exception
55
     */
56 1
    public function authenticate(ServerRequestInterface $request): ClientInterface
57
    {
58 1
        $identifier = null;
59 1
        $password = null;
60 1
        $useHTTPAuthenticationScheme = true;
61 1
        $body = $request->getParsedBody();
62 1
        if ($request->hasHeader('Authorization')) {
63
            // 2.3 The client MUST NOT use more than one authentication method in each request
64 1
            if (isset($body['client_secret'])) {
65
                throw new \Exception('Multiple authentication methods used');
66
            }
67
68 1
            $authorization = $request->getHeader('Authorization')[0] ?? '';
69 1
            $authorization = explode(' ', trim($authorization));
70 1
            $method = $authorization[0];
71 1
            if (strtolower($method) === 'basic') {
72 1
                $authorization = explode(':', base64_decode($authorization[1]));
73 1
                $identifier = $authorization[0] ?? null;
74 1
                $password = $authorization[1] ?? '';
75
            }
76
        } else {
77
            $identifier = $body['client_id'] ?? null;
78
            $password = $body['client_secret'] ?? '';
79
            $useHTTPAuthenticationScheme = false;
80
        }
81
82 1
        if (is_null($identifier)) {
83
            throw new \Exception('No client authentication included');
84
        }
85
86 1
        $client = $this->clientStorage->get($identifier);
87 1
        if (!$client) {
88
            throw new \Exception('Unknown client');
89
        }
90
91 1
        if (!$useHTTPAuthenticationScheme &&
92
            ($this->supportCredentialsInBody === false ||
93 1
                (is_null($this->supportCredentialsInBody) && $client->isHttpBasicAuthenticationSchemeSupported()))) {
94
            throw new \Exception('Authentication method is limited to HTTP Basic authentication scheme');
95
        }
96
97 1
        if (!$client instanceof ConfidentialClientInterface) {
98
            throw new \Exception('Unsupported authentication method');
99
        }
100
101 1
        if ($client->getPassword() !== $password) {
102
            throw new \Exception('Authentication failed');
103
        }
104
105 1
        return $client;
106
    }
107
}