Passed
Push — master ( 904589...078d26 )
by Thomas Mauro
02:52
created

AuthorizationService::getAuthorizationUri()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 11.897

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 14
dl 0
loc 22
ccs 11
cts 15
cp 0.7332
rs 7.6666
c 2
b 0
f 0
cc 10
nc 10
nop 2
crap 11.897

How to fix   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
declare(strict_types=1);
4
5
namespace TMV\OpenIdClient\Service;
6
7
use Http\Discovery\Psr17FactoryDiscovery;
8
use Http\Discovery\Psr18ClientDiscovery;
9
use JsonSerializable;
10
use Psr\Http\Client\ClientExceptionInterface;
11
use Psr\Http\Client\ClientInterface;
12
use Psr\Http\Message\RequestFactoryInterface;
13
use Psr\Http\Message\UriFactoryInterface;
14
use Psr\Http\Message\UriInterface;
15
use TMV\OpenIdClient\ClientInterface as OpenIDClient;
16
use TMV\OpenIdClient\Exception\InvalidArgumentException;
17
use TMV\OpenIdClient\Exception\RuntimeException;
18
use function TMV\OpenIdClient\parseMetadataResponse;
19
20
class AuthorizationService
21
{
22
    /** @var ClientInterface */
23
    private $client;
24
25
    /** @var RequestFactoryInterface */
26
    private $requestFactory;
27
28
    /** @var UriFactoryInterface */
29
    private $uriFactory;
30
31
    /**
32
     * AuthorizationService constructor.
33
     *
34
     * @param null|ClientInterface $client
35
     * @param null|RequestFactoryInterface $requestFactory
36
     * @param null|UriFactoryInterface $uriFactory
37
     */
38 3
    public function __construct(
39
        ?ClientInterface $client = null,
40
        ?RequestFactoryInterface $requestFactory = null,
41
        ?UriFactoryInterface $uriFactory = null
42
    ) {
43 3
        $this->client = $client ?: Psr18ClientDiscovery::find();
44 3
        $this->requestFactory = $requestFactory ?: Psr17FactoryDiscovery::findRequestFactory();
45 3
        $this->uriFactory = $uriFactory ?: Psr17FactoryDiscovery::findUrlFactory();
46 3
    }
47
48
    /**
49
     * @param OpenIDClient $client
50
     * @param array<string, mixed>|null $params
51
     *
52
     * @return UriInterface
53
     */
54 2
    public function getAuthorizationUri(OpenIDClient $client, ?array $params = null): UriInterface
55
    {
56 2
        $issuerMetadata = $client->getIssuer()->getMetadata();
57 2
        $endpointUri = $issuerMetadata->getAuthorizationEndpoint();
58 2
        $params = $params ?: $client->getAuthRequest()->createParams();
59
60 2
        foreach ($params as $key => $value) {
61 2
            if (null === $value) {
62
                unset($params[$key]);
63 2
            } elseif ('claims' === $key && (\is_array($value) || $value instanceof JsonSerializable)) {
64
                $params['claims'] = \json_encode($value);
65 2
            } elseif (! \is_string($value)) {
66
                $params[$key] = (string) $value;
67
            }
68
        }
69
70 2
        if (empty($params['nonce']) && \in_array('id_token', \explode(' ', $params['response_type'] ?? ''), true)) {
71
            throw new InvalidArgumentException('nonce MUST be provided for implicit and hybrid flows');
72
        }
73
74 2
        return $this->uriFactory->createUri($endpointUri)
75 2
            ->withQuery(\http_build_query($params));
76
    }
77
78 1
    public function fetchTokenFromCode(OpenIDClient $client, string $code): array
79
    {
80
        $claims = [
81 1
            'grant_type' => 'authorization_code',
82 1
            'code' => $code,
83 1
            'redirect_uri' => $client->getAuthRequest()->getRedirectUri(),
84
        ];
85
86 1
        $authMethod = $client->getAuthMethodFactory()
87 1
            ->create($client->getMetadata()->getTokenEndpointAuthMethod());
88
89 1
        $tokenRequest = $this->requestFactory->createRequest('POST', $client->getTokenEndpoint())
90 1
            ->withHeader('content-type', 'application/x-www-form-urlencoded');
91
92 1
        $tokenRequest = $authMethod->createRequest($tokenRequest, $client, $claims);
93
94
        try {
95 1
            $response = $this->client->sendRequest($tokenRequest);
96
        } catch (ClientExceptionInterface $e) {
97
            throw new RuntimeException('Unable to get token response', 0, $e);
98
        }
99
100 1
        return parseMetadataResponse($response);
101
    }
102
}
103