View source
<?php
namespace Auth0\Tests;
use Auth0\SDK\Auth0;
use Auth0\SDK\Exception\ApiException;
use Auth0\SDK\Exception\CoreException;
use Auth0\Tests\Traits\ErrorHelpers;
use Firebase\JWT\JWT;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Response;
class Auth0Test extends \PHPUnit_Framework_TestCase {
use ErrorHelpers;
public static $baseConfig = [
'domain' => '__test_domain__',
'client_id' => '__test_client_id__',
'client_secret' => '__test_client_secret__',
'redirect_uri' => '__test_redirect_uri__',
'store' => false,
'state_handler' => false,
];
protected static $headers = [
'content-type' => 'json',
];
public function tearDown() {
parent::tearDown();
$_GET = [];
}
public function testThatExchangeReturnsFalseIfNoCodePresent() {
$auth0 = new Auth0(self::$baseConfig);
$this
->assertFalse($auth0
->exchange());
}
public function testThatExchangeSucceedsWithIdToken() {
$id_token_payload = [
'sub' => '123',
];
$id_token = JWT::encode($id_token_payload, '__test_client_secret__');
$response_body = '{"access_token":"1.2.3","id_token":"' . $id_token . '","refresh_token":"4.5.6"}';
$mock = new MockHandler([
new Response(200, self::$headers, $response_body),
new Response(200, self::$headers, json_encode($id_token_payload)),
]);
$add_config = [
'guzzle_options' => [
'handler' => HandlerStack::create($mock),
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
$this
->assertEquals($id_token_payload, $auth0
->getUser());
$this
->assertEquals($id_token, $auth0
->getIdToken());
$this
->assertEquals('1.2.3', $auth0
->getAccessToken());
$this
->assertEquals('4.5.6', $auth0
->getRefreshToken());
}
public function testThatExchangeSucceedsWithNoIdToken() {
$mock = new MockHandler([
new Response(200, self::$headers, '{"access_token":"1.2.3","refresh_token":"4.5.6"}'),
new Response(200, self::$headers, '{"sub":"123"}'),
]);
$add_config = [
'scope' => 'offline_access read:messages',
'audience' => 'https://api.identifier',
'guzzle_options' => [
'handler' => HandlerStack::create($mock),
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
$this
->assertEquals([
'sub' => '123',
], $auth0
->getUser());
$this
->assertEquals('1.2.3', $auth0
->getAccessToken());
$this
->assertEquals('4.5.6', $auth0
->getRefreshToken());
}
public function testThatExchangeSkipsUserinfo() {
$id_token_payload = [
'sub' => 'correct_sub',
];
$id_token = JWT::encode($id_token_payload, '__test_client_secret__');
$mock = new MockHandler([
new Response(200, self::$headers, '{"access_token":"1.2.3","id_token":"' . $id_token . '"}'),
]);
$add_config = [
'scope' => 'openid',
'skip_userinfo' => true,
'guzzle_options' => [
'handler' => HandlerStack::create($mock),
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
$this
->assertEquals([
'sub' => 'correct_sub',
], $auth0
->getUser());
$this
->assertEquals($id_token, $auth0
->getIdToken());
$this
->assertEquals('1.2.3', $auth0
->getAccessToken());
}
public function testThatRenewTokensFailsIfThereIsNoAccessToken() {
$auth0 = new Auth0(self::$baseConfig);
try {
$caught_exception = false;
$auth0
->renewTokens();
} catch (CoreException $e) {
$caught_exception = $this
->errorHasString($e, "Can't renew the access token if there isn't one valid");
}
$this
->assertTrue($caught_exception);
}
public function testThatRenewTokensFailsIfThereIsNoRefreshToken() {
$mock = new MockHandler([
new Response(200, self::$headers, '{"access_token":"1.2.3"}'),
]);
$add_config = [
'skip_userinfo' => true,
'persist_access_token' => true,
'guzzle_options' => [
'handler' => HandlerStack::create($mock),
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
try {
$caught_exception = false;
$auth0
->renewTokens();
} catch (CoreException $e) {
$caught_exception = $this
->errorHasString($e, "Can't renew the access token if there isn't a refresh token available");
}
$this
->assertTrue($caught_exception);
}
public function testThatRenewTokensFailsIfNoAccessOrIdTokenReturned() {
$mock = new MockHandler([
new Response(200, self::$headers, '{"access_token":"1.2.3","refresh_token":"2.3.4"}'),
new Response(200, self::$headers, '{"access_token":"1.2.3"}'),
new Response(200, self::$headers, '{"id_token":"1.2.3"}'),
]);
$add_config = [
'skip_userinfo' => true,
'persist_access_token' => true,
'guzzle_options' => [
'handler' => HandlerStack::create($mock),
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
try {
$caught_exception = false;
$auth0
->renewTokens();
} catch (ApiException $e) {
$caught_exception = $this
->errorHasString($e, 'Token did not refresh correctly. Access or ID token not provided');
}
$this
->assertTrue($caught_exception);
try {
$caught_exception = false;
$auth0
->renewTokens();
} catch (ApiException $e) {
$caught_exception = $this
->errorHasString($e, 'Token did not refresh correctly. Access or ID token not provided');
}
$this
->assertTrue($caught_exception);
}
public function testThatRenewTokensSucceeds() {
$id_token = JWT::encode([
'sub' => uniqid(),
], '__test_client_secret__');
$request_history = [];
$mock = new MockHandler([
new Response(200, self::$headers, '{"access_token":"1.2.3","refresh_token":"2.3.4"}'),
new Response(200, self::$headers, '{"access_token":"__test_access_token__","id_token":"' . $id_token . '"}'),
]);
$handler = HandlerStack::create($mock);
$handler
->push(Middleware::history($request_history));
$add_config = [
'skip_userinfo' => true,
'persist_access_token' => true,
'guzzle_options' => [
'handler' => $handler,
],
];
$auth0 = new Auth0(self::$baseConfig + $add_config);
$_GET['code'] = uniqid();
$this
->assertTrue($auth0
->exchange());
$auth0
->renewTokens([
'scope' => 'openid',
]);
$this
->assertEquals('__test_access_token__', $auth0
->getAccessToken());
$this
->assertEquals($id_token, $auth0
->getIdToken());
$renew_request = $request_history[1]['request'];
$renew_body = json_decode($renew_request
->getBody(), true);
$this
->assertEquals('openid', $renew_body['scope']);
$this
->assertEquals('__test_client_secret__', $renew_body['client_secret']);
$this
->assertEquals('__test_client_id__', $renew_body['client_id']);
$this
->assertEquals('2.3.4', $renew_body['refresh_token']);
$this
->assertEquals('https://__test_domain__/oauth/token', (string) $renew_request
->getUri());
}
public function testThatGetLoginUrlUsesDefaultValues() {
$auth0 = new Auth0(self::$baseConfig);
$parsed_url = parse_url($auth0
->getLoginUrl());
$this
->assertEquals('https', $parsed_url['scheme']);
$this
->assertEquals('__test_domain__', $parsed_url['host']);
$this
->assertEquals('/authorize', $parsed_url['path']);
$url_query = explode('&', $parsed_url['query']);
$this
->assertContains('scope=openid%20profile%20email', $url_query);
$this
->assertContains('response_type=code', $url_query);
$this
->assertContains('redirect_uri=__test_redirect_uri__', $url_query);
$this
->assertContains('client_id=__test_client_id__', $url_query);
}
public function testThatGetLoginUrlAddsValues() {
$auth0 = new Auth0(self::$baseConfig);
$custom_params = [
'connection' => '__test_connection__',
'prompt' => 'none',
'audience' => '__test_audience__',
'state' => '__test_state__',
];
$auth_url = $auth0
->getLoginUrl($custom_params);
$parsed_url_query = parse_url($auth_url, PHP_URL_QUERY);
$url_query = explode('&', $parsed_url_query);
$this
->assertContains('redirect_uri=__test_redirect_uri__', $url_query);
$this
->assertContains('client_id=__test_client_id__', $url_query);
$this
->assertContains('connection=__test_connection__', $url_query);
$this
->assertContains('prompt=none', $url_query);
$this
->assertContains('audience=__test_audience__', $url_query);
$this
->assertContains('state=__test_state__', $url_query);
}
public function testThatGetLoginUrlOverridesDefaultValues() {
$auth0 = new Auth0(self::$baseConfig);
$override_params = [
'scope' => 'openid profile email',
'response_type' => 'id_token',
'response_mode' => 'form_post',
];
$auth_url = $auth0
->getLoginUrl($override_params);
$parsed_url_query = parse_url($auth_url, PHP_URL_QUERY);
$url_query = explode('&', $parsed_url_query);
$this
->assertContains('scope=openid%20profile%20email', $url_query);
$this
->assertContains('response_type=id_token', $url_query);
$this
->assertContains('response_mode=form_post', $url_query);
$this
->assertContains('redirect_uri=__test_redirect_uri__', $url_query);
$this
->assertContains('client_id=__test_client_id__', $url_query);
}
public function testThatGetLoginUrlGeneratesState() {
$custom_config = self::$baseConfig;
unset($custom_config['state_handler']);
$auth0 = new Auth0($custom_config);
$auth_url = @$auth0
->getLoginUrl();
$parsed_url_query = parse_url($auth_url, PHP_URL_QUERY);
$url_query = explode('&', $parsed_url_query);
$this
->assertContains('state=' . $_SESSION['auth0__webauth_state'], $url_query);
}
}