1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CommerceGuys\Guzzle\Oauth2\Tests\GrantType; |
4
|
|
|
|
5
|
|
|
use CommerceGuys\Guzzle\Oauth2\AccessToken; |
6
|
|
|
use CommerceGuys\Guzzle\Oauth2\GrantType\ClientCredentials; |
7
|
|
|
use CommerceGuys\Guzzle\Oauth2\GrantType\RefreshToken; |
8
|
|
|
use CommerceGuys\Guzzle\Oauth2\Middleware\OAuthMiddleware; |
9
|
|
|
use CommerceGuys\Guzzle\Oauth2\Tests\MockOAuth2Server; |
10
|
|
|
use CommerceGuys\Guzzle\Oauth2\Tests\MockOAuthMiddleware; |
11
|
|
|
use CommerceGuys\Guzzle\Oauth2\Tests\TestBase; |
12
|
|
|
use GuzzleHttp\HandlerStack; |
13
|
|
|
use GuzzleHttp\RequestOptions; |
14
|
|
|
use Psr\Http\Message\ResponseInterface; |
15
|
|
|
|
16
|
|
|
class OAuthMiddlewareTest extends TestBase |
17
|
|
|
{ |
18
|
|
|
public function testMiddlewareOnBeforeWhenAccessTokenNotSetYet() |
19
|
|
|
{ |
20
|
|
|
$client = $this->createClient([ |
21
|
|
|
RequestOptions::AUTH => 'oauth2', |
22
|
|
|
], |
23
|
|
|
[ |
24
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 2, |
25
|
|
|
]); |
26
|
|
|
|
27
|
|
|
$middleware = new OAuthMiddleware($client, new ClientCredentials($client, [ |
28
|
|
|
'client_id' => 'test', |
29
|
|
|
'client_secret' => 'testSecret', |
30
|
|
|
])); |
31
|
|
|
|
32
|
|
|
$handlerStack = $this->getHandlerStack(); |
33
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
34
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
35
|
|
|
|
36
|
|
|
|
37
|
|
|
/** @var ResponseInterface */ |
38
|
|
|
$response = $client->get('/api/collection'); |
39
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function testMiddlewareOnBeforeUsesRefreshToken() |
43
|
|
|
{ |
44
|
|
|
$credentials = [ |
45
|
|
|
'client_id' => 'test', |
46
|
|
|
'client_secret' => 'testSecret', |
47
|
|
|
]; |
48
|
|
|
|
49
|
|
|
$client = $this->createClient( |
50
|
|
|
[ |
51
|
|
|
RequestOptions::AUTH => 'oauth2', |
52
|
|
|
], |
53
|
|
|
[ |
54
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 3, |
55
|
|
|
] |
56
|
|
|
); |
57
|
|
|
|
58
|
|
|
$accessTokenGrantType = new ClientCredentials( |
59
|
|
|
$client, |
60
|
|
|
$credentials |
61
|
|
|
); |
62
|
|
|
$refreshToken = new RefreshToken($client, $credentials); |
63
|
|
|
|
64
|
|
|
$middleware = new OAuthMiddleware( |
65
|
|
|
$client, |
66
|
|
|
$accessTokenGrantType, |
67
|
|
|
$refreshToken |
68
|
|
|
); |
69
|
|
|
$handlerStack = $this->getHandlerStack(); |
70
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
71
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
72
|
|
|
|
73
|
|
|
// Initially, the access token should be expired. Before the first API |
74
|
|
|
// call, the middleware will use the refresh token to get a new access |
75
|
|
|
// token. |
76
|
|
|
$accessToken = new AccessToken('tokenOld', 'client_credentials', [ |
77
|
|
|
'refresh_token' => 'refreshTokenOld', |
78
|
|
|
'expires' => 0 |
79
|
|
|
]); |
80
|
|
|
$middleware->setAccessToken($accessToken); |
81
|
|
|
|
82
|
|
|
$response = $client->get('/api/collection'); |
83
|
|
|
|
84
|
|
|
// Now, the access token should be valid. |
85
|
|
|
$this->assertEquals('token', $middleware->getAccessToken()->getToken()); |
86
|
|
|
$this->assertFalse($middleware->getAccessToken()->isExpired()); |
87
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
88
|
|
|
|
89
|
|
|
// Also, the refresh token should have changed. |
90
|
|
|
$newRefreshToken = $middleware->getRefreshToken(); |
91
|
|
|
$this->assertEquals('refreshToken', $newRefreshToken->getToken()); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
public function testMiddlewareOnFailureUsesRefreshToken() |
95
|
|
|
{ |
96
|
|
|
$credentials = [ |
97
|
|
|
'client_id' => 'test', |
98
|
|
|
'client_secret' => 'testSecret', |
99
|
|
|
]; |
100
|
|
|
$client = $this->createClient( |
101
|
|
|
[ |
102
|
|
|
RequestOptions::AUTH => 'oauth2', |
103
|
|
|
], |
104
|
|
|
[ |
105
|
|
|
MockOAuth2Server::KEY_TOKEN_INVALID_COUNT => 1, |
106
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 3, |
107
|
|
|
] |
108
|
|
|
); |
109
|
|
|
|
110
|
|
|
$accessTokenGrantType = new ClientCredentials($client, $credentials); |
111
|
|
|
|
112
|
|
|
$middleware = new MockOAuthMiddleware( |
113
|
|
|
$client, |
114
|
|
|
$accessTokenGrantType, |
115
|
|
|
new RefreshToken($client, $credentials), |
116
|
|
|
[ |
117
|
|
|
MockOAuthMiddleware::KEY_TOKEN_EXPIRED_ON_FAILURE_COUNT => 1, |
118
|
|
|
] |
119
|
|
|
); |
120
|
|
|
$handlerStack = $this->getHandlerStack(); |
121
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
122
|
|
|
$handlerStack->push($middleware->modifyBeforeOnFailure()); |
|
|
|
|
123
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
124
|
|
|
|
125
|
|
|
// Use a access token that isn't expired on the client side, but |
126
|
|
|
// the server thinks is expired. This should trigger the onFailure event |
127
|
|
|
// in the middleware, forcing it to try the refresh token grant type. |
128
|
|
|
$accessToken = new AccessToken('tokenInvalid', 'client_credentials', [ |
129
|
|
|
'refresh_token' => 'refreshTokenOld', |
130
|
|
|
'expires' => time() + 500, |
131
|
|
|
]); |
132
|
|
|
$middleware->setAccessToken($accessToken); |
133
|
|
|
$this->assertFalse($middleware->getAccessToken()->isExpired()); |
134
|
|
|
|
135
|
|
|
//Will invoke once the onFailure |
136
|
|
|
$response = $client->get('/api/collection'); |
137
|
|
|
|
138
|
|
|
// Now, the access token should be valid. |
139
|
|
|
$this->assertFalse($middleware->getAccessToken()->isExpired()); |
140
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
141
|
|
|
|
142
|
|
|
// Also, the refresh token should have changed. |
143
|
|
|
$newRefreshToken = $middleware->getRefreshToken(); |
144
|
|
|
$this->assertEquals('refreshToken', $newRefreshToken->getToken()); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function testMiddlewareWithValidNotExpiredToken() |
148
|
|
|
{ |
149
|
|
|
$client = $this->createClient([ |
150
|
|
|
RequestOptions::AUTH => 'oauth2', |
151
|
|
|
RequestOptions::HTTP_ERRORS => false, |
152
|
|
|
], [ |
153
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 1, |
154
|
|
|
]); |
155
|
|
|
$credentials = [ |
156
|
|
|
'client_id' => 'test', |
157
|
|
|
'client_secret' => 'testSecret', |
158
|
|
|
]; |
159
|
|
|
|
160
|
|
|
$accessTokenGrantType = new ClientCredentials($client, $credentials); |
161
|
|
|
|
162
|
|
|
$middleware = new OAuthMiddleware($client, $accessTokenGrantType); |
163
|
|
|
$handlerStack = $this->getHandlerStack(); |
164
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
165
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
166
|
|
|
|
167
|
|
|
// Set a valid token. |
168
|
|
|
$middleware->setAccessToken('token'); |
169
|
|
|
$this->assertEquals($middleware->getAccessToken()->getToken(), 'token'); |
170
|
|
|
$this->assertFalse($middleware->getAccessToken()->isExpired()); |
171
|
|
|
$response = $client->get('/api/collection'); |
172
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
public function testOnFailureWhichReachesLimit() |
176
|
|
|
{ |
177
|
|
|
$client = $this->createClient([ |
178
|
|
|
RequestOptions::AUTH => 'oauth2', |
179
|
|
|
RequestOptions::HTTP_ERRORS => false, |
180
|
|
|
], [ |
181
|
|
|
MockOAuth2Server::KEY_TOKEN_INVALID_COUNT => 6, |
182
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 6, |
183
|
|
|
]); |
184
|
|
|
$credentials = [ |
185
|
|
|
'client_id' => 'test', |
186
|
|
|
'client_secret' => 'testSecret', |
187
|
|
|
]; |
188
|
|
|
|
189
|
|
|
$accessTokenGrantType = new ClientCredentials($client, $credentials); |
190
|
|
|
|
191
|
|
|
$middleware = new OAuthMiddleware($client, $accessTokenGrantType, new RefreshToken($client, $credentials)); |
192
|
|
|
$handlerStack = $this->getHandlerStack(); |
193
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
194
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
195
|
|
|
|
196
|
|
|
//Will invoke 5 times onFailure |
197
|
|
|
$middleware->setAccessToken('tokenInvalid'); |
198
|
|
|
$response = $client->get('/api/collection'); |
199
|
|
|
$this->assertEquals(401, $response->getStatusCode()); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
public function testOnFailureWhichSuccessOnThirdTime() |
203
|
|
|
{ |
204
|
|
|
$client = $this->createClient([ |
205
|
|
|
RequestOptions::AUTH => 'oauth2', |
206
|
|
|
RequestOptions::HTTP_ERRORS => false, |
207
|
|
|
], [ |
208
|
|
|
MockOAuth2Server::KEY_TOKEN_INVALID_COUNT => 2, |
209
|
|
|
MockOAuth2Server::KEY_EXPECTED_QUERY_COUNT => 4, |
210
|
|
|
]); |
211
|
|
|
$credentials = [ |
212
|
|
|
'client_id' => 'test', |
213
|
|
|
'client_secret' => 'testSecret', |
214
|
|
|
]; |
215
|
|
|
|
216
|
|
|
$accessTokenGrantType = new ClientCredentials($client, $credentials); |
217
|
|
|
|
218
|
|
|
$middleware = new OAuthMiddleware($client, $accessTokenGrantType); |
219
|
|
|
$handlerStack = $this->getHandlerStack(); |
220
|
|
|
$handlerStack->push($middleware->onBefore()); |
|
|
|
|
221
|
|
|
$handlerStack->push($middleware->onFailure(5)); |
|
|
|
|
222
|
|
|
|
223
|
|
|
// Will invoke 2 times onFailure |
224
|
|
|
$response = $client->get('/api/collection'); |
225
|
|
|
$this->assertEquals(200, $response->getStatusCode()); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
public function testSettingManualAccessTokenWithInvalidValue() |
229
|
|
|
{ |
230
|
|
|
$client = $this->createClient([], [], 0); |
|
|
|
|
231
|
|
|
|
232
|
|
|
$this->setExpectedException('\\InvalidArgumentException', 'Invalid access token'); |
233
|
|
|
$middleware = new OAuthMiddleware($client); |
234
|
|
|
$middleware->setAccessToken([]); |
|
|
|
|
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
public function testSettingManualRefreshTokenWhenNoAccessToken() |
238
|
|
|
{ |
239
|
|
|
$client = $this->createClient([], [], 0); |
|
|
|
|
240
|
|
|
|
241
|
|
|
$this->setExpectedException('\\InvalidArgumentException', 'Unable to update the refresh token. You have never set first the access token.'); |
242
|
|
|
$middleware = new OAuthMiddleware($client); |
243
|
|
|
$middleware->setRefreshToken('refreshToken'); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function testSettingManualRefreshTokenWithRefreshTokenGrantType() |
247
|
|
|
{ |
248
|
|
|
$credentials = [ |
249
|
|
|
'client_id' => 'test', |
250
|
|
|
'client_secret' => 'testSecret', |
251
|
|
|
]; |
252
|
|
|
$client = $this->createClient([], [], 0); |
|
|
|
|
253
|
|
|
$accessTokenGrantType = new ClientCredentials($client, $credentials); |
254
|
|
|
$refreshTokenGrantType = new RefreshToken($client, $credentials); |
255
|
|
|
|
256
|
|
|
$middleware = new OAuthMiddleware($client, $accessTokenGrantType, $refreshTokenGrantType); |
257
|
|
|
$token = new AccessToken('token', 'client_credentials', ['refresh_token' => 'refreshTokenOld']); |
258
|
|
|
$middleware->setAccessToken($token); |
259
|
|
|
|
260
|
|
|
$this->assertEquals('refreshTokenOld', $middleware->getRefreshToken()->getToken()); |
261
|
|
|
$this->assertEquals('refreshTokenOld', $refreshTokenGrantType->getConfigByName(RefreshToken::CONFIG_REFRESH_TOKEN)); |
262
|
|
|
|
263
|
|
|
$middleware->setRefreshToken('refreshToken'); |
264
|
|
|
$this->assertEquals('refresh_token', $middleware->getRefreshToken()->getType()); |
265
|
|
|
$this->assertEquals('refreshToken', $middleware->getRefreshToken()->getToken()); |
266
|
|
|
$this->assertEquals('refreshToken', $refreshTokenGrantType->getConfigByName(RefreshToken::CONFIG_REFRESH_TOKEN)); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
public function testSettingManualRefreshToken() |
270
|
|
|
{ |
271
|
|
|
$client = $this->createClient([], [], 0); |
|
|
|
|
272
|
|
|
|
273
|
|
|
$middleware = new OAuthMiddleware($client); |
274
|
|
|
$token = new AccessToken('token', 'client_credentials', ['refresh_token' => 'refreshTokenOld']); |
275
|
|
|
$middleware->setAccessToken($token); |
276
|
|
|
|
277
|
|
|
$this->assertEquals('refreshTokenOld', $middleware->getRefreshToken()->getToken()); |
278
|
|
|
|
279
|
|
|
$middleware->setRefreshToken('refreshToken'); |
280
|
|
|
$this->assertEquals('refresh_token', $middleware->getRefreshToken()->getType()); |
281
|
|
|
$this->assertEquals('refreshToken', $middleware->getRefreshToken()->getToken()); |
282
|
|
|
} |
283
|
|
|
} |
284
|
|
|
|
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.