Completed
Pull Request — master (#925)
by
unknown
02:58
created

Introspector::respondToIntrospectionRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 8
cts 8
cp 1
rs 9.7333
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
3
namespace League\OAuth2\Server;
4
5
use InvalidArgumentException;
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\Repositories\AccessTokenRepositoryInterface;
12
use League\OAuth2\Server\ResponseTypes\IntrospectionResponse;
13
use Psr\Http\Message\ServerRequestInterface;
14
15
class Introspector
16
{
17
    /**
18
     * @var AccessTokenRepositoryInterface
19
     */
20
    private $accessTokenRepository;
21
22
    /**
23
     * @var CryptKey
24
     */
25
    private $privateKey;
26
27
    /**
28
     * @var Parser
29
     */
30
    private $parser;
31
32
    /**
33
     * New Introspector instance.
34
     *
35
     * @param AccessTokenRepositoryInterface $accessTokenRepository
36
     * @param CryptKey                       $privateKey
37
     * @param Parser                         $parser
38
     */
39 5
    public function __construct(
40
        AccessTokenRepositoryInterface $accessTokenRepository,
41
        CryptKey $privateKey,
42
        Parser $parser
43
    ) {
44 5
        $this->accessTokenRepository = $accessTokenRepository;
45 5
        $this->privateKey = $privateKey;
46 5
        $this->parser = $parser;
47 5
    }
48
49
    /**
50
     * Return an introspection response.
51
     *
52
     * @param ServerRequestInterface $request
53
     *
54
     * @return IntrospectionResponse
55
     */
56 5
    public function respondToIntrospectionRequest(
57
        ServerRequestInterface $request,
58
        IntrospectionResponse $responseType
59
    ) {
60 5
        $jwt = $request->getParsedBody()['token'] ?? null;
61
62
        try {
63 5
            $token = $this->parser->parse($jwt);
64 1
        } catch (InvalidArgumentException $e) {
65 1
            return $responseType;
66
        }
67
68 4
        return $this->isTokenValid($token) ?
69 1
            $this->setTokenOnResponse($token, $responseType) :
70 4
            $responseType;
71
    }
72
73
    /**
74
     * Validate the JWT and make sure it has not expired or been revoked
75
     *
76
     * @return bool
77
     */
78 4
    private function isTokenValid(Token $token)
79
    {
80 4
        return $this->verifyToken($token) && !$this->isTokenExpired($token) && !$this->isTokenRevoked($token);
81
    }
82
83
    /**
84
     * Validate the JWT token.
85
     *
86
     * @param Token $token
87
     *
88
     * @return bool
89
     */
90 4
    private function verifyToken(Token $token)
91
    {
92 4
        $keychain = new Keychain();
93 4
        $key = $keychain->getPrivateKey($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase());
94
95 4
        return $token->verify(new Sha256, $key->getContent());
96
    }
97
98
    /**
99
     * Ensure access token hasn't expired
100
     *
101
     * @param Token $token
102
     *
103
     * @return bool
104
     */
105 3
    private function isTokenExpired(Token $token)
106
    {
107 3
        $data = new ValidationData(time());
108
109 3
        return !$token->validate($data);
110
    }
111
112
    /**
113
     * Check if the given access token is revoked.
114
     *
115
     * @param Token $token
116
     *
117
     * @return bool
118
     */
119 2
    private function isTokenRevoked(Token $token)
120
    {
121 2
        return $this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'));
122
    }
123
124
    /**
125
     * Create active introspection response.
126
     *
127
     * @param Token $token
128
     *
129
     * @return IntrospectionResponse
130
     */
131 1
    private function setTokenOnResponse(Token $token, IntrospectionResponse $responseType)
132
    {
133 1
        $responseType->setToken($token);
134
135 1
        return $responseType;
136
    }
137
}
138