Failed Conditions
Push — master ( 14a869...357c66 )
by Florent
05:07
created

TokenIntrospectionEndpoint::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
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\TokenIntrospectionEndpoint;
15
16
use Http\Message\ResponseFactory;
17
use OAuth2Framework\Component\Core\Util\RequestBodyParser;
18
use Psr\Http\Server\RequestHandlerInterface;
19
use Psr\Http\Server\MiddlewareInterface;
20
use OAuth2Framework\Component\Core\ResourceServer\ResourceServer;
21
use OAuth2Framework\Component\Core\Message\OAuth2Message;
22
use Psr\Http\Message\ResponseInterface;
23
use Psr\Http\Message\ServerRequestInterface;
24
25
final class TokenIntrospectionEndpoint implements MiddlewareInterface
26
{
27
    /**
28
     * @var TokenTypeHintManager
29
     */
30
    private $tokenTypeHintManager;
31
32
    /**
33
     * @var ResponseFactory
34
     */
35
    private $responseFactory;
36
37
    /**
38
     * TokenIntrospectionEndpoint constructor.
39
     *
40
     * @param TokenTypeHintManager $tokenTypeHintManager
41
     * @param ResponseFactory      $responseFactory
42
     */
43
    public function __construct(TokenTypeHintManager $tokenTypeHintManager, ResponseFactory $responseFactory)
44
    {
45
        $this->tokenTypeHintManager = $tokenTypeHintManager;
46
        $this->responseFactory = $responseFactory;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
53
    {
54
        try {
55
            $resourceServer = $this->getResourceServer($request);
56
            $token = $this->getToken($request);
57
            $hints = $this->getTokenTypeHints($request);
58
59
            foreach ($hints as $hint) {
60
                $result = $hint->find($token);
61
                if (null !== $result) {
62
                    if (null === $result->getResourceServerId() || $result->getResourceServerId()->getValue() === $resourceServer->getResourceServerId()->getValue()) {
63
                        $data = $hint->introspect($result);
64
                        $response = $this->responseFactory->createResponse();
65
                        $response->getBody()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
66
                        $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate, private', 'Pragma' => 'no-cache'];
67
                        foreach ($headers as $k => $v) {
68
                            $response = $response->withHeader($k, $v);
69
                        }
70
71
                        return $response;
72
                    }
73
                }
74
            }
75
            $responseContent = ['active' => false];
76
            $responseStatucCode = 200;
77
        } catch (OAuth2Message $e) {
78
            $responseContent = $e->getData();
79
            $responseStatucCode = $e->getCode();
80
        }
81
82
        $response = $this->responseFactory->createResponse($responseStatucCode);
83
        $response->getBody()->write(json_encode($responseContent, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
84
        $headers = ['Content-Type' => 'application/json; charset=UTF-8', 'Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate, private', 'Pragma' => 'no-cache'];
85
        foreach ($headers as $k => $v) {
86
            $response = $response->withHeader($k, $v);
87
        }
88
89
        return $response;
90
    }
91
92
    /**
93
     * @param ServerRequestInterface $request
94
     *
95
     * @throws OAuth2Message
96
     *
97
     * @return ResourceServer
98
     */
99
    private function getResourceServer(ServerRequestInterface $request): ResourceServer
100
    {
101
        $resourceServer = $request->getAttribute('resource_server');
102
        if (null === $resourceServer) {
103
            throw new OAuth2Message(400, OAuth2Message::ERROR_INVALID_RESOURCE_SERVER, 'Resource Server authentication failed.');
104
        }
105
106
        return $resourceServer;
107
    }
108
109
    /**
110
     * @param ServerRequestInterface $request
111
     *
112
     * @throws OAuth2Message
113
     *
114
     * @return string
115
     */
116
    private function getToken(ServerRequestInterface $request): string
117
    {
118
        $params = $this->getRequestParameters($request);
119
        if (!array_key_exists('token', $params)) {
120
            throw new OAuth2Message(400, OAuth2Message::ERROR_INVALID_REQUEST, 'The parameter "token" is missing.');
121
        }
122
123
        return $params['token'];
124
    }
125
126
    /**
127
     * @param ServerRequestInterface $request
128
     *
129
     * @throws OAuth2Message
130
     *
131
     * @return TokenTypeHint[]
132
     */
133
    private function getTokenTypeHints(ServerRequestInterface $request): array
134
    {
135
        $params = $this->getRequestParameters($request);
136
        $tokenTypeHints = $this->tokenTypeHintManager->getTokenTypeHints();
137
138
        if (array_key_exists('token_type_hint', $params)) {
139
            $tokenTypeHint = $params['token_type_hint'];
140
            if (!array_key_exists($params['token_type_hint'], $tokenTypeHints)) {
141
                throw new OAuth2Message(400, 'unsupported_token_type', sprintf('The token type hint "%s" is not supported. Please use one of the following values: %s.', $params['token_type_hint'], implode(', ', array_keys($tokenTypeHints))));
142
            }
143
144
            $hint = $tokenTypeHints[$tokenTypeHint];
145
            unset($tokenTypeHints[$tokenTypeHint]);
146
            $tokenTypeHints = [$tokenTypeHint => $hint] + $tokenTypeHints;
147
        }
148
149
        return $tokenTypeHints;
150
    }
151
152
    /**
153
     * @param ServerRequestInterface $request
154
     *
155
     * @return array
156
     */
157
    private function getRequestParameters(ServerRequestInterface $request): array
158
    {
159
        $parameters = RequestBodyParser::parseFormUrlEncoded($request);
160
161
        return array_intersect_key($parameters, array_flip(['token', 'token_type_hint']));
162
    }
163
}
164