Passed
Push — master ( fc8907...17cbbf )
by Alexandre
01:43
created

AuthorizationEndpoint::handleRequest()   F

Complexity

Conditions 17
Paths 562

Size

Total Lines 80
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 80
rs 2.7375
c 0
b 0
f 0
cc 17
eloc 40
nc 562
nop 1

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: 18/02/2018
6
 * Time: 18:14
7
 */
8
9
namespace OAuth2\Extensions\OpenID\Endpoints;
10
11
12
use GuzzleHttp\Psr7\Response;
13
use OAuth2\Exceptions\OAuthException;
14
use OAuth2\ResponseModes\ResponseModeManager;
15
use OAuth2\ResponseTypes\ResponseTypeManager;
16
use OAuth2\Extensions\OpenID\Roles\ResourceOwnerInterface;
17
use OAuth2\ScopePolicy\ScopePolicyManager;
18
use OAuth2\Storages\ClientStorageInterface;
19
use Psr\Http\Message\ResponseInterface;
20
use Psr\Http\Message\ServerRequestInterface;
21
22
class AuthorizationEndpoint extends \OAuth2\Endpoints\AuthorizationEndpoint
23
{
24
    const DISPLAY_PAGE = 'page';
25
    const DISPLAY_POPUP = 'popup';
26
    const DISPLAY_TOUCH = 'touch';
27
    const DISPLAY_WAP = 'wap';
28
29
    const PROMPT_NONE = 'none';
30
    const PROMPT_LOGIN = 'login';
31
    const PROMPT_CONSENT = 'consent';
32
    const PROMPT_SELECT_ACCOUNT = 'select_account';
33
    /**
34
     * @var mixed|null
35
     */
36
    private $nonce;
37
    /**
38
     * @var string|null
39
     */
40
    private $display;
41
    /**
42
     * @var string|null
43
     */
44
    private $prompt;
45
    /**
46
     * @var int|null
47
     */
48
    private $maxAge;
49
    /**
50
     * @var string[]|null
51
     */
52
    private $uiLocales;
53
    /**
54
     * @var string|null
55
     */
56
    private $idTokenHint;
57
    /**
58
     * @var string|null
59
     */
60
    private $loginHint;
61
    /**
62
     * @var string[]|null
63
     */
64
    private $acrValues;
65
    /**
66
     * @var ResourceOwnerInterface
67
     */
68
    private $resourceOwner;
69
70
    public function __construct(ResponseTypeManager $responseTypeManager, ResponseModeManager $responseModeManager,
71
                                ScopePolicyManager $scopePolicyManager, ResourceOwnerInterface $resourceOwner,
72
                                ClientStorageInterface $clientStorage)
73
    {
74
        parent::__construct($responseTypeManager, $responseModeManager, $scopePolicyManager, $resourceOwner, $clientStorage);
75
        $this->resourceOwner = $resourceOwner;
76
    }
77
78
    public function handleRequest(ServerRequestInterface $request): ResponseInterface
79
    {
80
        if ($request->getMethod() === 'GET') {
81
            $requestData = $request->getQueryParams();
82
        } else if ($request->getMethod() === 'POST') {
83
            $requestData = is_array($request->getParsedBody()) ? $request->getParsedBody() : [];
84
        } else {
85
            return new Response(404);
86
        }
87
88
        try {
89
            // Authentication Request Validation
90
            // The Authorization Server MUST validate all the OAuth 2.0 parameters according to the OAuth 2.0 specification.
91
            parent::verifyRequestData($requestData);
92
93
            if (in_array('openid', $this->getScopes())) {
94
                $this->verifyRequestData($requestData);
95
            }
96
97
        } catch (OAuthException $e) {
98
            /**
99
             * If the Authorization Server encounters any error, it MUST return an error response, per Section 3.1.2.6.
100
             */
101
102
            return new Response(400, ['content-type' => 'application/json'], $e->jsonSerialize());
103
        }
104
105
        try {
106
            // Authorization Server Authenticates End-User
107
            if (!$this->resourceOwner->isAuthenticated(self::PROMPT_LOGIN)) {
0 ignored issues
show
Bug introduced by
self::PROMPT_LOGIN of type string is incompatible with the type boolean expected by parameter $alwaysAuthenticate of OAuth2\Extensions\OpenID...face::isAuthenticated(). ( Ignorable by Annotation )

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

107
            if (!$this->resourceOwner->isAuthenticated(/** @scrutinizer ignore-type */ self::PROMPT_LOGIN)) {
Loading history...
108
                if ($this->prompt == self::PROMPT_NONE) {
109
                    throw new OAuthException('login_required');
110
                }
111
112
                // may throw interaction_required
113
                return $this->resourceOwner->authenticate($this->prompt == self::PROMPT_SELECT_ACCOUNT);
114
            }
115
116
            if ($this->prompt == self::PROMPT_NONE &&
117
                $this->resourceOwner->isInteractionRequiredForConsent($this)) {
118
                throw new OAuthException('interaction_required');
119
            }
120
121
            $consentGiven = $this->resourceOwner->hasGivenConsent($this->getClient(), $this->getScopes(),
122
                $this->prompt == self::PROMPT_CONSENT);
123
124
            if (is_null($consentGiven)) {
125
                if ($this->prompt == self::PROMPT_NONE) {
126
                    throw new OAuthException('consent_required');
127
                }
128
129
                return $this->resourceOwner->obtainConsent($this->getClient(), $this->getScopes(), $this->loginHint);
130
            }
131
132
            if (empty($consentGiven)) {
133
                throw new OAuthException('access_denied', 'The resource owner denied the request.',
134
                    'https://tools.ietf.org/html/rfc6749#section-4.1');
135
            }
136
137
            $responseData = $this->getResponseType()->handleAuthorizationRequest($this, $requestData);
138
        } catch (OAuthException $e) {
139
            /**
140
             * If the Authorization Server encounters any error, it MUST return an error response, per Section 3.1.2.6.
141
             */
142
            $responseData = [
143
                'error' => $e->getError()
144
            ];
145
            if ($e->getErrorDescription()) {
146
                $responseData['error_description'] = $e->getErrorDescription();
147
            }
148
            if ($e->getErrorUri()) {
149
                $responseData['error_uri'] = $e->getErrorUri();
150
            }
151
        }
152
153
        if (!empty($this->getState())) {
154
            $responseData['state'] = $this->getState();
155
        }
156
157
        return $this->getResponseMode()->buildResponse($this, $requestData, $responseData);
158
    }
159
160
161
    /**
162
     * @param array $requestData
163
     */
164
    public function verifyRequestData(array $requestData)
165
    {
166
        $this->nonce = empty($requestData['state']) ? null : $requestData['state'];
167
        $this->display = empty($requestData['display']) ? null : $requestData['display'];
168
        $this->prompt = empty($requestData['prompt']) ? null : $requestData['prompt'];
169
        $this->maxAge = empty($requestData['max_age']) ? null : $requestData['max_age'];
170
        $this->uiLocales = empty($requestData['ui_locales']) ? null : explode(' ', $requestData['ui_locales']);
171
        $this->idTokenHint = empty($requestData['id_token_hint']) ? null : $requestData['id_token_hint'];
172
        $this->loginHint = empty($requestData['login_hint']) ? null : $requestData['login_hint'];
173
        $this->acrValues = empty($requestData['acr_values']) ? null : explode(' ', $requestData['acr_values']);
174
    }
175
176
    /**
177
     * @return mixed|null
178
     */
179
    public function getNonce(): ?mixed
0 ignored issues
show
Bug introduced by
The type OAuth2\Extensions\OpenID\Endpoints\mixed was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
180
    {
181
        return $this->nonce;
182
    }
183
184
    /**
185
     * @return null|string
186
     */
187
    public function getDisplay(): ?string
188
    {
189
        return $this->display;
190
    }
191
192
    /**
193
     * @return null|string
194
     */
195
    public function getPrompt(): ?string
196
    {
197
        return $this->prompt;
198
    }
199
200
    /**
201
     * @return int|null
202
     */
203
    public function getMaxAge(): ?int
204
    {
205
        return $this->maxAge;
206
    }
207
208
    /**
209
     * @return null|string[]
210
     */
211
    public function getUiLocales(): ?array
212
    {
213
        return $this->uiLocales;
214
    }
215
216
    /**
217
     * @return null|string
218
     */
219
    public function getIdTokenHint(): ?string
220
    {
221
        return $this->idTokenHint;
222
    }
223
224
    /**
225
     * @return null|string
226
     */
227
    public function getLoginHint(): ?string
228
    {
229
        return $this->loginHint;
230
    }
231
232
    /**
233
     * @return null|string[]
234
     */
235
    public function getAcrValues(): ?array
236
    {
237
        return $this->acrValues;
238
    }
239
}