Completed
Pull Request — master (#869)
by
unknown
02:45 queued 01:08
created

Introspector   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 11
c 0
b 0
f 0
lcom 1
cbo 4
dl 0
loc 150
ccs 46
cts 46
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A respondToIntrospectionRequest() 0 16 2
A verifyToken() 0 9 2
A checkIfTokenIsExpired() 0 8 2
A checkIfTokenIsRevoked() 0 6 2
A createActiveResponse() 0 19 1
A createInactiveResponse() 0 12 1
1
<?php
2
3
namespace League\OAuth2\Server;
4
5
use Exception;
6
use Lcobucci\JWT\Parser;
7
use Lcobucci\JWT\Signer\Keychain;
8
use Lcobucci\JWT\Signer\Rsa\Sha256;
9
use Lcobucci\JWT\Token;
10
use Lcobucci\JWT\ValidationData;
11
use League\OAuth2\Server\Exception\OAuthServerException;
12
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
13
use League\OAuth2\Server\ResponseTypes\IntrospectionResponse;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
class Introspector
17
{
18
    /**
19
     * @var AccessTokenRepositoryInterface
20
     */
21
    private $accessTokenRepository;
22
23
    /**
24
     * @var CryptKey
25
     */
26
    private $privateKey;
27
28
    /**
29
     * @var Parser
30
     */
31
    private $parser;
32
33
    /**
34
     * New Introspector instance.
35
     *
36
     * @param AccessTokenRepositoryInterface $accessTokenRepository
37
     * @param CryptKey                       $privateKey
38
     * @param Parser                         $parser
39
     */
40 5
    public function __construct(
41
        AccessTokenRepositoryInterface $accessTokenRepository,
42
        CryptKey $privateKey,
43
        Parser $parser
44
    ) {
45 5
        $this->accessTokenRepository = $accessTokenRepository;
46 5
        $this->privateKey = $privateKey;
47 5
        $this->parser = $parser;
48 5
    }
49
50
    /**
51
     * Return an introspection response.
52
     *
53
     * @param ServerRequestInterface $request
54
     *
55
     * @return IntrospectionResponse
56
     */
57 5
    public function respondToIntrospectionRequest(ServerRequestInterface $request)
58
    {
59 5
        $jwt = $request->getParsedBody()['token'] ?? null;
60
61
        try {
62 5
            $token = $this->parser->parse($jwt);
63
64 4
            $this->verifyToken($token);
65 3
            $this->checkIfTokenIsExpired($token);
66 2
            $this->checkIfTokenIsRevoked($token);
67
68 1
            return $this->createActiveResponse($token);
69 4
        } catch (Exception $ex) {
70 4
            return $this->createInactiveResponse();
71
        }
72
    }
73
74
    /**
75
     * Validate the JWT token.
76
     *
77
     * @param Token $token
78
     *
79
     * @throws OAuthServerException
80
     */
81 4
    private function verifyToken(Token $token)
82
    {
83 4
        $keychain = new Keychain();
84 4
        $key = $keychain->getPrivateKey($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
85
86 4
        if (!$token->verify(new Sha256, $key)) {
87 1
            throw OAuthServerException::accessDenied('Access token could not be verified');
88
        }
89 3
    }
90
91
    /**
92
     * Ensure access token hasn't expired
93
     *
94
     * @param Token $token
95
     *
96
     * @throws OAuthServerException
97
     */
98 3
    private function checkIfTokenIsExpired(Token $token)
99
    {
100 3
        $data = new ValidationData(time());
101
102 3
        if (!$token->validate($data)) {
103 1
            throw OAuthServerException::accessDenied('Access token is invalid');
104
        }
105 2
    }
106
107
    /**
108
     * Check if the given access token is revoked.
109
     *
110
     * @param Token $token
111
     *
112
     * @throws OAuthServerException
113
     */
114 2
    private function checkIfTokenIsRevoked(Token $token)
115
    {
116 2
        if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
117 1
            throw OAuthServerException::accessDenied('Access token has been revoked');
118
        }
119 1
    }
120
121
    /**
122
     * Create active introspection response.
123
     *
124
     * @param Token $token
125
     *
126
     * @return IntrospectionResponse
127
     */
128 1
    private function createActiveResponse(Token $token)
129
    {
130 1
        $response = new IntrospectionResponse();
131
132 1
        $response->setIntrospectionData(
133
            [
134 1
                'active' => true,
135 1
                'token_type' => 'access_token',
136 1
                'scope' => $token->getClaim('scopes', ''),
137 1
                'client_id' => $token->getClaim('aud'),
138 1
                'exp' => $token->getClaim('exp'),
139 1
                'iat' => $token->getClaim('iat'),
140 1
                'sub' => $token->getClaim('sub'),
141 1
                'jti' => $token->getClaim('jti'),
142
            ]
143
            );
144
145 1
        return $response;
146
    }
147
148
    /**
149
     * Create inactive introspection response
150
     *
151
     * @return IntrospectionResponse
152
     */
153 4
    private function createInactiveResponse()
154
    {
155 4
        $response = new IntrospectionResponse();
156
157 4
        $response->setIntrospectionData(
158
            [
159 4
                'active' => false,
160
            ]
161
        );
162
163 4
        return $response;
164
    }
165
}
166