Completed
Pull Request — master (#925)
by Steve
01:48
created

BearerTokenValidator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 86.67%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 2
dl 0
loc 112
ccs 26
cts 30
cp 0.8667
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setPrivateKey() 0 4 1
A validateIntrospection() 0 18 5
A getTokenFromRequest() 0 7 1
A isTokenUnverified() 0 11 1
A isTokenExpired() 0 6 1
A isTokenRevoked() 0 4 1
1
<?php
2
3
namespace League\OAuth2\Server\IntrospectionValidators;
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\CryptKey;
12
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
13
use Psr\Http\Message\ServerRequestInterface;
14
15
class BearerTokenValidator implements IntrospectionValidatorInterface
16
{
17
    /**
18
     * @var AccessTokenRepositoryInterface
19
     */
20
    private $accessTokenRepository;
21
22
    /**
23
     * @var \League\OAuth2\Server\CryptKey
24
     */
25
    protected $privateKey;
26
27
    /**
28
     * @param AccessTokenRepositoryInterface $accessTokenRepository
29
     */
30 4
    public function __construct(AccessTokenRepositoryInterface $accessTokenRepository)
31
    {
32 4
        $this->accessTokenRepository = $accessTokenRepository;
33 4
    }
34
35
    /**
36
     * Set the private key.
37
     *
38
     * @param \League\OAuth2\Server\CryptKey $key
39
     */
40 2
    public function setPrivateKey(CryptKey $key)
41
    {
42 2
        $this->privateKey = $key;
43 2
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 5
    public function validateIntrospection(ServerRequestInterface $request)
49
    {
50
        try {
51 5
            $token = $this->getTokenFromRequest($request);
52 1
        } catch (InvalidArgumentException $e) {
53 1
            return false;
54
        }
55
56
        if (
57 4
            $this->isTokenRevoked($token) ||
58 3
            $this->isTokenExpired($token) ||
59 4
            $this->isTokenUnverified($token)
60
        ) {
61 3
            return false;
62
        }
63
64 1
        return true;
65
    }
66
67
    /**
68
     * Gets the token from the request body.
69
     *
70
     * @param ServerRequestInterface $request
71
     *
72
     * @return Token
73
     */
74
    public function getTokenFromRequest(ServerRequestInterface $request)
75
    {
76
        $jwt = $request->getParsedBody()['token'] ?? null;
77
78
        return (new Parser())
79
            ->parse($jwt);
80
    }
81
82
    /**
83
     * Checks whether the token is unverified.
84
     *
85
     * @param Token $token
86
     *
87
     * @return bool
88
     */
89 2
    private function isTokenUnverified(Token $token)
90
    {
91 2
        $keychain = new Keychain();
92
93 2
        $key = $keychain->getPrivateKey(
94 2
            $this->privateKey->getKeyPath(),
95 2
            $this->privateKey->getPassPhrase()
96
        );
97
98 2
        return $token->verify(new Sha256(), $key->getContent()) === false;
99
    }
100
101
    /**
102
     * Ensure access token hasn't expired.
103
     *
104
     * @param Token $token
105
     *
106
     * @return bool
107
     */
108 3
    private function isTokenExpired(Token $token)
109
    {
110 3
        $data = new ValidationData(time());
111
112 3
        return !$token->validate($data);
113
    }
114
115
    /**
116
     * Check if the given token is revoked.
117
     *
118
     * @param Token $token
119
     *
120
     * @return bool
121
     */
122 4
    private function isTokenRevoked(Token $token)
123
    {
124 4
        return $this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'));
125
    }
126
}
127