Failed Conditions
Pull Request — ng (#75)
by Florent
07:54 queued 03:54
created

AuthorizationEndpoint   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 13
dl 0
loc 154
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
redirectToLoginPage() 0 1 ?
processConsentScreen() 0 1 ?
C process() 0 51 12
A buildResponse() 0 16 4
A throwRedirectionException() 0 13 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace OAuth2Framework\Component\Server\AuthorizationEndpoint;
15
16
use Interop\Http\Server\RequestHandlerInterface;
17
use Interop\Http\Server\MiddlewareInterface;
18
use OAuth2Framework\Component\Server\AuthorizationEndpoint\AfterConsentScreen\AfterConsentScreenManager;
19
use OAuth2Framework\Component\Server\AuthorizationEndpoint\BeforeConsentScreen\BeforeConsentScreenManager;
20
use OAuth2Framework\Component\Server\AuthorizationEndpoint\UserAccountDiscovery\UserAccountDiscoveryManager;
21
use OAuth2Framework\Component\Server\Core\Response\OAuth2Exception;
22
use Psr\Http\Message\ResponseInterface;
23
use Psr\Http\Message\ServerRequestInterface;
24
25
abstract class AuthorizationEndpoint implements MiddlewareInterface
26
{
27
    /**
28
     * @var UserAccountDiscoveryManager
29
     */
30
    private $userAccountDiscoveryManager;
31
32
    /**
33
     * @var BeforeConsentScreenManager
34
     */
35
    private $beforeConsentScreenManager;
36
37
    /**
38
     * @var AfterConsentScreenManager
39
     */
40
    private $afterConsentScreenManager;
41
42
    /**
43
     * @var AuthorizationFactory
44
     */
45
    private $authorizationFactory;
46
47
    /**
48
     * AuthorizationEndpoint constructor.
49
     *
50
     * @param AuthorizationFactory        $authorizationFactory
51
     * @param UserAccountDiscoveryManager $userAccountDiscoveryManager
52
     * @param BeforeConsentScreenManager  $beforeConsentScreenManager
53
     * @param AfterConsentScreenManager   $afterConsentScreenManager
54
     */
55
    public function __construct(AuthorizationFactory $authorizationFactory, UserAccountDiscoveryManager $userAccountDiscoveryManager, BeforeConsentScreenManager $beforeConsentScreenManager, AfterConsentScreenManager $afterConsentScreenManager)
56
    {
57
        $this->authorizationFactory = $authorizationFactory;
58
        $this->userAccountDiscoveryManager = $userAccountDiscoveryManager;
59
        $this->beforeConsentScreenManager = $beforeConsentScreenManager;
60
        $this->afterConsentScreenManager = $afterConsentScreenManager;
61
    }
62
63
    /**
64
     * @param Authorization          $authorization
65
     * @param ServerRequestInterface $request
66
     *
67
     * @return ResponseInterface
68
     */
69
    abstract protected function redirectToLoginPage(Authorization $authorization, ServerRequestInterface $request): ResponseInterface;
70
71
    /**
72
     * @param ServerRequestInterface $request
73
     * @param Authorization          $authorization
74
     *
75
     * @return ResponseInterface
76
     */
77
    abstract protected function processConsentScreen(ServerRequestInterface $request, Authorization $authorization): ResponseInterface;
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
83
    {
84
        try {
85
            $authorization = $this->authorizationFactory->createAuthorizationFromRequest($request);
86
            $authorization = $this->userAccountDiscoveryManager->find($request, $authorization);
87
88
            if (null === $authorization->getUserAccount()) {
89
                return $this->redirectToLoginPage($authorization, $request);
90
            }
91
92
            $authorization = $this->beforeConsentScreenManager->process($request, $authorization);
93
94
            return $this->processConsentScreen($request, $authorization);
95
        } catch (OAuth2Exception $e) {
96
            $data = $e->getData();
97
            if (null !== $e->getAuthorization()) {
0 ignored issues
show
Bug introduced by
The method getAuthorization() does not seem to exist on object<OAuth2Framework\C...sponse\OAuth2Exception>.

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...
98
                $redirectUri = $e->getAuthorization()->getRedirectUri();
0 ignored issues
show
Bug introduced by
The method getAuthorization() does not seem to exist on object<OAuth2Framework\C...sponse\OAuth2Exception>.

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...
99
                $responseMode = $e->getAuthorization()->getResponseMode();
0 ignored issues
show
Bug introduced by
The method getAuthorization() does not seem to exist on object<OAuth2Framework\C...sponse\OAuth2Exception>.

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...
100
                if (null !== $redirectUri && null !== $responseMode) {
101
                    $data['redirect_uri'] = $redirectUri;
102
                    $data['response_mode'] = $responseMode;
103
104
                    throw new OAuth2Exception(302, $data, $e->getAuthorization(), $e);
0 ignored issues
show
Bug introduced by
The method getAuthorization() does not seem to exist on object<OAuth2Framework\C...sponse\OAuth2Exception>.

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...
Documentation introduced by
$data is of type array<string,?,{"response_mode":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$e is of type object<OAuth2Framework\C...sponse\OAuth2Exception>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
                }
106
            }
107
108
            throw $e;
109
        } catch (Exception\ProcessAuthorizationException $e) {
110
            $authorization = $e->getAuthorization();
111
            $authorization = $this->afterConsentScreenManager->process($request, $authorization);
112
            if (false === $authorization->isAuthorized()) {
113
                $this->throwRedirectionException($authorization, OAuth2Exception::ERROR_ACCESS_DENIED, 'The resource owner denied access to your client.');
114
            }
115
116
            $responseTypeProcessor = ResponseTypeProcessor::create($authorization);
117
118
            try {
119
                $authorization = $responseTypeProcessor->process();
120
            } catch (OAuth2Exception $e) {
121
                $this->throwRedirectionException($authorization, $e->getData()['error'], $e->getData()['error_description']);
122
            }
123
124
            return $this->buildResponse($authorization);
125
        } catch (Exception\CreateRedirectionException $e) {
126
            $this->throwRedirectionException($e->getAuthorization(), $e->getMessage(), $e->getDescription());
127
        } catch (Exception\ShowConsentScreenException $e) {
128
            return $this->processConsentScreen($request, $e->getAuthorization());
129
        } catch (Exception\RedirectToLoginPageException $e) {
130
            return $this->redirectToLoginPage($e->getAuthorization(), $request);
131
        }
132
    }
133
134
    /**
135
     * @param Authorization $authorization
136
     *
137
     * @throws OAuth2Exception
138
     *
139
     * @return ResponseInterface
140
     */
141
    private function buildResponse(Authorization $authorization): ResponseInterface
142
    {
143
        if (null === $authorization->getResponseMode() || null === $authorization->getRedirectUri()) {
144
            throw new OAuth2Exception(400, ['error' => 'EEE', 'error_description' => 'FFF']);
0 ignored issues
show
Bug introduced by
The call to OAuth2Exception::__construct() misses a required argument $errorDescription.

This check looks for function calls that miss required arguments.

Loading history...
Documentation introduced by
array('error' => 'EEE', ..._description' => 'FFF') is of type array<string,string,{"er...description":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
145
        }
146
147
        $response = $authorization->getResponseMode()->buildResponse(
148
            $authorization->getRedirectUri(),
149
            $authorization->getResponseParameters()
150
        );
151
        foreach ($authorization->getResponseHeaders() as $k => $v) {
152
            $response = $response->withHeader($k, $v);
153
        }
154
155
        return $response;
156
    }
157
158
    /**
159
     * @param Authorization $authorization
160
     * @param string        $error
161
     * @param string        $error_description
162
     *
163
     * @throws OAuth2Exception
164
     */
165
    private function throwRedirectionException(Authorization $authorization, string $error, string $error_description)
166
    {
167
        $params = $authorization->getResponseParameters();
168
        if (null === $authorization->getResponseMode() || null === $authorization->getRedirectUri()) {
169
            throw new OAuth2Exception(400, $error, $error_description, $params);
170
        }
171
        $params += [
172
            'response_mode' => $authorization->getResponseMode(),
173
            'redirect_uri' => $authorization->getRedirectUri(),
174
        ];
175
176
        throw new OAuth2Exception(302, $error, $error_description, $params);
177
    }
178
}
179