PluginProbe
WP-Stateless – Google Cloud Storage / 2.1.4
WP-Stateless – Google Cloud Storage v2.1.4
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / lib / Google / vendor / google / auth / tests / OAuth2Test.php

OAuth2Test.php in WP-Stateless – Google Cloud Storage 2.1.4, at lib/Google/vendor/google/auth/tests/OAuth2Test.php

832 lines 24.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Copyright 2010 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 namespace Google\Auth\Tests;
19
20 use Google\Auth\HttpHandler\Guzzle6HttpHandler;
21 use Google\Auth\OAuth2;
22 use GuzzleHttp\Client;
23 use GuzzleHttp\Psr7;
24 use GuzzleHttp\Psr7\Response;
25
26 class OAuth2AuthorizationUriTest extends \PHPUnit_Framework_TestCase
27 {
28
29 private $minimal = [
30 'authorizationUri' => 'https://accounts.test.org/insecure/url',
31 'redirectUri' => 'https://accounts.test.org/redirect/url',
32 'clientId' => 'aClientID'
33 ];
34
35 /**
36 * @expectedException InvalidArgumentException
37 */
38 public function testIsNullIfAuthorizationUriIsNull()
39 {
40 $o = new OAuth2([]);
41 $this->assertNull($o->buildFullAuthorizationUri());
42 }
43
44 /**
45 * @expectedException InvalidArgumentException
46 */
47 public function testRequiresTheClientId()
48 {
49 $o = new OAuth2([
50 'authorizationUri' => 'https://accounts.test.org/auth/url',
51 'redirectUri' => 'https://accounts.test.org/redirect/url'
52 ]);
53 $o->buildFullAuthorizationUri();
54 }
55
56 /**
57 * @expectedException InvalidArgumentException
58 */
59 public function testRequiresTheRedirectUri()
60 {
61 $o = new OAuth2([
62 'authorizationUri' => 'https://accounts.test.org/auth/url',
63 'clientId' => 'aClientID'
64 ]);
65 $o->buildFullAuthorizationUri();
66 }
67
68 /**
69 * @expectedException InvalidArgumentException
70 */
71 public function testCannotHavePromptAndApprovalPrompt()
72 {
73 $o = new OAuth2([
74 'authorizationUri' => 'https://accounts.test.org/auth/url',
75 'clientId' => 'aClientID'
76 ]);
77 $o->buildFullAuthorizationUri([
78 'approval_prompt' => 'an approval prompt',
79 'prompt' => 'a prompt',
80 ]);
81 }
82
83 /**
84 * @expectedException InvalidArgumentException
85 */
86 public function testCannotHaveInsecureAuthorizationUri()
87 {
88 $o = new OAuth2([
89 'authorizationUri' => 'http://accounts.test.org/insecure/url',
90 'redirectUri' => 'https://accounts.test.org/redirect/url',
91 'clientId' => 'aClientID'
92 ]);
93 $o->buildFullAuthorizationUri();
94 }
95
96 /**
97 * @expectedException InvalidArgumentException
98 */
99 public function testCannotHaveRelativeRedirectUri()
100 {
101 $o = new OAuth2([
102 'authorizationUri' => 'http://accounts.test.org/insecure/url',
103 'redirectUri' => '/redirect/url',
104 'clientId' => 'aClientID'
105 ]);
106 $o->buildFullAuthorizationUri();
107 }
108
109 public function testHasDefaultXXXTypeParams()
110 {
111 $o = new OAuth2($this->minimal);
112 $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery());
113 $this->assertEquals('code', $q['response_type']);
114 $this->assertEquals('offline', $q['access_type']);
115 }
116
117 public function testCanBeUrlObject()
118 {
119 $config = array_merge($this->minimal, [
120 'authorizationUri' => Psr7\uri_for('https://another/uri')
121 ]);
122 $o = new OAuth2($config);
123 $this->assertEquals('/uri', $o->buildFullAuthorizationUri()->getPath());
124 }
125
126 public function testCanOverrideParams()
127 {
128 $overrides = [
129 'access_type' => 'o_access_type',
130 'client_id' => 'o_client_id',
131 'redirect_uri' => 'o_redirect_uri',
132 'response_type' => 'o_response_type',
133 'state' => 'o_state',
134 ];
135 $config = array_merge($this->minimal, ['state' => 'the_state']);
136 $o = new OAuth2($config);
137 $q = Psr7\parse_query($o->buildFullAuthorizationUri($overrides)->getQuery());
138 $this->assertEquals('o_access_type', $q['access_type']);
139 $this->assertEquals('o_client_id', $q['client_id']);
140 $this->assertEquals('o_redirect_uri', $q['redirect_uri']);
141 $this->assertEquals('o_response_type', $q['response_type']);
142 $this->assertEquals('o_state', $q['state']);
143 }
144
145 public function testIncludesTheScope()
146 {
147 $with_strings = array_merge($this->minimal, ['scope' => 'scope1 scope2']);
148 $o = new OAuth2($with_strings);
149 $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery());
150 $this->assertEquals('scope1 scope2', $q['scope']);
151
152 $with_array = array_merge($this->minimal, [
153 'scope' => ['scope1', 'scope2']
154 ]);
155 $o = new OAuth2($with_array);
156 $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery());
157 $this->assertEquals('scope1 scope2', $q['scope']);
158 }
159
160 public function testRedirectUriPostmessageIsAllowed()
161 {
162 $o = new OAuth2([
163 'authorizationUri' => 'https://accounts.test.org/insecure/url',
164 'redirectUri' => 'postmessage',
165 'clientId' => 'aClientID'
166 ]);
167 $this->assertEquals('postmessage', $o->getRedirectUri());
168 $url = $o->buildFullAuthorizationUri();
169 $parts = parse_url((string) $url);
170 parse_str($parts['query'], $query);
171 $this->assertArrayHasKey('redirect_uri', $query);
172 $this->assertEquals('postmessage', $query['redirect_uri']);
173 }
174 }
175
176 class OAuth2GrantTypeTest extends \PHPUnit_Framework_TestCase
177 {
178 private $minimal = [
179 'authorizationUri' => 'https://accounts.test.org/insecure/url',
180 'redirectUri' => 'https://accounts.test.org/redirect/url',
181 'clientId' => 'aClientID'
182 ];
183
184 public function testReturnsNullIfCannotBeInferred()
185 {
186 $o = new OAuth2($this->minimal);
187 $this->assertNull($o->getGrantType());
188 }
189
190 public function testInfersAuthorizationCode()
191 {
192 $o = new OAuth2($this->minimal);
193 $o->setCode('an auth code');
194 $this->assertEquals('authorization_code', $o->getGrantType());
195 }
196
197 public function testInfersRefreshToken()
198 {
199 $o = new OAuth2($this->minimal);
200 $o->setRefreshToken('a refresh token');
201 $this->assertEquals('refresh_token', $o->getGrantType());
202 }
203
204 public function testInfersPassword()
205 {
206 $o = new OAuth2($this->minimal);
207 $o->setPassword('a password');
208 $o->setUsername('a username');
209 $this->assertEquals('password', $o->getGrantType());
210 }
211
212 public function testInfersJwtBearer()
213 {
214 $o = new OAuth2($this->minimal);
215 $o->setIssuer('an issuer');
216 $o->setSigningKey('a key');
217 $this->assertEquals('urn:ietf:params:oauth:grant-type:jwt-bearer',
218 $o->getGrantType());
219 }
220
221 public function testSetsKnownTypes()
222 {
223 $o = new OAuth2($this->minimal);
224 foreach (OAuth2::$knownGrantTypes as $t) {
225 $o->setGrantType($t);
226 $this->assertEquals($t, $o->getGrantType());
227 }
228 }
229
230 public function testSetsUrlAsGrantType()
231 {
232 $o = new OAuth2($this->minimal);
233 $o->setGrantType('http://a/grant/url');
234 $this->assertEquals('http://a/grant/url', $o->getGrantType());
235 }
236 }
237
238 class OAuth2GetCacheKeyTest extends \PHPUnit_Framework_TestCase
239 {
240 private $minimal = [
241 'clientID' => 'aClientID'
242 ];
243
244 public function testIsNullWithNoScopes()
245 {
246 $o = new OAuth2($this->minimal);
247 $this->assertNull($o->getCacheKey());
248 }
249
250 public function testIsScopeIfSingleScope()
251 {
252 $o = new OAuth2($this->minimal);
253 $o->setScope('test/scope/1');
254 $this->assertEquals('test/scope/1', $o->getCacheKey());
255 }
256
257 public function testIsAllScopesWhenScopeIsArray()
258 {
259 $o = new OAuth2($this->minimal);
260 $o->setScope(['test/scope/1', 'test/scope/2']);
261 $this->assertEquals('test/scope/1:test/scope/2', $o->getCacheKey());
262 }
263 }
264
265 class OAuth2TimingTest extends \PHPUnit_Framework_TestCase
266 {
267 private $minimal = [
268 'authorizationUri' => 'https://accounts.test.org/insecure/url',
269 'redirectUri' => 'https://accounts.test.org/redirect/url',
270 'clientId' => 'aClientID'
271 ];
272
273 public function testIssuedAtDefaultsToNull()
274 {
275 $o = new OAuth2($this->minimal);
276 $this->assertNull($o->getIssuedAt());
277 }
278
279 public function testExpiresAtDefaultsToNull()
280 {
281 $o = new OAuth2($this->minimal);
282 $this->assertNull($o->getExpiresAt());
283 }
284
285 public function testExpiresInDefaultsToNull()
286 {
287 $o = new OAuth2($this->minimal);
288 $this->assertNull($o->getExpiresIn());
289 }
290
291 public function testSettingExpiresInSetsIssuedAt()
292 {
293 $o = new OAuth2($this->minimal);
294 $this->assertNull($o->getIssuedAt());
295 $aShortWhile = 5;
296 $o->setExpiresIn($aShortWhile);
297 $this->assertEquals($aShortWhile, $o->getExpiresIn());
298 $this->assertNotNull($o->getIssuedAt());
299 }
300
301 public function testSettingExpiresInSetsExpireAt()
302 {
303 $o = new OAuth2($this->minimal);
304 $this->assertNull($o->getExpiresAt());
305 $aShortWhile = 5;
306 $o->setExpiresIn($aShortWhile);
307 $this->assertNotNull($o->getExpiresAt());
308 $this->assertEquals($aShortWhile, $o->getExpiresAt() - $o->getIssuedAt());
309 }
310
311 public function testIsNotExpiredByDefault()
312 {
313 $o = new OAuth2($this->minimal);
314 $this->assertFalse($o->isExpired());
315 }
316
317 public function testIsNotExpiredIfExpiresAtIsOld()
318 {
319 $o = new OAuth2($this->minimal);
320 $o->setExpiresAt(time() - 2);
321 $this->assertTrue($o->isExpired());
322 }
323 }
324
325 class OAuth2GeneralTest extends \PHPUnit_Framework_TestCase
326 {
327 private $minimal = [
328 'authorizationUri' => 'https://accounts.test.org/insecure/url',
329 'redirectUri' => 'https://accounts.test.org/redirect/url',
330 'clientId' => 'aClientID'
331 ];
332
333 /**
334 * @expectedException InvalidArgumentException
335 */
336 public function testFailsOnUnknownSigningAlgorithm()
337 {
338 $o = new OAuth2($this->minimal);
339 $o->setSigningAlgorithm('this is definitely not an algorithm name');
340 }
341
342 public function testAllowsKnownSigningAlgorithms()
343 {
344 $o = new OAuth2($this->minimal);
345 foreach (OAuth2::$knownSigningAlgorithms as $a) {
346 $o->setSigningAlgorithm($a);
347 $this->assertEquals($a, $o->getSigningAlgorithm());
348 }
349 }
350
351 /**
352 * @expectedException InvalidArgumentException
353 */
354 public function testFailsOnRelativeRedirectUri()
355 {
356 $o = new OAuth2($this->minimal);
357 $o->setRedirectUri('/relative/url');
358 }
359
360
361 public function testAllowsUrnRedirectUri()
362 {
363 $urn = 'urn:ietf:wg:oauth:2.0:oob';
364 $o = new OAuth2($this->minimal);
365 $o->setRedirectUri($urn);
366 $this->assertEquals($urn, $o->getRedirectUri());
367 }
368 }
369
370 class OAuth2JwtTest extends \PHPUnit_Framework_TestCase
371 {
372 private $signingMinimal = [
373 'signingKey' => 'example_key',
374 'signingAlgorithm' => 'HS256',
375 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
376 'issuer' => 'app@example.com',
377 'audience' => 'accounts.google.com',
378 'clientId' => 'aClientID'
379 ];
380
381 /**
382 * @expectedException DomainException
383 */
384 public function testFailsWithMissingAudience()
385 {
386 $testConfig = $this->signingMinimal;
387 unset($testConfig['audience']);
388 $o = new OAuth2($testConfig);
389 $o->toJwt();
390 }
391
392 /**
393 * @expectedException DomainException
394 */
395 public function testFailsWithMissingIssuer()
396 {
397 $testConfig = $this->signingMinimal;
398 unset($testConfig['issuer']);
399 $o = new OAuth2($testConfig);
400 $o->toJwt();
401 }
402
403 /**
404 */
405 public function testCanHaveNoScope()
406 {
407 $testConfig = $this->signingMinimal;
408 unset($testConfig['scope']);
409 $o = new OAuth2($testConfig);
410 $o->toJwt();
411 }
412
413 /**
414 * @expectedException DomainException
415 */
416 public function testFailsWithMissingSigningKey()
417 {
418 $testConfig = $this->signingMinimal;
419 unset($testConfig['signingKey']);
420 $o = new OAuth2($testConfig);
421 $o->toJwt();
422 }
423
424 /**
425 * @expectedException DomainException
426 */
427 public function testFailsWithMissingSigningAlgorithm()
428 {
429 $testConfig = $this->signingMinimal;
430 unset($testConfig['signingAlgorithm']);
431 $o = new OAuth2($testConfig);
432 $o->toJwt();
433 }
434
435 public function testCanHS256EncodeAValidPayload()
436 {
437 $testConfig = $this->signingMinimal;
438 $o = new OAuth2($testConfig);
439 $payload = $o->toJwt();
440 $roundTrip = $this->jwtDecode($payload, $testConfig['signingKey'], array('HS256')) ;
441 $this->assertEquals($roundTrip->iss, $testConfig['issuer']);
442 $this->assertEquals($roundTrip->aud, $testConfig['audience']);
443 $this->assertEquals($roundTrip->scope, $testConfig['scope']);
444 }
445
446 public function testCanRS256EncodeAValidPayload()
447 {
448 $publicKey = file_get_contents(__DIR__ . '/fixtures' . '/public.pem');
449 $privateKey = file_get_contents(__DIR__ . '/fixtures' . '/private.pem');
450 $testConfig = $this->signingMinimal;
451 $o = new OAuth2($testConfig);
452 $o->setSigningAlgorithm('RS256');
453 $o->setSigningKey($privateKey);
454 $payload = $o->toJwt();
455 $roundTrip = $this->jwtDecode($payload, $publicKey, array('RS256')) ;
456 $this->assertEquals($roundTrip->iss, $testConfig['issuer']);
457 $this->assertEquals($roundTrip->aud, $testConfig['audience']);
458 $this->assertEquals($roundTrip->scope, $testConfig['scope']);
459 }
460
461 private function jwtDecode()
462 {
463 $args = func_get_args();
464 $class = 'JWT';
465 if (class_exists('Firebase\JWT\JWT')) {
466 $class = 'Firebase\JWT\JWT';
467 }
468
469 return call_user_func_array("$class::decode", $args);
470 }
471 }
472
473 class OAuth2GenerateAccessTokenRequestTest extends \PHPUnit_Framework_TestCase
474 {
475 private $tokenRequestMinimal = [
476 'tokenCredentialUri' => 'https://tokens_r_us/test',
477 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
478 'issuer' => 'app@example.com',
479 'audience' => 'accounts.google.com',
480 'clientId' => 'aClientID'
481 ];
482
483 /**
484 * @expectedException DomainException
485 */
486 public function testFailsIfNoTokenCredentialUri()
487 {
488 $testConfig = $this->tokenRequestMinimal;
489 unset($testConfig['tokenCredentialUri']);
490 $o = new OAuth2($testConfig);
491 $o->generateCredentialsRequest();
492 }
493
494 /**
495 * @expectedException DomainException
496 */
497 public function testFailsIfAuthorizationCodeIsMissing()
498 {
499 $testConfig = $this->tokenRequestMinimal;
500 $testConfig['redirectUri'] = 'https://has/redirect/uri';
501 $o = new OAuth2($testConfig);
502 $o->generateCredentialsRequest();
503 }
504
505 public function testGeneratesAuthorizationCodeRequests()
506 {
507 $testConfig = $this->tokenRequestMinimal;
508 $testConfig['redirectUri'] = 'https://has/redirect/uri';
509 $o = new OAuth2($testConfig);
510 $o->setCode('an_auth_code');
511
512 // Generate the request and confirm that it's correct.
513 $req = $o->generateCredentialsRequest();
514 $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req);
515 $this->assertEquals('POST', $req->getMethod());
516 $fields = Psr7\parse_query((string) $req->getBody());
517 $this->assertEquals('authorization_code', $fields['grant_type']);
518 $this->assertEquals('an_auth_code', $fields['code']);
519 }
520
521 public function testGeneratesPasswordRequests()
522 {
523 $testConfig = $this->tokenRequestMinimal;
524 $o = new OAuth2($testConfig);
525 $o->setUsername('a_username');
526 $o->setPassword('a_password');
527
528 // Generate the request and confirm that it's correct.
529 $req = $o->generateCredentialsRequest();
530 $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req);
531 $this->assertEquals('POST', $req->getMethod());
532 $fields = Psr7\parse_query((string) $req->getBody());
533 $this->assertEquals('password', $fields['grant_type']);
534 $this->assertEquals('a_password', $fields['password']);
535 $this->assertEquals('a_username', $fields['username']);
536 }
537
538 public function testGeneratesRefreshTokenRequests()
539 {
540 $testConfig = $this->tokenRequestMinimal;
541 $o = new OAuth2($testConfig);
542 $o->setRefreshToken('a_refresh_token');
543
544 // Generate the request and confirm that it's correct.
545 $req = $o->generateCredentialsRequest();
546 $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req);
547 $this->assertEquals('POST', $req->getMethod());
548 $fields = Psr7\parse_query((string) $req->getBody());
549 $this->assertEquals('refresh_token', $fields['grant_type']);
550 $this->assertEquals('a_refresh_token', $fields['refresh_token']);
551 }
552
553 public function testClientSecretAddedIfSetForAuthorizationCodeRequests()
554 {
555 $testConfig = $this->tokenRequestMinimal;
556 $testConfig['clientSecret'] = 'a_client_secret';
557 $testConfig['redirectUri'] = 'https://has/redirect/uri';
558 $o = new OAuth2($testConfig);
559 $o->setCode('an_auth_code');
560 $request = $o->generateCredentialsRequest();
561 $fields = Psr7\parse_query((string) $request->getBody());
562 $this->assertEquals('a_client_secret', $fields['client_secret']);
563 }
564
565 public function testClientSecretAddedIfSetForRefreshTokenRequests()
566 {
567 $testConfig = $this->tokenRequestMinimal;
568 $testConfig['clientSecret'] = 'a_client_secret';
569 $o = new OAuth2($testConfig);
570 $o->setRefreshToken('a_refresh_token');
571 $request = $o->generateCredentialsRequest();
572 $fields = Psr7\parse_query((string) $request->getBody());
573 $this->assertEquals('a_client_secret', $fields['client_secret']);
574 }
575
576 public function testClientSecretAddedIfSetForPasswordRequests()
577 {
578 $testConfig = $this->tokenRequestMinimal;
579 $testConfig['clientSecret'] = 'a_client_secret';
580 $o = new OAuth2($testConfig);
581 $o->setUsername('a_username');
582 $o->setPassword('a_password');
583 $request = $o->generateCredentialsRequest();
584 $fields = Psr7\parse_query((string) $request->getBody());
585 $this->assertEquals('a_client_secret', $fields['client_secret']);
586 }
587
588 public function testGeneratesAssertionRequests()
589 {
590 $testConfig = $this->tokenRequestMinimal;
591 $o = new OAuth2($testConfig);
592 $o->setSigningKey('a_key');
593 $o->setSigningAlgorithm('HS256');
594
595 // Generate the request and confirm that it's correct.
596 $req = $o->generateCredentialsRequest();
597 $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req);
598 $this->assertEquals('POST', $req->getMethod());
599 $fields = Psr7\parse_query((string) $req->getBody());
600 $this->assertEquals(OAuth2::JWT_URN, $fields['grant_type']);
601 $this->assertTrue(array_key_exists('assertion', $fields));
602 }
603
604 public function testGeneratesExtendedRequests()
605 {
606 $testConfig = $this->tokenRequestMinimal;
607 $o = new OAuth2($testConfig);
608 $o->setGrantType('urn:my_test_grant_type');
609 $o->setExtensionParams(['my_param' => 'my_value']);
610
611 // Generate the request and confirm that it's correct.
612 $req = $o->generateCredentialsRequest();
613 $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req);
614 $this->assertEquals('POST', $req->getMethod());
615 $fields = Psr7\parse_query((string) $req->getBody());
616 $this->assertEquals('my_value', $fields['my_param']);
617 $this->assertEquals('urn:my_test_grant_type', $fields['grant_type']);
618 }
619 }
620
621 class OAuth2FetchAuthTokenTest extends \PHPUnit_Framework_TestCase
622 {
623 private $fetchAuthTokenMinimal = [
624 'tokenCredentialUri' => 'https://tokens_r_us/test',
625 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
626 'signingKey' => 'example_key',
627 'signingAlgorithm' => 'HS256',
628 'issuer' => 'app@example.com',
629 'audience' => 'accounts.google.com',
630 'clientId' => 'aClientID'
631 ];
632
633 /**
634 * @expectedException GuzzleHttp\Exception\ClientException
635 */
636 public function testFailsOn400()
637 {
638 $testConfig = $this->fetchAuthTokenMinimal;
639 $httpHandler = getHandler([
640 buildResponse(400)
641 ]);
642 $o = new OAuth2($testConfig);
643 $o->fetchAuthToken($httpHandler);
644 }
645
646 /**
647 * @expectedException GuzzleHttp\Exception\ServerException
648 */
649 public function testFailsOn500()
650 {
651 $testConfig = $this->fetchAuthTokenMinimal;
652 $httpHandler = getHandler([
653 buildResponse(500)
654 ]);
655 $o = new OAuth2($testConfig);
656 $o->fetchAuthToken($httpHandler);
657 }
658
659 /**
660 * @expectedException Exception
661 * @expectedExceptionMessage Invalid JSON response
662 */
663 public function testFailsOnNoContentTypeIfResponseIsNotJSON()
664 {
665 $testConfig = $this->fetchAuthTokenMinimal;
666 $notJson = '{"foo": , this is cannot be passed as json" "bar"}';
667 $httpHandler = getHandler([
668 buildResponse(200, [], Psr7\stream_for($notJson))
669 ]);
670 $o = new OAuth2($testConfig);
671 $o->fetchAuthToken($httpHandler);
672 }
673
674 public function testFetchesJsonResponseOnNoContentTypeOK()
675 {
676 $testConfig = $this->fetchAuthTokenMinimal;
677 $json = '{"foo": "bar"}';
678 $httpHandler = getHandler([
679 buildResponse(200, [], Psr7\stream_for($json))
680 ]);
681 $o = new OAuth2($testConfig);
682 $tokens = $o->fetchAuthToken($httpHandler);
683 $this->assertEquals($tokens['foo'], 'bar');
684 }
685
686 public function testFetchesFromFormEncodedResponseOK()
687 {
688 $testConfig = $this->fetchAuthTokenMinimal;
689 $json = 'foo=bar&spice=nice';
690 $httpHandler = getHandler([
691 buildResponse(
692 200,
693 ['Content-Type' => 'application/x-www-form-urlencoded'],
694 Psr7\stream_for($json)
695 )
696 ]);
697 $o = new OAuth2($testConfig);
698 $tokens = $o->fetchAuthToken($httpHandler);
699 $this->assertEquals($tokens['foo'], 'bar');
700 $this->assertEquals($tokens['spice'], 'nice');
701 }
702
703 public function testUpdatesTokenFieldsOnFetch()
704 {
705 $testConfig = $this->fetchAuthTokenMinimal;
706 $wanted_updates = [
707 'expires_at' => '1',
708 'expires_in' => '57',
709 'issued_at' => '2',
710 'access_token' => 'an_access_token',
711 'id_token' => 'an_id_token',
712 'refresh_token' => 'a_refresh_token',
713 ];
714 $json = json_encode($wanted_updates);
715 $httpHandler = getHandler([
716 buildResponse(200, [], Psr7\stream_for($json))
717 ]);
718 $o = new OAuth2($testConfig);
719 $this->assertNull($o->getExpiresAt());
720 $this->assertNull($o->getExpiresIn());
721 $this->assertNull($o->getIssuedAt());
722 $this->assertNull($o->getAccessToken());
723 $this->assertNull($o->getIdToken());
724 $this->assertNull($o->getRefreshToken());
725 $tokens = $o->fetchAuthToken($httpHandler);
726 $this->assertEquals(1, $o->getExpiresAt());
727 $this->assertEquals(57, $o->getExpiresIn());
728 $this->assertEquals(2, $o->getIssuedAt());
729 $this->assertEquals('an_access_token', $o->getAccessToken());
730 $this->assertEquals('an_id_token', $o->getIdToken());
731 $this->assertEquals('a_refresh_token', $o->getRefreshToken());
732 }
733 }
734
735 class OAuth2VerifyIdTokenTest extends \PHPUnit_Framework_TestCase
736 {
737 private $publicKey;
738 private $privateKey;
739 private $verifyIdTokenMinimal = [
740 'scope' => 'https://www.googleapis.com/auth/userinfo.profile',
741 'audience' => 'myaccount.on.host.issuer.com',
742 'issuer' => 'an.issuer.com',
743 'clientId' => 'myaccount.on.host.issuer.com'
744 ];
745
746 public function setUp()
747 {
748 $this->publicKey =
749 file_get_contents(__DIR__ . '/fixtures' . '/public.pem');
750 $this->privateKey =
751 file_get_contents(__DIR__ . '/fixtures' . '/private.pem');
752 }
753
754 /**
755 * @expectedException UnexpectedValueException
756 */
757 public function testFailsIfIdTokenIsInvalid()
758 {
759 $testConfig = $this->verifyIdTokenMinimal;
760 $not_a_jwt = 'not a jot';
761 $o = new OAuth2($testConfig);
762 $o->setIdToken($not_a_jwt);
763 $o->verifyIdToken($this->publicKey);
764 }
765
766 /**
767 * @expectedException DomainException
768 */
769 public function testFailsIfAudienceIsMissing()
770 {
771 $testConfig = $this->verifyIdTokenMinimal;
772 $now = time();
773 $origIdToken = [
774 'issuer' => $testConfig['issuer'],
775 'exp' => $now + 65, // arbitrary
776 'iat' => $now,
777 ];
778 $o = new OAuth2($testConfig);
779 $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, 'RS256');
780 $o->setIdToken($jwtIdToken);
781 $o->verifyIdToken($this->publicKey);
782 }
783
784 /**
785 * @expectedException DomainException
786 */
787 public function testFailsIfAudienceIsWrong()
788 {
789 $now = time();
790 $testConfig = $this->verifyIdTokenMinimal;
791 $origIdToken = [
792 'aud' => 'a different audience',
793 'iss' => $testConfig['issuer'],
794 'exp' => $now + 65, // arbitrary
795 'iat' => $now,
796 ];
797 $o = new OAuth2($testConfig);
798 $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, 'RS256');
799 $o->setIdToken($jwtIdToken);
800 $o->verifyIdToken($this->publicKey);
801 }
802
803 public function testShouldReturnAValidIdToken()
804 {
805 $testConfig = $this->verifyIdTokenMinimal;
806 $now = time();
807 $origIdToken = [
808 'aud' => $testConfig['audience'],
809 'iss' => $testConfig['issuer'],
810 'exp' => $now + 65, // arbitrary
811 'iat' => $now,
812 ];
813 $o = new OAuth2($testConfig);
814 $alg = 'RS256';
815 $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, $alg);
816 $o->setIdToken($jwtIdToken);
817 $roundTrip = $o->verifyIdToken($this->publicKey, array($alg));
818 $this->assertEquals($origIdToken['aud'], $roundTrip->aud);
819 }
820
821 private function jwtEncode()
822 {
823 $args = func_get_args();
824 $class = 'JWT';
825 if (class_exists('Firebase\JWT\JWT')) {
826 $class = 'Firebase\JWT\JWT';
827 }
828
829 return call_user_func_array("$class::encode", $args);
830 }
831 }
832