Failed Conditions
Push — master ( c6baf0...a3629e )
by Florent
16:19
created

AuthorizationEndpoint::process()   C

Complexity

Conditions 11
Paths 218

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 46
rs 6.2583
c 0
b 0
f 0
cc 11
nc 218
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\ConsentScreen\ExtensionManager;
18
use OAuth2Framework\Component\AuthorizationEndpoint\Exception\OAuth2AuthorizationException;
19
use OAuth2Framework\Component\AuthorizationEndpoint\ParameterChecker\ParameterCheckerManager;
20
use OAuth2Framework\Component\AuthorizationEndpoint\UserAccount\UserAccountCheckerManager;
21
use OAuth2Framework\Component\AuthorizationEndpoint\UserAccount\UserAccountDiscovery;
22
use OAuth2Framework\Component\Core\Message\OAuth2Message;
23
use Psr\Http\Message\ResponseInterface;
24
use Psr\Http\Message\ServerRequestInterface;
25
use Psr\Http\Server\MiddlewareInterface;
26
use Psr\Http\Server\RequestHandlerInterface;
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
    public function __construct(MessageFactory $messageFactory, AuthorizationRequestLoader $authorizationRequestLoader, ParameterCheckerManager $parameterCheckerManager, UserAccountDiscovery $userAccountDiscovery, UserAccountCheckerManager $userAccountCheckerManager, ExtensionManager $consentScreenExtensionManager)
64
    {
65
        $this->messageFactory = $messageFactory;
66
        $this->authorizationRequestLoader = $authorizationRequestLoader;
67
        $this->parameterCheckerManager = $parameterCheckerManager;
68
        $this->userAccountDiscovery = $userAccountDiscovery;
69
        $this->userAccountCheckerManager = $userAccountCheckerManager;
70
        $this->consentScreenExtensionManager = $consentScreenExtensionManager;
71
    }
72
73
    abstract protected function redirectToLoginPage(ServerRequestInterface $request, Authorization $authorization): ResponseInterface;
74
75
    abstract protected function processConsentScreen(ServerRequestInterface $request, Authorization $authorization): ResponseInterface;
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
81
    {
82
        try {
83
            $authorization = $this->createAuthorizationFromRequest($request);
84
            $isFullyAuthenticated = null;
85
            $userAccount = $this->userAccountDiscovery->find($isFullyAuthenticated);
86
            if (!\is_bool($isFullyAuthenticated)) {
87
                $isFullyAuthenticated = false;
88
            }
89
            if (null !== $userAccount) {
90
                $authorization = $authorization->withUserAccount($userAccount, $isFullyAuthenticated);
91
            }
92
            $this->userAccountCheckerManager->check($authorization, $userAccount, $isFullyAuthenticated);
93
            if (null === $userAccount) {
94
                return $this->redirectToLoginPage($request, $authorization);
95
            }
96
            $authorization = $this->consentScreenExtensionManager->processBefore($request, $authorization);
97
98
            return $this->processConsentScreen($request, $authorization);
99
        } catch (OAuth2AuthorizationException $e) {
100
            throw $e;
101
        } catch (Exception\ProcessAuthorizationException $e) {
102
            $authorization = $e->getAuthorization();
103
            $authorization = $this->consentScreenExtensionManager->processAfter($request, $authorization);
104
            if (false === $authorization->isAuthorized()) {
105
                $this->throwRedirectionException($authorization, OAuth2Message::ERROR_ACCESS_DENIED, 'The resource owner denied access to your client.');
106
            }
107
108
            $responseType = $authorization->getResponseType();
109
110
            try {
111
                $authorization = $responseType->preProcess($authorization);
112
                $authorization = $responseType->process($authorization);
113
            } catch (OAuth2Message $e) {
114
                $this->throwRedirectionException($authorization, $e->getMessage(), $e->getErrorDescription());
115
            }
116
117
            return $this->buildResponse($authorization);
118
        } catch (Exception\CreateRedirectionException $e) {
119
            $this->throwRedirectionException($e->getAuthorization(), $e->getMessage(), $e->getDescription());
120
        } catch (Exception\ShowConsentScreenException $e) {
121
            return $this->processConsentScreen($request, $e->getAuthorization());
122
        } catch (Exception\RedirectToLoginPageException $e) {
123
            return $this->redirectToLoginPage($request, $e->getAuthorization());
124
        }
125
    }
126
127
    protected function buildResponse(Authorization $authorization): ResponseInterface
128
    {
129
        $response = $authorization->getResponseMode()->buildResponse(
130
            $this->messageFactory->createResponse(),
131
            $authorization->getRedirectUri(),
132
            $authorization->getResponseParameters()
133
        );
134
        foreach ($authorization->getResponseHeaders() as $k => $v) {
135
            $response = $response->withHeader($k, $v);
136
        }
137
138
        return $response;
139
    }
140
141
    protected function throwRedirectionException(Authorization $authorization, string $error, string $errorDescription)
142
    {
143
        $params = $authorization->getResponseParameters();
144
        if (null === $authorization->getResponseMode() || null === $authorization->getRedirectUri()) {
145
            throw new OAuth2Message(400, $error, $errorDescription);
146
        }
147
        $params += [
148
            'response_mode' => $authorization->getResponseMode(),
149
            'redirect_uri' => $authorization->getRedirectUri(),
150
        ];
151
152
        throw new OAuth2Message(302, $error, $errorDescription, $params);
153
    }
154
155
    public function createAuthorizationFromRequest(ServerRequestInterface $request): Authorization
156
    {
157
        $authorization = $this->authorizationRequestLoader->load($request);
158
        $authorization = $this->parameterCheckerManager->process($authorization);
159
160
        return $authorization;
161
    }
162
}
163