Failed Conditions
Push — master ( d35532...b3f3b3 )
by Florent
04:23
created

AuthorizationEndpoint::process()   D

Complexity

Conditions 10
Paths 108

Size

Total Lines 43
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 43
rs 4.7301
c 0
b 0
f 0
cc 10
eloc 32
nc 108
nop 2

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
/*
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\AuthorizationEndpoint;
15
16
use Http\Message\MessageFactory;
17
use OAuth2Framework\Component\AuthorizationEndpoint\ParameterChecker\ParameterCheckerManager;
18
use OAuth2Framework\Component\AuthorizationEndpoint\UserAccount\UserAccountCheckerManager;
19
use Psr\Http\Server\RequestHandlerInterface;
20
use Psr\Http\Server\MiddlewareInterface;
21
use OAuth2Framework\Component\AuthorizationEndpoint\ConsentScreen\ExtensionManager;
22
use OAuth2Framework\Component\AuthorizationEndpoint\Exception\OAuth2AuthorizationException;
23
use OAuth2Framework\Component\AuthorizationEndpoint\UserAccount\UserAccountDiscovery;
24
use OAuth2Framework\Component\Core\Message\OAuth2Message;
25
use Psr\Http\Message\ResponseInterface;
26
use Psr\Http\Message\ServerRequestInterface;
27
28
abstract class AuthorizationEndpoint implements MiddlewareInterface
29
{
30
    /**
31
     * @var UserAccountDiscovery
32
     */
33
    protected $userAccountDiscovery;
34
35
    /**
36
     * @var UserAccountCheckerManager
37
     */
38
    protected $userAccountCheckerManager;
39
40
    /**
41
     * @var ExtensionManager
42
     */
43
    protected $consentScreenExtensionManager;
44
45
    /**
46
     * @var AuthorizationRequestLoader
47
     */
48
    protected $authorizationRequestLoader;
49
50
    /**
51
     * @var ParameterCheckerManager
52
     */
53
    protected $parameterCheckerManager;
54
55
    /**
56
     * @var MessageFactory
57
     */
58
    protected $messageFactory;
59
60
    /**
61
     * AuthorizationEndpoint constructor.
62
     *
63
     * @param MessageFactory             $messageFactory
64
     * @param AuthorizationRequestLoader $authorizationRequestLoader
65
     * @param ParameterCheckerManager    $parameterCheckerManager
66
     * @param UserAccountDiscovery       $userAccountDiscovery
67
     * @param UserAccountCheckerManager  $userAccountCheckerManager
68
     * @param ExtensionManager           $consentScreenExtensionManager
69
     */
70
    public function __construct(MessageFactory $messageFactory, AuthorizationRequestLoader $authorizationRequestLoader, ParameterCheckerManager $parameterCheckerManager, UserAccountDiscovery $userAccountDiscovery, UserAccountCheckerManager $userAccountCheckerManager, ExtensionManager $consentScreenExtensionManager)
71
    {
72
        $this->messageFactory = $messageFactory;
73
        $this->authorizationRequestLoader = $authorizationRequestLoader;
74
        $this->parameterCheckerManager = $parameterCheckerManager;
75
        $this->userAccountDiscovery = $userAccountDiscovery;
76
        $this->userAccountCheckerManager = $userAccountCheckerManager;
77
        $this->consentScreenExtensionManager = $consentScreenExtensionManager;
78
    }
79
80
    /**
81
     * @param ServerRequestInterface $request
82
     * @param Authorization          $authorization
83
     *
84
     * @return ResponseInterface
85
     */
86
    abstract protected function redirectToLoginPage(ServerRequestInterface $request, Authorization $authorization): ResponseInterface;
87
88
    /**
89
     * @param ServerRequestInterface $request
90
     * @param Authorization          $authorization
91
     *
92
     * @return ResponseInterface
93
     */
94
    abstract protected function processConsentScreen(ServerRequestInterface $request, Authorization $authorization): ResponseInterface;
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
100
    {
101
        try {
102
            $authorization = $this->createAuthorizationFromRequest($request);
103
            $isFullyAuthenticated = null;
104
            $userAccount = $this->userAccountDiscovery->find($isFullyAuthenticated);
105
            if (!is_bool($isFullyAuthenticated)) {
106
                $isFullyAuthenticated = false;
107
            }
108
            if (null === $userAccount) {
109
                return $this->redirectToLoginPage($request, $authorization);
110
            }
111
            $authorization = $authorization->withUserAccount($userAccount, $isFullyAuthenticated);
112
            $this->userAccountCheckerManager->check($authorization);
113
            $authorization = $this->consentScreenExtensionManager->processBefore($request, $authorization);
114
115
            return $this->processConsentScreen($request, $authorization);
116
        } catch (OAuth2AuthorizationException $e) {
117
            throw $e;
118
        } catch (Exception\ProcessAuthorizationException $e) {
119
            $authorization = $e->getAuthorization();
120
            $authorization = $this->consentScreenExtensionManager->processAfter($request, $authorization);
121
            if (false === $authorization->isAuthorized()) {
122
                $this->throwRedirectionException($authorization, OAuth2Message::ERROR_ACCESS_DENIED, 'The resource owner denied access to your client.');
123
            }
124
125
            $responseType = $authorization->getResponseType();
126
127
            try {
128
                $authorization = $responseType->process($authorization);
129
            } catch (OAuth2Message $e) {
130
                $this->throwRedirectionException($authorization, $e->getMessage(), $e->getErrorDescription());
131
            }
132
133
            return $this->buildResponse($authorization);
134
        } catch (Exception\CreateRedirectionException $e) {
135
            $this->throwRedirectionException($e->getAuthorization(), $e->getMessage(), $e->getDescription());
136
        } catch (Exception\ShowConsentScreenException $e) {
137
            return $this->processConsentScreen($request, $e->getAuthorization());
138
        } catch (Exception\RedirectToLoginPageException $e) {
139
            return $this->redirectToLoginPage($request, $e->getAuthorization());
140
        }
141
    }
142
143
    /**
144
     * @param Authorization $authorization
145
     *
146
     * @return ResponseInterface
147
     */
148
    protected function buildResponse(Authorization $authorization): ResponseInterface
149
    {
150
        $response = $authorization->getResponseMode()->buildResponse(
151
            $this->messageFactory->createResponse(),
152
            $authorization->getRedirectUri(),
153
            $authorization->getResponseParameters()
154
        );
155
        foreach ($authorization->getResponseHeaders() as $k => $v) {
156
            $response = $response->withHeader($k, $v);
157
        }
158
159
        return $response;
160
    }
161
162
    /**
163
     * @param Authorization $authorization
164
     * @param string        $error
165
     * @param string        $error_description
166
     */
167
    protected function throwRedirectionException(Authorization $authorization, string $error, string $error_description)
168
    {
169
        $params = $authorization->getResponseParameters();
170
        if (null === $authorization->getResponseMode() || null === $authorization->getRedirectUri()) {
171
            throw new OAuth2Message(400, $error, $error_description);
172
        }
173
        $params += [
174
            'response_mode' => $authorization->getResponseMode(),
175
            'redirect_uri' => $authorization->getRedirectUri(),
176
        ];
177
178
        throw new OAuth2Message(302, $error, $error_description, $params);
179
    }
180
181
    /**
182
     * @param ServerRequestInterface $request
183
     *
184
     * @return Authorization
185
     */
186
    public function createAuthorizationFromRequest(ServerRequestInterface $request): Authorization
187
    {
188
        $authorization = $this->authorizationRequestLoader->load($request);
189
        $authorization = $this->parameterCheckerManager->process($authorization);
190
191
        return $authorization;
192
    }
193
}
194