Passed
Pull Request — master (#1135)
by
unknown
03:32
created

RevokeTokenHandler::setRefreshTokenRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * @author      Alex Bilbie <[email protected]>
4
 * @copyright   Copyright (c) Alex Bilbie
5
 * @license     http://mit-license.org/
6
 *
7
 * @link        https://github.com/thephpleague/oauth2-server
8
 */
9
10
namespace League\OAuth2\Server;
11
12
use Exception;
13
use Lcobucci\JWT\Parser;
14
use Lcobucci\JWT\Signer\Rsa\Sha256;
15
use Lcobucci\JWT\Token;
16
use League\Event\EmitterAwareInterface;
17
use League\Event\EmitterAwareTrait;
18
use League\OAuth2\Server\Exception\OAuthServerException;
19
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
20
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
21
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
22
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
23
use Psr\Http\Message\ServerRequestInterface;
24
25
class RevokeTokenHandler implements EmitterAwareInterface
26
{
27 1
    use EmitterAwareTrait, CryptTrait, RequestValidatorTrait;
28
29
    /**
30
     * @var ClientRepositoryInterface
31
     */
32
    protected $clientRepository;
33
34
    /**
35
     * @var AccessTokenRepositoryInterface
36
     */
37
    private $accessTokenRepository;
38
39
    /**
40
     * @var RefreshTokenRepositoryInterface
41
     */
42
    private $refreshTokenRepository;
43
44
    /**
45
     * @var bool
46
     */
47
    private $canRevokeAccessTokens;
48
49
    /**
50
     * @var CryptKey
51
     */
52
    protected $publicKey;
53
54
    /**
55
     * New handler instance.
56
     *
57
     * @param RefreshTokenRepositoryInterface $refreshTokenRepository
58
     * @param CryptKey|string                 $publicKey
59
     * @param bool                            $canRevokeAccessTokens
60
     */
61 12
    public function __construct(
62
        RefreshTokenRepositoryInterface $refreshTokenRepository,
63
        $publicKey,
64
        $canRevokeAccessTokens = true
65
    ) {
66 12
        $this->setRefreshTokenRepository($refreshTokenRepository);
67
68 12
        if ($publicKey instanceof CryptKey === false) {
69 1
            $publicKey = new CryptKey($publicKey);
70
        }
71 12
        $this->publicKey = $publicKey;
72
73 12
        $this->canRevokeAccessTokens = $canRevokeAccessTokens;
74 12
    }
75
76
    /**
77
     * @return ClientRepositoryInterface
78
     */
79
    public function getClientRepository()
80
    {
81
        return $this->clientRepository;
82
    }
83
84
    /**
85
     * @param ClientRepositoryInterface $clientRepository
86
     */
87 12
    public function setClientRepository(ClientRepositoryInterface $clientRepository)
88
    {
89 12
        $this->clientRepository = $clientRepository;
90 12
    }
91
92
    /**
93
     * @param AccessTokenRepositoryInterface $accessTokenRepository
94
     */
95 12
    public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository)
96
    {
97 12
        $this->accessTokenRepository = $accessTokenRepository;
98 12
    }
99
100
    /**
101
     * @param RefreshTokenRepositoryInterface $refreshTokenRepository
102
     */
103 12
    public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository)
104
    {
105 12
        $this->refreshTokenRepository = $refreshTokenRepository;
106 12
    }
107
108
    /**
109
     * Set the public key
110
     *
111
     * @param CryptKey $key
112
     */
113
    public function setPublicKey(CryptKey $key)
114
    {
115
        $this->publicKey = $key;
116
    }
117
118
    /**
119
     * Return the grant identifier that can be used in matching up requests.
120
     *
121
     * @return string
122
     */
123 12
    public function getIdentifier()
124
    {
125 12
        return '';
126
    }
127
128
    /**
129
     * Return a revoke token response.
130
     * https://tools.ietf.org/html/rfc7009
131
     *
132
     * @param ServerRequestInterface $request
133
     * @param ResponseTypeInterface  $responseType
134
     *
135
     * @throws OAuthServerException
136
     *
137
     * @return ResponseTypeInterface
138
     */
139 12
    public function respondToRevokeTokenRequest(ServerRequestInterface $request, ResponseTypeInterface $responseType)
140
    {
141 12
        $token = $this->getRequestParameter('token', $request);
142 12
        $hint = $this->getRequestParameter('token_type_hint', $request);
143
144
        // Validate request
145 12
        $client = $this->validateClient($request);
146 12
        $clientId = $client->getIdentifier();
147
148 12
        if (is_null($token)) {
149 1
            return $responseType;
150
        }
151
152
        // Attempt to revoke tokens
153 11
        if ($hint === 'refresh_token') {
154 6
            if (!$this->revokeRefreshToken($token, $clientId, $request)) {
155 5
                $this->revokeAccessToken($token, $clientId, $request);
156
            }
157
        } else {
158 5
            if (!$this->revokeAccessToken($token, $clientId, $request)) {
159 2
                $this->revokeRefreshToken($token, $clientId, $request);
160
            }
161
        }
162
163 9
        return $responseType;
164
    }
165
166
    /**
167
     * @param string $tokenParam
168
     * @param string $clientId
169
     *
170
     * @throws OAuthServerException
171
     *
172
     * @return bool true if token was a refresh token
173
     */
174 6
    protected function revokeAccessToken($tokenParam, $clientId, ServerRequestInterface $request)
0 ignored issues
show
Unused Code introduced by
The parameter $clientId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

174
    protected function revokeAccessToken($tokenParam, /** @scrutinizer ignore-unused */ $clientId, ServerRequestInterface $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
175
    {
176 6
        $token = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $token is dead and can be removed.
Loading history...
177
        try {
178 6
            $token = (new Parser())->parse($tokenParam);
179
180 3
            if ($token->verify(new Sha256(), $this->publicKey->getKeyPath()) === false) {
181 3
                return false;
182
            }
183 3
        } catch (Exception $exception) {
184
            // JWT couldn't be parsed as access token
185 3
            return false;
186
        }
187
188 3
        $clientId = $token->getClaim('aud');
189 3
        if ($clientId !== $clientId) {
190
            throw OAuthServerException::invalidClient($request);
191
        }
192
193 3
        if (!$this->canRevokeAccessTokens) {
194 1
            $errorMessage = 'The authorization server does not support the revocation of the presented token type.';
195 1
            throw new OAuthServerException($errorMessage, 2, 'unsupported_token_type', 400);
196
        }
197 2
        $this->accessTokenRepository->revokeAccessToken($token->getClaim('jti'));
198
199 2
        return true;
200
    }
201
202
    /**
203
     * @param string $tokenParam
204
     * @param string $clientId
205
     *
206
     * @throws OAuthServerException
207
     *
208
     * @return bool true if token was a refresh token
209
     */
210 8
    protected function revokeRefreshToken($tokenParam, $clientId, ServerRequestInterface $request)
211
    {
212 8
        $refreshTokenData = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $refreshTokenData is dead and can be removed.
Loading history...
213
        try {
214 8
            $refreshToken = $this->decrypt($tokenParam);
215 6
            $refreshTokenData = json_decode($refreshToken, true);
216 2
        } catch (Exception $e) {
217
            // token couldn't be decrypted as refresh token
218 2
            return false;
219
        }
220
221 6
        if ($refreshTokenData['client_id'] !== $clientId) {
222 1
            throw OAuthServerException::invalidClient($request);
223
        }
224
225 5
        $this->refreshTokenRepository->revokeRefreshToken($refreshTokenData['refresh_token_id']);
226 5
        if ($this->canRevokeAccessTokens) {
227 4
            $this->accessTokenRepository->revokeAccessToken($refreshTokenData['access_token_id']);
228
        }
229
230 5
        return true;
231
    }
232
}
233