add composer's vendor directory

This commit is contained in:
Marcel Kapfer (mmk2410) 2016-05-07 12:59:40 +02:00
parent 01a3860d73
commit 60b094d5fa
745 changed files with 56017 additions and 1 deletions

View file

@ -0,0 +1,16 @@
<?php
namespace OAuth2;
class AutoloadTest extends \PHPUnit_Framework_TestCase
{
public function testClassesExist()
{
// autoloader is called in test/bootstrap.php
$this->assertTrue(class_exists('OAuth2\Server'));
$this->assertTrue(class_exists('OAuth2\Request'));
$this->assertTrue(class_exists('OAuth2\Response'));
$this->assertTrue(class_exists('OAuth2\GrantType\UserCredentials'));
$this->assertTrue(interface_exists('OAuth2\Storage\AccessTokenInterface'));
}
}

View file

@ -0,0 +1,476 @@
<?php
namespace OAuth2\Controller;
use OAuth2\Storage\Memory;
use OAuth2\Scope;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\GrantType\AuthorizationCode;
use OAuth2\Request;
use OAuth2\Response;
use OAuth2\Request\TestRequest;
class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
{
public function testNoClientIdResponse()
{
$server = $this->getTestServer();
$request = new Request();
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'No client id supplied');
}
public function testInvalidClientIdResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Fake Client ID', // invalid client id
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'The client id supplied is invalid');
}
public function testNoRedirectUriSuppliedOrStoredResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_uri');
$this->assertEquals($response->getParameter('error_description'), 'No redirect URI was supplied or stored');
}
public function testNoResponseTypeResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'invalid_request');
$this->assertEquals($query['error_description'], 'Invalid or missing response type');
}
public function testInvalidResponseTypeResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'invalid', // invalid response type
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'invalid_request');
$this->assertEquals($query['error_description'], 'Invalid or missing response type');
}
public function testRedirectUriFragmentResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com#fragment', // valid redirect URI
'response_type' => 'code', // invalid response type
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_uri');
$this->assertEquals($response->getParameter('error_description'), 'The redirect URI must not contain a fragment');
}
public function testEnforceState()
{
$server = $this->getTestServer(array('enforce_state' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'invalid_request');
$this->assertEquals($query['error_description'], 'The state parameter is required');
}
public function testDoNotEnforceState()
{
$server = $this->getTestServer(array('enforce_state' => false));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNotContains('error', $response->getHttpHeader('Location'));
}
public function testEnforceScope()
{
$server = $this->getTestServer();
$scopeStorage = new Memory(array('default_scope' => false, 'supported_scopes' => array('testscope')));
$server->setScopeUtil(new Scope($scopeStorage));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'invalid_client');
$this->assertEquals($query['error_description'], 'This application requires you specify a scope parameter');
$request->query['scope'] = 'testscope';
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNotContains('error', $response->getHttpHeader('Location'));
}
public function testInvalidRedirectUri()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID with Redirect Uri', // valid client id
'redirect_uri' => 'http://adobe.com', // invalid redirect URI
'response_type' => 'code',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
$this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
}
public function testNoRedirectUriWithMultipleRedirectUris()
{
$server = $this->getTestServer();
// create a request with no "redirect_uri" in querystring
$request = new Request(array(
'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
'response_type' => 'code',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_uri');
$this->assertEquals($response->getParameter('error_description'), 'A redirect URI must be supplied when multiple redirect URIs are registered');
}
public function testRedirectUriWithValidRedirectUri()
{
$server = $this->getTestServer();
// create a request with no "redirect_uri" in querystring
$request = new Request(array(
'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
'response_type' => 'code',
'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
}
public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
{
$server = $this->getTestServer(array('require_exact_redirect_uri' => true));
// create a request with no "redirect_uri" in querystring
$request = new Request(array(
'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
'response_type' => 'code',
'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
$this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
}
public function testRedirectUriWithDifferentQueryAndExactMatchNotRequired()
{
$server = $this->getTestServer(array('require_exact_redirect_uri' => false));
// create a request with no "redirect_uri" in querystring
$request = new Request(array(
'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
'response_type' => 'code',
'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
}
public function testMultipleRedirectUris()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
'redirect_uri' => 'http://brentertainment.com', // valid redirect URI
'response_type' => 'code',
'state' => 'xyz'
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
// call again with different (but still valid) redirect URI
$request->query['redirect_uri'] = 'http://morehazards.com';
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
}
/**
* @see http://tools.ietf.org/html/rfc6749#section-4.1.3
* @see https://github.com/bshaffer/oauth2-server-php/issues/163
*/
public function testNoRedirectUriSuppliedDoesNotRequireTokenRedirectUri()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID with Redirect Uri', // valid client id
'response_type' => 'code',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('state', $response->getHttpHeader('Location'));
$this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['query'], $query);
// call token endpoint with no redirect_uri supplied
$request = TestRequest::createPost(array(
'client_id' => 'Test Client ID with Redirect Uri', // valid client id
'client_secret' => 'TestSecret2',
'grant_type' => 'authorization_code',
'code' => $query['code'],
));
$server->handleTokenRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 200);
$this->assertNotNull($response->getParameter('access_token'));
}
public function testUserDeniesAccessResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'access_denied');
$this->assertEquals($query['error_description'], 'The user denied access to your application');
}
public function testCodeQueryParamIsSet()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
$this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
$this->assertArrayHasKey('query', $parts);
$this->assertFalse(isset($parts['fragment']));
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['query'], $query);
$this->assertNotNull($query);
$this->assertArrayHasKey('code', $query);
// ensure no id_token was saved, since the openid scope wasn't requested
$storage = $server->getStorage('authorization_code');
$code = $storage->getAuthorizationCode($query['code']);
$this->assertTrue(empty($code['id_token']));
// ensure no error was returned
$this->assertFalse(isset($query['error']));
$this->assertFalse(isset($query['error_description']));
}
public function testSuccessfulRequestReturnsStateParameter()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
'state' => 'test', // valid state string (just needs to be passed back to us)
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
parse_str($parts['query'], $query);
$this->assertArrayHasKey('state', $query);
$this->assertEquals($query['state'], 'test');
// ensure no error was returned
$this->assertFalse(isset($query['error']));
$this->assertFalse(isset($query['error_description']));
}
public function testSuccessfulRequestStripsExtraParameters()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'code',
'state' => 'test', // valid state string (just needs to be passed back to us)
'fake' => 'something', // extra query param
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$parts = parse_url($location);
$this->assertFalse(isset($parts['fake']));
$this->assertArrayHasKey('query', $parts);
parse_str($parts['query'], $query);
$this->assertFalse(isset($parmas['fake']));
$this->assertArrayHasKey('state', $query);
$this->assertEquals($query['state'], 'test');
}
public function testSuccessfulOpenidConnectRequest()
{
$server = $this->getTestServer(array(
'use_openid_connect' => true,
'issuer' => 'bojanz',
));
$request = new Request(array(
'client_id' => 'Test Client ID',
'redirect_uri' => 'http://adobe.com',
'response_type' => 'code',
'state' => 'xyz',
'scope' => 'openid',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
$this->assertFalse(isset($parts['fragment']));
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['query'], $query);
$this->assertNotNull($query);
$this->assertArrayHasKey('code', $query);
// ensure no error was returned
$this->assertFalse(isset($query['error']));
$this->assertFalse(isset($query['error_description']));
// confirm that the id_token has been created.
$storage = $server->getStorage('authorization_code');
$code = $storage->getAuthorizationCode($query['code']);
$this->assertTrue(!empty($code['id_token']));
}
public function testCreateController()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$controller = new AuthorizeController($storage);
}
private function getTestServer($config = array())
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
// Add the two types supported for authorization grant
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,175 @@
<?php
namespace OAuth2\Controller;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\GrantType\AuthorizationCode;
use OAuth2\Request;
use OAuth2\Response;
class ResourceControllerTest extends \PHPUnit_Framework_TestCase
{
public function testNoAccessToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
}
public function testMalformedHeader()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'tH1s i5 B0gU5';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Malformed auth header');
}
public function testMultipleTokensSubmitted()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->request['access_token'] = 'TEST';
$request->query['access_token'] = 'TEST';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Only one method may be used to authenticate at a time (Auth header, GET or POST)');
}
public function testInvalidRequestMethod()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->server['REQUEST_METHOD'] = 'GET';
$request->request['access_token'] = 'TEST';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'When putting the token in the body, the method must be POST or PUT');
}
public function testInvalidContentType()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->server['REQUEST_METHOD'] = 'POST';
$request->server['CONTENT_TYPE'] = 'application/json';
$request->request['access_token'] = 'TEST';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
}
public function testInvalidToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer TESTTOKEN';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
$this->assertEquals($response->getParameter('error'), 'invalid_token');
$this->assertEquals($response->getParameter('error_description'), 'The access token provided is invalid');
}
public function testExpiredToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-expired';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
$this->assertEquals($response->getParameter('error'), 'expired_token');
$this->assertEquals($response->getParameter('error_description'), 'The access token provided has expired');
}
public function testOutOfScopeToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
$scope = 'outofscope';
$allow = $server->verifyResourceRequest($request, $response = new Response(), $scope);
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 403);
$this->assertEquals($response->getParameter('error'), 'insufficient_scope');
$this->assertEquals($response->getParameter('error_description'), 'The request requires higher privileges than provided by the access token');
// verify the "scope" has been set in the "WWW-Authenticate" header
preg_match('/scope="(.*?)"/', $response->getHttpHeader('WWW-Authenticate'), $matches);
$this->assertEquals(2, count($matches));
$this->assertEquals($matches[1], 'outofscope');
}
public function testMalformedToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-malformed';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
$this->assertEquals($response->getParameter('error'), 'malformed_token');
$this->assertEquals($response->getParameter('error_description'), 'Malformed token (missing "expires")');
}
public function testValidToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertTrue($allow);
}
public function testValidTokenWithScopeParam()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
$request->query['scope'] = 'testscope';
$allow = $server->verifyResourceRequest($request, $response = new Response());
$this->assertTrue($allow);
}
public function testCreateController()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$tokenType = new \OAuth2\TokenType\Bearer();
$controller = new ResourceController($tokenType, $storage);
}
private function getTestServer($config = array())
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
// Add the two types supported for authorization grant
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,289 @@
<?php
namespace OAuth2\Controller;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\GrantType\AuthorizationCode;
use OAuth2\GrantType\ClientCredentials;
use OAuth2\GrantType\UserCredentials;
use OAuth2\Scope;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class TokenControllerTest extends \PHPUnit_Framework_TestCase
{
public function testNoGrantType()
{
// add the test parameters in memory
$server = $this->getTestServer();
$server->handleTokenRequest(TestRequest::createPost(), $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'The grant type was not specified in the request');
}
public function testInvalidGrantType()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'invalid_grant_type', // invalid grant type
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'unsupported_grant_type');
$this->assertEquals($response->getParameter('error_description'), 'Grant type "invalid_grant_type" not supported');
}
public function testNoClientId()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode',
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'Client credentials were not found in the headers or body');
}
public function testNoClientSecretWithConfidentialClient()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode',
'client_id' => 'Test Client ID', // valid client id
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
}
public function testNoClientSecretWithEmptySecret()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode-empty-secret',
'client_id' => 'Test Client ID Empty Secret', // valid client id
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 200);
}
public function testInvalidClientId()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode',
'client_id' => 'Fake Client ID', // invalid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
}
public function testInvalidClientSecret()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode',
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'Fake Client Secret', // invalid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
}
public function testValidTokenResponse()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode', // valid authorization code
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertTrue($response instanceof Response);
$this->assertEquals($response->getStatusCode(), 200);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$this->assertNotNull($response->getParameter('access_token'));
$this->assertNotNull($response->getParameter('expires_in'));
$this->assertNotNull($response->getParameter('token_type'));
}
public function testValidClientIdScope()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode',
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'scope' => 'clientscope1 clientscope2'
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 200);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$this->assertEquals('clientscope1 clientscope2', $response->getParameter('scope'));
}
public function testInvalidClientIdScope()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'code' => 'testcode-with-scope',
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'scope' => 'clientscope3'
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
}
public function testEnforceScope()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new ClientCredentials($storage));
$scope = new Scope(array(
'default_scope' => false,
'supported_scopes' => array('testscope')
));
$server->setScopeUtil($scope);
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$response = $server->handleTokenRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'This application requires you specify a scope parameter');
}
public function testCanReceiveAccessTokenUsingPasswordGrantTypeWithoutClientSecret()
{
// add the test parameters in memory
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new UserCredentials($storage));
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID For Password Grant', // valid client id
'username' => 'johndoe', // valid username
'password' => 'password', // valid password for username
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertTrue($response instanceof Response);
$this->assertEquals(200, $response->getStatusCode(), var_export($response, 1));
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$this->assertNotNull($response->getParameter('access_token'));
$this->assertNotNull($response->getParameter('expires_in'));
$this->assertNotNull($response->getParameter('token_type'));
}
public function testInvalidTokenTypeHintForRevoke()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'token_type_hint' => 'foo',
'token' => 'sometoken'
));
$server->handleRevokeRequest($request, $response = new Response());
$this->assertTrue($response instanceof Response);
$this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Token type hint must be either \'access_token\' or \'refresh_token\'');
}
public function testMissingTokenForRevoke()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'token_type_hint' => 'access_token'
));
$server->handleRevokeRequest($request, $response = new Response());
$this->assertTrue($response instanceof Response);
$this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing token parameter to revoke');
}
public function testInvalidRequestMethodForRevoke()
{
$server = $this->getTestServer();
$request = new TestRequest();
$request->setQuery(array(
'token_type_hint' => 'access_token'
));
$server->handleRevokeRequest($request, $response = new Response());
$this->assertTrue($response instanceof Response);
$this->assertEquals(405, $response->getStatusCode(), var_export($response, 1));
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'The request method must be POST when revoking an access token');
}
public function testCreateController()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$accessToken = new \OAuth2\ResponseType\AccessToken($storage);
$controller = new TokenController($accessToken, $storage);
}
private function getTestServer()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,102 @@
<?php
namespace OAuth2\Encryption;
use OAuth2\Storage\Bootstrap;
class FirebaseJwtTest extends \PHPUnit_Framework_TestCase
{
private $privateKey;
public function setUp()
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC5/SxVlE8gnpFqCxgl2wjhzY7ucEi00s0kUg3xp7lVEvgLgYcA
nHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1owR0p4d9pOaJK07d01+RzoQLO
IQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8UlvdRKBxriRnlP3qJQIDAQAB
AoGAVgJJVU4fhYMu1e5JfYAcTGfF+Gf+h3iQm4JCpoUcxMXf5VpB9ztk3K7LRN5y
kwFuFALpnUAarRcUPs0D8FoP4qBluKksbAtgHkO7bMSH9emN+mH4le4qpFlR7+P1
3fLE2Y19IBwPwEfClC+TpJvuog6xqUYGPlg6XLq/MxQUB4ECQQDgovP1v+ONSeGS
R+NgJTR47noTkQT3M2izlce/OG7a+O0yw6BOZjNXqH2wx3DshqMcPUFrTjibIClP
l/tEQ3ShAkEA0/TdBYDtXpNNjqg0R9GVH2pw7Kh68ne6mZTuj0kCgFYpUF6L6iMm
zXamIJ51rTDsTyKTAZ1JuAhAsK/M2BbDBQJAKQ5fXEkIA+i+64dsDUR/hKLBeRYG
PFAPENONQGvGBwt7/s02XV3cgGbxIgAxqWkqIp0neb9AJUoJgtyaNe3GQQJANoL4
QQ0af0NVJAZgg8QEHTNL3aGrFSbzx8IE5Lb7PLRsJa5bP5lQxnDoYuU+EI/Phr62
niisp/b/ZDGidkTMXQJBALeRsH1I+LmICAvWXpLKa9Gv0zGCwkuIJLiUbV9c6CVh
suocCAteQwL5iW2gA4AnYr5OGeHFsEl7NCQcwfPZpJ0=
-----END RSA PRIVATE KEY-----
EOD;
}
/** @dataProvider provideClientCredentials */
public function testJwtUtil($client_id, $client_key)
{
$jwtUtil = new FirebaseJwt();
$params = array(
'iss' => $client_id,
'exp' => time() + 1000,
'iat' => time(),
'sub' => 'testuser@ourdomain.com',
'aud' => 'http://myapp.com/oauth/auth',
'scope' => null,
);
$encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
// test BC behaviour of trusting the algorithm in the header
$payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
$this->assertEquals($params, $payload);
// test BC behaviour of not verifying by passing false
$payload = $jwtUtil->decode($encoded, $client_key, false);
$this->assertEquals($params, $payload);
// test the new restricted algorithms header
$payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
$this->assertEquals($params, $payload);
}
public function testInvalidJwt()
{
$jwtUtil = new FirebaseJwt();
$this->assertFalse($jwtUtil->decode('goob'));
$this->assertFalse($jwtUtil->decode('go.o.b'));
}
/** @dataProvider provideClientCredentials */
public function testInvalidJwtHeader($client_id, $client_key)
{
$jwtUtil = new FirebaseJwt();
$params = array(
'iss' => $client_id,
'exp' => time() + 1000,
'iat' => time(),
'sub' => 'testuser@ourdomain.com',
'aud' => 'http://myapp.com/oauth/auth',
'scope' => null,
);
// testing for algorithm tampering when only RSA256 signing is allowed
// @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
$tampered = $jwtUtil->encode($params, $client_key, 'HS256');
$payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
$this->assertFalse($payload);
}
public function provideClientCredentials()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$client_id = 'Test Client ID';
$client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
return array(
array($client_id, $client_key),
);
}
}

View file

@ -0,0 +1,102 @@
<?php
namespace OAuth2\Encryption;
use OAuth2\Storage\Bootstrap;
class JwtTest extends \PHPUnit_Framework_TestCase
{
private $privateKey;
public function setUp()
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC5/SxVlE8gnpFqCxgl2wjhzY7ucEi00s0kUg3xp7lVEvgLgYcA
nHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1owR0p4d9pOaJK07d01+RzoQLO
IQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8UlvdRKBxriRnlP3qJQIDAQAB
AoGAVgJJVU4fhYMu1e5JfYAcTGfF+Gf+h3iQm4JCpoUcxMXf5VpB9ztk3K7LRN5y
kwFuFALpnUAarRcUPs0D8FoP4qBluKksbAtgHkO7bMSH9emN+mH4le4qpFlR7+P1
3fLE2Y19IBwPwEfClC+TpJvuog6xqUYGPlg6XLq/MxQUB4ECQQDgovP1v+ONSeGS
R+NgJTR47noTkQT3M2izlce/OG7a+O0yw6BOZjNXqH2wx3DshqMcPUFrTjibIClP
l/tEQ3ShAkEA0/TdBYDtXpNNjqg0R9GVH2pw7Kh68ne6mZTuj0kCgFYpUF6L6iMm
zXamIJ51rTDsTyKTAZ1JuAhAsK/M2BbDBQJAKQ5fXEkIA+i+64dsDUR/hKLBeRYG
PFAPENONQGvGBwt7/s02XV3cgGbxIgAxqWkqIp0neb9AJUoJgtyaNe3GQQJANoL4
QQ0af0NVJAZgg8QEHTNL3aGrFSbzx8IE5Lb7PLRsJa5bP5lQxnDoYuU+EI/Phr62
niisp/b/ZDGidkTMXQJBALeRsH1I+LmICAvWXpLKa9Gv0zGCwkuIJLiUbV9c6CVh
suocCAteQwL5iW2gA4AnYr5OGeHFsEl7NCQcwfPZpJ0=
-----END RSA PRIVATE KEY-----
EOD;
}
/** @dataProvider provideClientCredentials */
public function testJwtUtil($client_id, $client_key)
{
$jwtUtil = new Jwt();
$params = array(
'iss' => $client_id,
'exp' => time() + 1000,
'iat' => time(),
'sub' => 'testuser@ourdomain.com',
'aud' => 'http://myapp.com/oauth/auth',
'scope' => null,
);
$encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
// test BC behaviour of trusting the algorithm in the header
$payload = $jwtUtil->decode($encoded, $client_key);
$this->assertEquals($params, $payload);
// test BC behaviour of not verifying by passing false
$payload = $jwtUtil->decode($encoded, $client_key, false);
$this->assertEquals($params, $payload);
// test the new restricted algorithms header
$payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
$this->assertEquals($params, $payload);
}
public function testInvalidJwt()
{
$jwtUtil = new Jwt();
$this->assertFalse($jwtUtil->decode('goob'));
$this->assertFalse($jwtUtil->decode('go.o.b'));
}
/** @dataProvider provideClientCredentials */
public function testInvalidJwtHeader($client_id, $client_key)
{
$jwtUtil = new Jwt();
$params = array(
'iss' => $client_id,
'exp' => time() + 1000,
'iat' => time(),
'sub' => 'testuser@ourdomain.com',
'aud' => 'http://myapp.com/oauth/auth',
'scope' => null,
);
// testing for algorithm tampering when only RSA256 signing is allowed
// @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
$tampered = $jwtUtil->encode($params, $client_key, 'HS256');
$payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
$this->assertFalse($payload);
}
public function provideClientCredentials()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$client_id = 'Test Client ID';
$client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
return array(
array($client_id, $client_key),
);
}
}

View file

@ -0,0 +1,207 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class AuthorizationCodeTest extends \PHPUnit_Framework_TestCase
{
public function testNoCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "code" is required');
}
public function testInvalidCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'InvalidCode', // invalid authorization code
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
}
public function testCodeCannotBeUsedTwice()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode', // valid code
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 200);
$this->assertNotNull($response->getParameter('access_token'));
// try to use the same code again
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
}
public function testExpiredCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-expired', // expired authorization code
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'The authorization code has expired');
}
public function testValidCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode', // valid code
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
}
public function testValidCodeNoScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-with-scope', // valid code
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1 scope2');
}
public function testValidCodeSameScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-with-scope', // valid code
'scope' => 'scope2 scope1',
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope2 scope1');
}
public function testValidCodeLessScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-with-scope', // valid code
'scope' => 'scope1',
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1');
}
public function testValidCodeDifferentScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-with-scope', // valid code
'scope' => 'scope3',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
}
public function testValidCodeInvalidScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-with-scope', // valid code
'scope' => 'invalid-scope',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
}
public function testValidClientDifferentCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Some Other Client', // valid client id
'client_secret' => 'TestSecret3', // valid client secret
'code' => 'testcode', // valid code
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'authorization_code doesn\'t exist or is invalid for the client');
}
private function getTestServer()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,159 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Request;
use OAuth2\Response;
class ClientCredentialsTest extends \PHPUnit_Framework_TestCase
{
public function testInvalidCredentials()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'FakeSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
}
public function testValidCredentials()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('scope', $token);
$this->assertNull($token['scope']);
}
public function testValidCredentialsWithScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'scope' => 'scope1',
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1');
}
public function testValidCredentialsInvalidScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'scope' => 'invalid-scope',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
}
public function testValidCredentialsInHeader()
{
// create with HTTP_AUTHORIZATION in header
$server = $this->getTestServer();
$headers = array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('Test Client ID:TestSecret'), 'REQUEST_METHOD' => 'POST');
$params = array('grant_type' => 'client_credentials');
$request = new Request(array(), $params, array(), array(), array(), $headers);
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertNotNull($token['access_token']);
// create using PHP Authorization Globals
$headers = array('PHP_AUTH_USER' => 'Test Client ID', 'PHP_AUTH_PW' => 'TestSecret', 'REQUEST_METHOD' => 'POST');
$params = array('grant_type' => 'client_credentials');
$request = new Request(array(), $params, array(), array(), array(), $headers);
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertNotNull($token['access_token']);
}
public function testValidCredentialsInRequest()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertNotNull($token['access_token']);
}
public function testValidCredentialsInQuerystring()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertNotNull($token['access_token']);
}
public function testClientUserIdIsSetInAccessToken()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Client ID With User ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
// verify the user_id was associated with the token
$storage = $server->getStorage('client');
$token = $storage->getAccessToken($token['access_token']);
$this->assertNotNull($token);
$this->assertArrayHasKey('user_id', $token);
$this->assertEquals($token['user_id'], 'brent@brentertainment.com');
}
private function getTestServer()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new ClientCredentials($storage));
return $server;
}
}

View file

@ -0,0 +1,143 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
class ImplicitTest extends \PHPUnit_Framework_TestCase
{
public function testImplicitNotAllowedResponse()
{
$server = $this->getTestServer();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'token', // invalid response type
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'unsupported_response_type');
$this->assertEquals($query['error_description'], 'implicit grant type not supported');
}
public function testUserDeniesAccessResponse()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'token', // valid response type
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), false);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
parse_str($parts['query'], $query);
$this->assertEquals($query['error'], 'access_denied');
$this->assertEquals($query['error_description'], 'The user denied access to your application');
}
public function testSuccessfulRequestFragmentParameter()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'token', // valid response type
'state' => 'xyz',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
$this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
$this->assertArrayHasKey('fragment', $parts);
$this->assertFalse(isset($parts['query']));
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['fragment'], $params);
$this->assertNotNull($params);
$this->assertArrayHasKey('access_token', $params);
$this->assertArrayHasKey('expires_in', $params);
$this->assertArrayHasKey('token_type', $params);
}
public function testSuccessfulRequestReturnsStateParameter()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'token', // valid response type
'state' => 'test', // valid state string (just needs to be passed back to us)
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
parse_str($parts['fragment'], $params);
$this->assertArrayHasKey('state', $params);
$this->assertEquals($params['state'], 'test');
}
public function testSuccessfulRequestStripsExtraParameters()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com?fake=something', // valid redirect URI
'response_type' => 'token', // valid response type
'state' => 'test', // valid state string (just needs to be passed back to us)
'fake' => 'something', // add extra param to querystring
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNull($response->getParameter('error'));
$this->assertNull($response->getParameter('error_description'));
$location = $response->getHttpHeader('Location');
$parts = parse_url($location);
$this->assertFalse(isset($parts['fake']));
$this->assertArrayHasKey('fragment', $parts);
parse_str($parts['fragment'], $params);
$this->assertFalse(isset($parmas['fake']));
$this->assertArrayHasKey('state', $params);
$this->assertEquals($params['state'], 'test');
}
private function getTestServer($config = array())
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
// Add the two types supported for authorization grant
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,360 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
use OAuth2\Encryption\Jwt;
class JwtBearerTest extends \PHPUnit_Framework_TestCase
{
private $privateKey;
public function setUp()
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC5/SxVlE8gnpFqCxgl2wjhzY7ucEi00s0kUg3xp7lVEvgLgYcA
nHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1owR0p4d9pOaJK07d01+RzoQLO
IQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8UlvdRKBxriRnlP3qJQIDAQAB
AoGAVgJJVU4fhYMu1e5JfYAcTGfF+Gf+h3iQm4JCpoUcxMXf5VpB9ztk3K7LRN5y
kwFuFALpnUAarRcUPs0D8FoP4qBluKksbAtgHkO7bMSH9emN+mH4le4qpFlR7+P1
3fLE2Y19IBwPwEfClC+TpJvuog6xqUYGPlg6XLq/MxQUB4ECQQDgovP1v+ONSeGS
R+NgJTR47noTkQT3M2izlce/OG7a+O0yw6BOZjNXqH2wx3DshqMcPUFrTjibIClP
l/tEQ3ShAkEA0/TdBYDtXpNNjqg0R9GVH2pw7Kh68ne6mZTuj0kCgFYpUF6L6iMm
zXamIJ51rTDsTyKTAZ1JuAhAsK/M2BbDBQJAKQ5fXEkIA+i+64dsDUR/hKLBeRYG
PFAPENONQGvGBwt7/s02XV3cgGbxIgAxqWkqIp0neb9AJUoJgtyaNe3GQQJANoL4
QQ0af0NVJAZgg8QEHTNL3aGrFSbzx8IE5Lb7PLRsJa5bP5lQxnDoYuU+EI/Phr62
niisp/b/ZDGidkTMXQJBALeRsH1I+LmICAvWXpLKa9Gv0zGCwkuIJLiUbV9c6CVh
suocCAteQwL5iW2gA4AnYr5OGeHFsEl7NCQcwfPZpJ0=
-----END RSA PRIVATE KEY-----
EOD;
}
public function testMalformedJWT()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get the jwt and break it
$jwt = $this->getJWT();
$jwt = substr_replace($jwt, 'broken', 3, 6);
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'JWT is malformed');
}
public function testBrokenSignature()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get the jwt and break signature
$jwt = $this->getJWT() . 'notSupposeToBeHere';
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'JWT failed signature verification');
}
public function testExpiredJWT()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get an expired JWT
$jwt = $this->getJWT(1234);
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'JWT has expired');
}
public function testBadExp()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get an expired JWT
$jwt = $this->getJWT('badtimestamp');
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Expiration (exp) time must be a unix time stamp');
}
public function testNoAssert()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Do not pass the assert (JWT)
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "assertion" required');
}
public function testNotBefore()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get a future NBF
$jwt = $this->getJWT(null, time() + 10000);
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'JWT cannot be used before the Not Before (nbf) time');
}
public function testBadNotBefore()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
));
//Get a non timestamp nbf
$jwt = $this->getJWT(null, 'notatimestamp');
$request->request['assertion'] = $jwt;
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Not Before (nbf) time must be a unix time stamp');
}
public function testNonMatchingAudience()
{
$server = $this->getTestServer('http://google.com/oauth/o/auth');
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(),
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid audience (aud)');
}
public function testBadClientID()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, null, 'bad_client_id'),
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
}
public function testBadSubject()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, 'anotheruser@ourdomain,com'),
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
}
public function testMissingKey()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, null, 'Missing Key Cli,nt'),
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
}
public function testValidJwt()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(), // valid assertion
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
}
public function testValidJwtWithScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
'scope' => 'scope1', // valid scope
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1');
}
public function testValidJwtInvalidScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
'scope' => 'invalid-scope', // invalid scope
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
}
public function testValidJti()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(null, null, 'testuser@ourdomain.com', 'Test Client ID', 'unused_jti'), // valid assertion with invalid scope
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
}
public function testInvalidJti()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'used_jti'), // valid assertion with invalid scope
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
}
public function testJtiReplayAttack()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'totally_new_jti'), // valid assertion with invalid scope
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
//Replay the same request
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
}
/**
* Generates a JWT
* @param $exp The expiration date. If the current time is greater than the exp, the JWT is invalid.
* @param $nbf The "not before" time. If the current time is less than the nbf, the JWT is invalid.
* @param $sub The subject we are acting on behalf of. This could be the email address of the user in the system.
* @param $iss The issuer, usually the client_id.
* @return string
*/
private function getJWT($exp = null, $nbf = null, $sub = null, $iss = 'Test Client ID', $jti = null)
{
if (!$exp) {
$exp = time() + 1000;
}
if (!$sub) {
$sub = "testuser@ourdomain.com";
}
$params = array(
'iss' => $iss,
'exp' => $exp,
'iat' => time(),
'sub' => $sub,
'aud' => 'http://myapp.com/oauth/auth',
);
if ($nbf) {
$params['nbf'] = $nbf;
}
if ($jti) {
$params['jti'] = $jti;
}
$jwtUtil = new Jwt();
return $jwtUtil->encode($params, $this->privateKey, 'RS256');
}
private function getTestServer($audience = 'http://myapp.com/oauth/auth')
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new JwtBearer($storage, $audience, new Jwt()));
return $server;
}
}

View file

@ -0,0 +1,204 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class RefreshTokenTest extends \PHPUnit_Framework_TestCase
{
private $storage;
public function testNoRefreshToken()
{
$server = $this->getTestServer();
$server->addGrantType(new RefreshToken($this->storage));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "refresh_token" is required');
}
public function testInvalidRefreshToken()
{
$server = $this->getTestServer();
$server->addGrantType(new RefreshToken($this->storage));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'fake-token', // invalid refresh token
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid refresh token');
}
public function testValidRefreshTokenWithNewRefreshTokenInResponse()
{
$server = $this->getTestServer();
$server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => true)));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken', // valid refresh token
));
$token = $server->grantAccessToken($request, new Response());
$this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
$refresh_token = $this->storage->getRefreshToken($token['refresh_token']);
$this->assertNotNull($refresh_token);
$this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
$this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
$this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
$used_token = $this->storage->getRefreshToken('test-refreshtoken');
$this->assertFalse($used_token, 'the refresh token used is no longer valid');
}
public function testValidRefreshTokenDoesNotUnsetToken()
{
$server = $this->getTestServer();
$server->addGrantType(new RefreshToken($this->storage, array(
'always_issue_new_refresh_token' => true,
'unset_refresh_token_after_use' => false,
)));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken', // valid refresh token
));
$token = $server->grantAccessToken($request, new Response());
$this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
$used_token = $this->storage->getRefreshToken('test-refreshtoken');
$this->assertNotNull($used_token, 'the refresh token used is still valid');
}
public function testValidRefreshTokenWithNoRefreshTokenInResponse()
{
$server = $this->getTestServer();
$server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => false)));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken', // valid refresh token
));
$token = $server->grantAccessToken($request, new Response());
$this->assertFalse(isset($token['refresh_token']), 'refresh token should not be returned');
$used_token = $this->storage->getRefreshToken('test-refreshtoken');
$this->assertNotNull($used_token, 'the refresh token used is still valid');
}
public function testValidRefreshTokenSameScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
'scope' => 'scope2 scope1',
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope2 scope1');
}
public function testValidRefreshTokenLessScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
'scope' => 'scope1',
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1');
}
public function testValidRefreshTokenDifferentScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
'scope' => 'scope3',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
}
public function testValidRefreshTokenInvalidScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
'scope' => 'invalid-scope',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
}
public function testValidClientDifferentRefreshToken()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Some Other Client', // valid client id
'client_secret' => 'TestSecret3', // valid client secret
'refresh_token' => 'test-refreshtoken', // valid refresh token
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'refresh_token doesn\'t exist or is invalid for the client');
}
private function getTestServer()
{
$this->storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($this->storage);
return $server;
}
}

View file

@ -0,0 +1,172 @@
<?php
namespace OAuth2\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class UserCredentialsTest extends \PHPUnit_Framework_TestCase
{
public function testNoUsername()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'password' => 'testpass', // valid password
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
}
public function testNoPassword()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
));
$server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
}
public function testInvalidUsername()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'fake-username', // valid username
'password' => 'testpass', // valid password
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 401);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
}
public function testInvalidPassword()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
'password' => 'fakepass', // invalid password
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 401);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
$this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
}
public function testValidCredentials()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
}
public function testValidCredentialsWithScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
'scope' => 'scope1', // valid scope
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('scope', $token);
$this->assertEquals($token['scope'], 'scope1');
}
public function testValidCredentialsInvalidScope()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
'scope' => 'invalid-scope',
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_scope');
$this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
}
public function testNoSecretWithPublicClient()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID Empty Secret', // valid public client
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
}
public function testNoSecretWithConfidentialClient()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid public client
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
));
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_client');
$this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
}
private function getTestServer()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage);
$server->addGrantType(new UserCredentials($storage));
return $server;
}
}

View file

@ -0,0 +1,182 @@
<?php
namespace OAuth2\OpenID\Controller;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
{
public function testValidateAuthorizeRequest()
{
$server = $this->getTestServer();
$response = new Response();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'id_token',
'state' => 'af0ifjsldkj',
'nonce' => 'n-0S6_WzA2Mj',
));
// Test valid id_token request
$server->handleAuthorizeRequest($request, $response, true);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['fragment'], $query);
$this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
$this->assertEquals($query['state'], 'af0ifjsldkj');
$this->assertArrayHasKey('id_token', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayNotHasKey('access_token', $query);
$this->assertArrayNotHasKey('expires_in', $query);
$this->assertArrayNotHasKey('token_type', $query);
// Test valid token id_token request
$request->query['response_type'] = 'id_token token';
$server->handleAuthorizeRequest($request, $response, true);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['fragment'], $query);
$this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
$this->assertEquals($query['state'], 'af0ifjsldkj');
$this->assertArrayHasKey('access_token', $query);
$this->assertArrayHasKey('expires_in', $query);
$this->assertArrayHasKey('token_type', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('id_token', $query);
// assert that with multiple-valued response types, order does not matter
$request->query['response_type'] = 'token id_token';
$server->handleAuthorizeRequest($request, $response, true);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['fragment'], $query);
$this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
$this->assertEquals($query['state'], 'af0ifjsldkj');
$this->assertArrayHasKey('access_token', $query);
$this->assertArrayHasKey('expires_in', $query);
$this->assertArrayHasKey('token_type', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('id_token', $query);
// assert that with multiple-valued response types with extra spaces do not matter
$request->query['response_type'] = ' token id_token ';
$server->handleAuthorizeRequest($request, $response, true);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['fragment'], $query);
$this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
$this->assertEquals($query['state'], 'af0ifjsldkj');
$this->assertArrayHasKey('access_token', $query);
$this->assertArrayHasKey('expires_in', $query);
$this->assertArrayHasKey('token_type', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('id_token', $query);
}
public function testMissingNonce()
{
$server = $this->getTestServer();
$authorize = $server->getAuthorizeController();
$response = new Response();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'id_token',
'state' => 'xyz',
));
// Test missing nonce for 'id_token' response type
$server->handleAuthorizeRequest($request, $response, true);
$params = $response->getParameters();
$this->assertEquals($params['error'], 'invalid_nonce');
$this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
// Test missing nonce for 'id_token token' response type
$request->query['response_type'] = 'id_token token';
$server->handleAuthorizeRequest($request, $response, true);
$params = $response->getParameters();
$this->assertEquals($params['error'], 'invalid_nonce');
$this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
}
public function testNotGrantedApplication()
{
$server = $this->getTestServer();
$response = new Response();
$request = new Request(array(
'client_id' => 'Test Client ID', // valid client id
'redirect_uri' => 'http://adobe.com', // valid redirect URI
'response_type' => 'id_token',
'state' => 'af0ifjsldkj',
'nonce' => 'n-0S6_WzA2Mj',
));
// Test not approved application
$server->handleAuthorizeRequest($request, $response, false);
$params = $response->getParameters();
$this->assertEquals($params['error'], 'consent_required');
$this->assertEquals($params['error_description'], 'The user denied access to your application');
// Test not approved application with prompt parameter
$request->query['prompt'] = 'none';
$server->handleAuthorizeRequest($request, $response, false);
$params = $response->getParameters();
$this->assertEquals($params['error'], 'login_required');
$this->assertEquals($params['error_description'], 'The user must log in');
// Test not approved application with user_id set
$request->query['prompt'] = 'none';
$server->handleAuthorizeRequest($request, $response, false, 'some-user-id');
$params = $response->getParameters();
$this->assertEquals($params['error'], 'interaction_required');
$this->assertEquals($params['error_description'], 'The user must grant access to your application');
}
public function testNeedsIdToken()
{
$server = $this->getTestServer();
$authorize = $server->getAuthorizeController();
$this->assertTrue($authorize->needsIdToken('openid'));
$this->assertTrue($authorize->needsIdToken('openid profile'));
$this->assertFalse($authorize->needsIdToken(''));
$this->assertFalse($authorize->needsIdToken('some-scope'));
}
private function getTestServer($config = array())
{
$config += array(
'use_openid_connect' => true,
'issuer' => 'phpunit',
'allow_implicit' => true
);
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
return $server;
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace OAuth2\OpenID\Controller;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
class UserInfoControllerTest extends \PHPUnit_Framework_TestCase
{
public function testCreateController()
{
$tokenType = new \OAuth2\TokenType\Bearer();
$storage = new \OAuth2\Storage\Memory();
$controller = new UserInfoController($tokenType, $storage, $storage);
$response = new Response();
$controller->handleUserInfoRequest(new Request(), $response);
$this->assertEquals(401, $response->getStatusCode());
}
public function testValidToken()
{
$server = $this->getTestServer();
$request = Request::createFromGlobals();
$request->headers['AUTHORIZATION'] = 'Bearer accesstoken-openid-connect';
$response = new Response();
$server->handleUserInfoRequest($request, $response);
$parameters = $response->getParameters();
$this->assertEquals($parameters['sub'], 'testuser');
$this->assertEquals($parameters['email'], 'testuser@test.com');
$this->assertEquals($parameters['email_verified'], true);
}
private function getTestServer($config = array())
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
return $server;
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace OAuth2\OpenID\GrantType;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class AuthorizationCodeTest extends \PHPUnit_Framework_TestCase
{
public function testValidCode()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-openid', // valid code
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('id_token', $token);
$this->assertEquals('test_id_token', $token['id_token']);
// this is only true if "offline_access" was requested
$this->assertFalse(isset($token['refresh_token']));
}
public function testOfflineAccess()
{
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'code' => 'testcode-openid', // valid code
'scope' => 'offline_access', // valid code
));
$token = $server->grantAccessToken($request, new Response());
$this->assertNotNull($token);
$this->assertArrayHasKey('id_token', $token);
$this->assertEquals('test_id_token', $token['id_token']);
$this->assertTrue(isset($token['refresh_token']));
}
private function getTestServer()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, array('use_openid_connect' => true));
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,91 @@
<?php
namespace OAuth2\OpenID\ResponseType;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
use OAuth2\Storage\Bootstrap;
use OAuth2\GrantType\ClientCredentials;
class CodeIdTokenTest extends \PHPUnit_Framework_TestCase
{
public function testHandleAuthorizeRequest()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = new Request(array(
'response_type' => 'code id_token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid',
'state' => 'test',
'nonce' => 'test',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['query'], $params);
$this->assertNotNull($params);
$this->assertArrayHasKey('id_token', $params);
$this->assertArrayHasKey('code', $params);
// validate ID Token
$parts = explode('.', $params['id_token']);
foreach ($parts as &$part) {
// Each part is a base64url encoded json string.
$part = str_replace(array('-', '_'), array('+', '/'), $part);
$part = base64_decode($part);
$part = json_decode($part, true);
}
list($header, $claims, $signature) = $parts;
$this->assertArrayHasKey('iss', $claims);
$this->assertArrayHasKey('sub', $claims);
$this->assertArrayHasKey('aud', $claims);
$this->assertArrayHasKey('iat', $claims);
$this->assertArrayHasKey('exp', $claims);
$this->assertArrayHasKey('auth_time', $claims);
$this->assertArrayHasKey('nonce', $claims);
// only exists if an access token was granted along with the id_token
$this->assertArrayNotHasKey('at_hash', $claims);
$this->assertEquals($claims['iss'], 'test');
$this->assertEquals($claims['aud'], 'Test Client ID');
$this->assertEquals($claims['nonce'], 'test');
$duration = $claims['exp'] - $claims['iat'];
$this->assertEquals($duration, 3600);
}
private function getTestServer($config = array())
{
$config += array(
'use_openid_connect' => true,
'issuer' => 'test',
'id_lifetime' => 3600,
'allow_implicit' => true,
);
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$responseTypes = array(
'code' => $code = new AuthorizationCode($memoryStorage),
'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
'code id_token' => new CodeIdToken($code, $idToken),
);
$server = new Server($memoryStorage, $config, array(), $responseTypes);
$server->addGrantType(new ClientCredentials($memoryStorage));
return $server;
}
}

View file

@ -0,0 +1,184 @@
<?php
namespace OAuth2\OpenID\ResponseType;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
use OAuth2\Storage\Bootstrap;
use OAuth2\GrantType\ClientCredentials;
use OAuth2\Encryption\Jwt;
class IdTokenTest extends \PHPUnit_Framework_TestCase
{
public function testValidateAuthorizeRequest()
{
$query = array(
'response_type' => 'id_token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid',
'state' => 'test',
);
// attempt to do the request without a nonce.
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request($query);
$valid = $server->validateAuthorizeRequest($request, $response = new Response());
// Add a nonce and retry.
$query['nonce'] = 'test';
$request = new Request($query);
$valid = $server->validateAuthorizeRequest($request, $response = new Response());
$this->assertTrue($valid);
}
public function testHandleAuthorizeRequest()
{
// add the test parameters in memory
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'response_type' => 'id_token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid email',
'state' => 'test',
'nonce' => 'test',
));
$user_id = 'testuser';
$server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
$this->assertFalse(isset($parts['query']));
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['fragment'], $params);
$this->assertNotNull($params);
$this->assertArrayHasKey('id_token', $params);
$this->assertArrayNotHasKey('access_token', $params);
$this->validateIdToken($params['id_token']);
}
public function testPassInAuthTime()
{
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'response_type' => 'id_token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid email',
'state' => 'test',
'nonce' => 'test',
));
// test with a scalar user id
$user_id = 'testuser123';
$server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
$this->assertTrue(is_array($payload));
$this->assertArrayHasKey('sub', $payload);
$this->assertEquals($user_id, $payload['sub']);
$this->assertArrayHasKey('auth_time', $payload);
// test with an array of user info
$userInfo = array(
'user_id' => 'testuser1234',
'auth_time' => date('Y-m-d H:i:s', strtotime('20 minutes ago')
));
$server->handleAuthorizeRequest($request, $response = new Response(), true, $userInfo);
list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
$this->assertTrue(is_array($payload));
$this->assertArrayHasKey('sub', $payload);
$this->assertEquals($userInfo['user_id'], $payload['sub']);
$this->assertArrayHasKey('auth_time', $payload);
$this->assertEquals($userInfo['auth_time'], $payload['auth_time']);
}
private function extractTokenDataFromResponse(Response $response)
{
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
$this->assertFalse(isset($parts['query']));
parse_str($parts['fragment'], $params);
$this->assertNotNull($params);
$this->assertArrayHasKey('id_token', $params);
$this->assertArrayNotHasKey('access_token', $params);
list($headb64, $payloadb64, $signature) = explode('.', $params['id_token']);
$jwt = new Jwt();
$header = json_decode($jwt->urlSafeB64Decode($headb64), true);
$payload = json_decode($jwt->urlSafeB64Decode($payloadb64), true);
return array($header, $payload, $signature);
}
private function validateIdToken($id_token)
{
$parts = explode('.', $id_token);
foreach ($parts as &$part) {
// Each part is a base64url encoded json string.
$part = str_replace(array('-', '_'), array('+', '/'), $part);
$part = base64_decode($part);
$part = json_decode($part, true);
}
list($header, $claims, $signature) = $parts;
$this->assertArrayHasKey('iss', $claims);
$this->assertArrayHasKey('sub', $claims);
$this->assertArrayHasKey('aud', $claims);
$this->assertArrayHasKey('iat', $claims);
$this->assertArrayHasKey('exp', $claims);
$this->assertArrayHasKey('auth_time', $claims);
$this->assertArrayHasKey('nonce', $claims);
$this->assertArrayHasKey('email', $claims);
$this->assertArrayHasKey('email_verified', $claims);
$this->assertEquals($claims['iss'], 'test');
$this->assertEquals($claims['aud'], 'Test Client ID');
$this->assertEquals($claims['nonce'], 'test');
$this->assertEquals($claims['email'], 'testuser@test.com');
$duration = $claims['exp'] - $claims['iat'];
$this->assertEquals($duration, 3600);
}
private function getTestServer($config = array())
{
$config += array(
'use_openid_connect' => true,
'issuer' => 'test',
'id_lifetime' => 3600,
);
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$memoryStorage->supportedScopes[] = 'email';
$storage = array(
'client' => $memoryStorage,
'scope' => $memoryStorage,
);
$responseTypes = array(
'id_token' => new IdToken($memoryStorage, $memoryStorage, $config),
);
$server = new Server($storage, $config, array(), $responseTypes);
$server->addGrantType(new ClientCredentials($memoryStorage));
return $server;
}
}

View file

@ -0,0 +1,91 @@
<?php
namespace OAuth2\OpenID\ResponseType;
use OAuth2\Server;
use OAuth2\Request;
use OAuth2\Response;
use OAuth2\Storage\Bootstrap;
use OAuth2\GrantType\ClientCredentials;
use OAuth2\ResponseType\AccessToken;
class IdTokenTokenTest extends \PHPUnit_Framework_TestCase
{
public function testHandleAuthorizeRequest()
{
// add the test parameters in memory
$server = $this->getTestServer(array('allow_implicit' => true));
$request = new Request(array(
'response_type' => 'id_token token',
'redirect_uri' => 'http://adobe.com',
'client_id' => 'Test Client ID',
'scope' => 'openid',
'state' => 'test',
'nonce' => 'test',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
$this->assertFalse(isset($parts['query']));
// assert fragment is in "application/x-www-form-urlencoded" format
parse_str($parts['fragment'], $params);
$this->assertNotNull($params);
$this->assertArrayHasKey('id_token', $params);
$this->assertArrayHasKey('access_token', $params);
// validate ID Token
$parts = explode('.', $params['id_token']);
foreach ($parts as &$part) {
// Each part is a base64url encoded json string.
$part = str_replace(array('-', '_'), array('+', '/'), $part);
$part = base64_decode($part);
$part = json_decode($part, true);
}
list($header, $claims, $signature) = $parts;
$this->assertArrayHasKey('iss', $claims);
$this->assertArrayHasKey('sub', $claims);
$this->assertArrayHasKey('aud', $claims);
$this->assertArrayHasKey('iat', $claims);
$this->assertArrayHasKey('exp', $claims);
$this->assertArrayHasKey('auth_time', $claims);
$this->assertArrayHasKey('nonce', $claims);
$this->assertArrayHasKey('at_hash', $claims);
$this->assertEquals($claims['iss'], 'test');
$this->assertEquals($claims['aud'], 'Test Client ID');
$this->assertEquals($claims['nonce'], 'test');
$duration = $claims['exp'] - $claims['iat'];
$this->assertEquals($duration, 3600);
}
private function getTestServer($config = array())
{
$config += array(
'use_openid_connect' => true,
'issuer' => 'test',
'id_lifetime' => 3600,
);
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$responseTypes = array(
'token' => $token = new AccessToken($memoryStorage, $memoryStorage),
'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
'id_token token' => new IdTokenToken($token, $idToken),
);
$server = new Server($memoryStorage, $config, array(), $responseTypes);
$server->addGrantType(new ClientCredentials($memoryStorage));
return $server;
}
}

View file

@ -0,0 +1,95 @@
<?php
namespace OAuth2\OpenID\Storage;
use OAuth2\Storage\BaseTest;
use OAuth2\Storage\NullStorage;
class AuthorizationCodeTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testCreateAuthorizationCode($storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
if (!$storage instanceof AuthorizationCodeInterface) {
return;
}
// assert code we are about to add does not exist
$code = $storage->getAuthorizationCode('new-openid-code');
$this->assertFalse($code);
// add new code
$expires = time() + 20;
$scope = null;
$id_token = 'fake_id_token';
$success = $storage->setAuthorizationCode('new-openid-code', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
$this->assertTrue($success);
$code = $storage->getAuthorizationCode('new-openid-code');
$this->assertNotNull($code);
$this->assertArrayHasKey('authorization_code', $code);
$this->assertArrayHasKey('client_id', $code);
$this->assertArrayHasKey('user_id', $code);
$this->assertArrayHasKey('redirect_uri', $code);
$this->assertArrayHasKey('expires', $code);
$this->assertEquals($code['authorization_code'], 'new-openid-code');
$this->assertEquals($code['client_id'], 'client ID');
$this->assertEquals($code['user_id'], 'SOMEUSERID');
$this->assertEquals($code['redirect_uri'], 'http://example.com');
$this->assertEquals($code['expires'], $expires);
$this->assertEquals($code['id_token'], $id_token);
// change existing code
$expires = time() + 42;
$new_id_token = 'fake_id_token-2';
$success = $storage->setAuthorizationCode('new-openid-code', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires, $scope, $new_id_token);
$this->assertTrue($success);
$code = $storage->getAuthorizationCode('new-openid-code');
$this->assertNotNull($code);
$this->assertArrayHasKey('authorization_code', $code);
$this->assertArrayHasKey('client_id', $code);
$this->assertArrayHasKey('user_id', $code);
$this->assertArrayHasKey('redirect_uri', $code);
$this->assertArrayHasKey('expires', $code);
$this->assertEquals($code['authorization_code'], 'new-openid-code');
$this->assertEquals($code['client_id'], 'client ID2');
$this->assertEquals($code['user_id'], 'SOMEOTHERID');
$this->assertEquals($code['redirect_uri'], 'http://example.org');
$this->assertEquals($code['expires'], $expires);
$this->assertEquals($code['id_token'], $new_id_token);
}
/** @dataProvider provideStorage */
public function testRemoveIdTokenFromAuthorizationCode($storage)
{
// add new code
$expires = time() + 20;
$scope = null;
$id_token = 'fake_id_token_to_remove';
$authcode = 'new-openid-code-'.rand();
$success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
$this->assertTrue($success);
// verify params were set
$code = $storage->getAuthorizationCode($authcode);
$this->assertNotNull($code);
$this->assertArrayHasKey('id_token', $code);
$this->assertEquals($code['id_token'], $id_token);
// remove the id_token
$success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, null);
// verify the "id_token" is now null
$code = $storage->getAuthorizationCode($authcode);
$this->assertNotNull($code);
$this->assertArrayHasKey('id_token', $code);
$this->assertEquals($code['id_token'], null);
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace OAuth2\OpenID\Storage;
use OAuth2\Storage\BaseTest;
use OAuth2\Storage\NullStorage;
class UserClaimsTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testGetUserClaims($storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
if (!$storage instanceof UserClaimsInterface) {
// incompatible storage
return;
}
// invalid user
$claims = $storage->getUserClaims('fake-user', '');
$this->assertFalse($claims);
// valid user (no scope)
$claims = $storage->getUserClaims('testuser', '');
/* assert the decoded token is the same */
$this->assertFalse(isset($claims['email']));
// valid user
$claims = $storage->getUserClaims('testuser', 'email');
/* assert the decoded token is the same */
$this->assertEquals($claims['email'], "testuser@test.com");
$this->assertEquals($claims['email_verified'], true);
}
}

View file

@ -0,0 +1,98 @@
<?php
namespace OAuth2;
use OAuth2\Request\TestRequest;
use OAuth2\Storage\Bootstrap;
use OAuth2\GrantType\AuthorizationCode;
class RequestTest extends \PHPUnit_Framework_TestCase
{
public function testRequestOverride()
{
$request = new TestRequest();
$server = $this->getTestServer();
// Smoke test for override request class
// $server->handleTokenRequest($request, $response = new Response());
// $this->assertInstanceOf('Response', $response);
// $server->handleAuthorizeRequest($request, $response = new Response(), true);
// $this->assertInstanceOf('Response', $response);
// $response = $server->verifyResourceRequest($request, $response = new Response());
// $this->assertTrue(is_bool($response));
/*** make some valid requests ***/
// Valid Token Request
$request->setPost(array(
'grant_type' => 'authorization_code',
'client_id' => 'Test Client ID',
'client_secret' => 'TestSecret',
'code' => 'testcode',
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertEquals($response->getStatusCode(), 200);
$this->assertNull($response->getParameter('error'));
$this->assertNotNUll($response->getParameter('access_token'));
}
public function testHeadersReturnsValueByKey()
{
$request = new Request(
array(),
array(),
array(),
array(),
array(),
array(),
array(),
array('AUTHORIZATION' => 'Basic secret')
);
$this->assertEquals('Basic secret', $request->headers('AUTHORIZATION'));
}
public function testHeadersReturnsDefaultIfHeaderNotPresent()
{
$request = new Request();
$this->assertEquals('Bearer', $request->headers('AUTHORIZATION', 'Bearer'));
}
public function testHeadersIsCaseInsensitive()
{
$request = new Request(
array(),
array(),
array(),
array(),
array(),
array(),
array(),
array('AUTHORIZATION' => 'Basic secret')
);
$this->assertEquals('Basic secret', $request->headers('Authorization'));
}
public function testRequestReturnsPostParamIfNoQueryParamAvailable()
{
$request = new Request(
array(),
array('client_id' => 'correct')
);
$this->assertEquals('correct', $request->query('client_id', $request->request('client_id')));
}
private function getTestServer($config = array())
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
// Add the two types supported for authorization grant
$server->addGrantType(new AuthorizationCode($storage));
return $server;
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace OAuth2;
class ResponseTest extends \PHPUnit_Framework_TestCase
{
public function testRenderAsXml()
{
$response = new Response(array(
'foo' => 'bar',
'halland' => 'oates',
));
$string = $response->getResponseBody('xml');
$this->assertContains('<response><foo>bar</foo><halland>oates</halland></response>', $string);
}
}

View file

@ -0,0 +1,107 @@
<?php
namespace OAuth2\ResponseType;
use OAuth2\Server;
use OAuth2\Storage\Memory;
class AccessTokenTest extends \PHPUnit_Framework_TestCase
{
public function testRevokeAccessTokenWithTypeHint()
{
$tokenStorage = new Memory(array(
'access_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
$accessToken = new AccessToken($tokenStorage);
$accessToken->revokeToken('revoke', 'access_token');
$this->assertFalse($tokenStorage->getAccessToken('revoke'));
}
public function testRevokeAccessTokenWithoutTypeHint()
{
$tokenStorage = new Memory(array(
'access_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
$accessToken = new AccessToken($tokenStorage);
$accessToken->revokeToken('revoke');
$this->assertFalse($tokenStorage->getAccessToken('revoke'));
}
public function testRevokeRefreshTokenWithTypeHint()
{
$tokenStorage = new Memory(array(
'refresh_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
$accessToken = new AccessToken(new Memory, $tokenStorage);
$accessToken->revokeToken('revoke', 'refresh_token');
$this->assertFalse($tokenStorage->getRefreshToken('revoke'));
}
public function testRevokeRefreshTokenWithoutTypeHint()
{
$tokenStorage = new Memory(array(
'refresh_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
$accessToken = new AccessToken(new Memory, $tokenStorage);
$accessToken->revokeToken('revoke');
$this->assertFalse($tokenStorage->getRefreshToken('revoke'));
}
public function testRevokeAccessTokenWithRefreshTokenTypeHint()
{
$tokenStorage = new Memory(array(
'access_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
$accessToken = new AccessToken($tokenStorage);
$accessToken->revokeToken('revoke', 'refresh_token');
$this->assertFalse($tokenStorage->getAccessToken('revoke'));
}
public function testRevokeAccessTokenWithBogusTypeHint()
{
$tokenStorage = new Memory(array(
'access_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
$accessToken = new AccessToken($tokenStorage);
$accessToken->revokeToken('revoke', 'foo');
$this->assertFalse($tokenStorage->getAccessToken('revoke'));
}
public function testRevokeRefreshTokenWithBogusTypeHint()
{
$tokenStorage = new Memory(array(
'refresh_tokens' => array(
'revoke' => array('mytoken'),
),
));
$this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
$accessToken = new AccessToken(new Memory, $tokenStorage);
$accessToken->revokeToken('revoke', 'foo');
$this->assertFalse($tokenStorage->getRefreshToken('revoke'));
}
}

View file

@ -0,0 +1,160 @@
<?php
namespace OAuth2\ResponseType;
use OAuth2\Server;
use OAuth2\Response;
use OAuth2\Request\TestRequest;
use OAuth2\Storage\Bootstrap;
use OAuth2\Storage\JwtAccessToken as JwtAccessTokenStorage;
use OAuth2\GrantType\ClientCredentials;
use OAuth2\GrantType\UserCredentials;
use OAuth2\GrantType\RefreshToken;
use OAuth2\Encryption\Jwt;
class JwtAccessTokenTest extends \PHPUnit_Framework_TestCase
{
public function testCreateAccessToken()
{
$server = $this->getTestServer();
$jwtResponseType = $server->getResponseType('token');
$accessToken = $jwtResponseType->createAccessToken('Test Client ID', 123, 'test', false);
$jwt = new Jwt;
$decodedAccessToken = $jwt->decode($accessToken['access_token'], null, false);
$this->assertArrayHasKey('id', $decodedAccessToken);
$this->assertArrayHasKey('jti', $decodedAccessToken);
$this->assertArrayHasKey('iss', $decodedAccessToken);
$this->assertArrayHasKey('aud', $decodedAccessToken);
$this->assertArrayHasKey('exp', $decodedAccessToken);
$this->assertArrayHasKey('iat', $decodedAccessToken);
$this->assertArrayHasKey('token_type', $decodedAccessToken);
$this->assertArrayHasKey('scope', $decodedAccessToken);
$this->assertEquals('https://api.example.com', $decodedAccessToken['iss']);
$this->assertEquals('Test Client ID', $decodedAccessToken['aud']);
$this->assertEquals(123, $decodedAccessToken['sub']);
$delta = $decodedAccessToken['exp'] - $decodedAccessToken['iat'];
$this->assertEquals(3600, $delta);
$this->assertEquals($decodedAccessToken['id'], $decodedAccessToken['jti']);
}
public function testGrantJwtAccessToken()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertNotNull($response->getParameter('access_token'));
$this->assertEquals(2, substr_count($response->getParameter('access_token'), '.'));
}
public function testAccessResourceWithJwtAccessToken()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
// make a call to the resource server using the crypto token
$request = TestRequest::createPost(array(
'access_token' => $JwtAccessToken,
));
$this->assertTrue($server->verifyResourceRequest($request));
}
public function testAccessResourceWithJwtAccessTokenUsingSecondaryStorage()
{
// add the test parameters in memory
$server = $this->getTestServer();
$request = TestRequest::createPost(array(
'grant_type' => 'client_credentials', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
// make a call to the resource server using the crypto token
$request = TestRequest::createPost(array(
'access_token' => $JwtAccessToken,
));
// create a resource server with the "memory" storage from the grant server
$resourceServer = new Server($server->getStorage('client_credentials'));
$this->assertTrue($resourceServer->verifyResourceRequest($request));
}
public function testJwtAccessTokenWithRefreshToken()
{
$server = $this->getTestServer();
// add "UserCredentials" grant type and "JwtAccessToken" response type
// and ensure "JwtAccessToken" response type has "RefreshToken" storage
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$server->addGrantType(new UserCredentials($memoryStorage));
$server->addGrantType(new RefreshToken($memoryStorage));
$server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, $memoryStorage), 'token');
$request = TestRequest::createPost(array(
'grant_type' => 'password', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'username' => 'test-username', // valid username
'password' => 'testpass', // valid password
));
// make the call to grant a crypto token
$server->handleTokenRequest($request, $response = new Response());
$this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
$this->assertNotNull($refreshToken = $response->getParameter('refresh_token'));
// decode token and make sure refresh_token isn't set
list($header, $payload, $signature) = explode('.', $JwtAccessToken);
$decodedToken = json_decode(base64_decode($payload), true);
$this->assertFalse(array_key_exists('refresh_token', $decodedToken));
// use the refresh token to get another access token
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token',
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => $refreshToken,
));
$server->handleTokenRequest($request, $response = new Response());
$this->assertNotNull($response->getParameter('access_token'));
}
private function getTestServer()
{
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$storage = array(
'access_token' => new JwtAccessTokenStorage($memoryStorage),
'client' => $memoryStorage,
'client_credentials' => $memoryStorage,
);
$server = new Server($storage);
$server->addGrantType(new ClientCredentials($memoryStorage));
// make the "token" response type a JwtAccessToken
$config = array('issuer' => 'https://api.example.com');
$server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, null, $config));
return $server;
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace OAuth2;
use OAuth2\Storage\Memory;
class ScopeTest extends \PHPUnit_Framework_TestCase
{
public function testCheckScope()
{
$scopeUtil = new Scope();
$this->assertFalse($scopeUtil->checkScope('invalid', 'list of scopes'));
$this->assertTrue($scopeUtil->checkScope('valid', 'valid and-some other-scopes'));
$this->assertTrue($scopeUtil->checkScope('valid another-valid', 'valid another-valid and-some other-scopes'));
// all scopes must match
$this->assertFalse($scopeUtil->checkScope('valid invalid', 'valid and-some other-scopes'));
$this->assertFalse($scopeUtil->checkScope('valid valid2 invalid', 'valid valid2 and-some other-scopes'));
}
public function testScopeStorage()
{
$scopeUtil = new Scope();
$this->assertEquals($scopeUtil->getDefaultScope(), null);
$scopeUtil = new Scope(array(
'default_scope' => 'default',
'supported_scopes' => array('this', 'that', 'another'),
));
$this->assertEquals($scopeUtil->getDefaultScope(), 'default');
$this->assertTrue($scopeUtil->scopeExists('this that another', 'client_id'));
$memoryStorage = new Memory(array(
'default_scope' => 'base',
'supported_scopes' => array('only-this-one'),
));
$scopeUtil = new Scope($memoryStorage);
$this->assertEquals($scopeUtil->getDefaultScope(), 'base');
$this->assertTrue($scopeUtil->scopeExists('only-this-one', 'client_id'));
}
}

View file

@ -0,0 +1,684 @@
<?php
namespace OAuth2;
use OAuth2\Request\TestRequest;
use OAuth2\ResponseType\AuthorizationCode;
use OAuth2\Storage\Bootstrap;
class ServerTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException LogicException OAuth2\Storage\ClientInterface
**/
public function testGetAuthorizeControllerWithNoClientStorageThrowsException()
{
// must set Client Storage
$server = new Server();
$server->getAuthorizeController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->getAuthorizeController();
}
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenResponseType()
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->getMock('OAuth2\ResponseType\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeResponseType()
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->getMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException allow_implicit
**/
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
{
// must set AuthorizationCode or AccessToken / implicit
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorage()
{
// must set AuthorizationCode or AccessToken / implicit
$server = new Server(array(), array('allow_implicit' => true));
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeStorage()
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AuthorizationCodeInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException grant_types
**/
public function testGetTokenControllerWithGrantTypeStorageThrowsException()
{
$server = new Server();
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\ClientCredentialsInterface
**/
public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\UserCredentialsInterface'));
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addGrantType($this->getMockBuilder('OAuth2\GrantType\AuthorizationCode')->disableOriginalConstructor()->getMock());
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
{
$server = new Server();
$server->getResourceController();
}
public function testGetResourceControllerWithAccessTokenStorage()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->getResourceController();
}
/**
* @expectedException InvalidArgumentException OAuth2\Storage\AccessTokenInterface
**/
public function testAddingStorageWithInvalidClass()
{
$server = new Server();
$server->addStorage(new \StdClass());
}
/**
* @expectedException InvalidArgumentException access_token
**/
public function testAddingStorageWithInvalidKey()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
}
/**
* @expectedException InvalidArgumentException OAuth2\Storage\AuthorizationCodeInterface
**/
public function testAddingStorageWithInvalidKeyStorageCombination()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
}
public function testAddingStorageWithValidKeyOnlySetsThatKey()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\Memory'), 'access_token');
$reflection = new \ReflectionClass($server);
$prop = $reflection->getProperty('storages');
$prop->setAccessible(true);
$storages = $prop->getValue($server); // get the private "storages" property
$this->assertEquals(1, count($storages));
$this->assertTrue(isset($storages['access_token']));
$this->assertFalse(isset($storages['authorization_code']));
}
public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
{
$server = new Server();
$memory = $this->getMock('OAuth2\Storage\Memory');
$server->addStorage($memory, 'client');
$client_credentials = $server->getStorage('client_credentials');
$this->assertNotNull($client_credentials);
$this->assertEquals($client_credentials, $memory);
}
public function testAddStorageWithNullValue()
{
$memory = $this->getMock('OAuth2\Storage\Memory');
$server = new Server($memory);
$server->addStorage(null, 'refresh_token');
$client_credentials = $server->getStorage('client_credentials');
$this->assertNotNull($client_credentials);
$this->assertEquals($client_credentials, $memory);
$refresh_token = $server->getStorage('refresh_token');
$this->assertNull($refresh_token);
}
public function testNewServerWithNullStorageValue()
{
$memory = $this->getMock('OAuth2\Storage\Memory');
$server = new Server(array(
'client_credentials' => $memory,
'refresh_token' => null,
));
$client_credentials = $server->getStorage('client_credentials');
$this->assertNotNull($client_credentials);
$this->assertEquals($client_credentials, $memory);
$refresh_token = $server->getStorage('refresh_token');
$this->assertNull($refresh_token);
}
public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
{
$server = new Server();
$memory = $this->getMock('OAuth2\Storage\Memory');
$server->addStorage($memory, 'client_credentials');
$client = $server->getStorage('client');
$this->assertNotNull($client);
$this->assertEquals($client, $memory);
}
public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
{
$server = new Server();
$pdo = $this->getMockBuilder('OAuth2\Storage\Pdo')
->disableOriginalConstructor()->getMock();
$memory = $this->getMock('OAuth2\Storage\Memory');
$server->addStorage($pdo, 'client');
$server->addStorage($memory, 'client_credentials');
$client = $server->getStorage('client');
$client_credentials = $server->getStorage('client_credentials');
$this->assertEquals($client, $pdo);
$this->assertEquals($client_credentials, $memory);
}
public function testAddingResponseType()
{
$storage = $this->getMock('OAuth2\Storage\Memory');
$storage
->expects($this->any())
->method('getClientDetails')
->will($this->returnValue(array('client_id' => 'some_client')));
$storage
->expects($this->any())
->method('checkRestrictedGrantType')
->will($this->returnValue(true));
// add with the "code" key explicitly set
$codeType = new AuthorizationCode($storage);
$server = new Server();
$server->addStorage($storage);
$server->addResponseType($codeType);
$request = new Request(array(
'response_type' => 'code',
'client_id' => 'some_client',
'redirect_uri' => 'http://example.com',
'state' => 'xyx',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
// the response is successful
$this->assertEquals($response->getStatusCode(), 302);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['query'], $query);
$this->assertTrue(isset($query['code']));
$this->assertFalse(isset($query['error']));
// add with the "code" key not set
$codeType = new AuthorizationCode($storage);
$server = new Server(array($storage), array(), array(), array($codeType));
$request = new Request(array(
'response_type' => 'code',
'client_id' => 'some_client',
'redirect_uri' => 'http://example.com',
'state' => 'xyx',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
// the response is successful
$this->assertEquals($response->getStatusCode(), 302);
$parts = parse_url($response->getHttpHeader('Location'));
parse_str($parts['query'], $query);
$this->assertTrue(isset($query['code']));
$this->assertFalse(isset($query['error']));
}
public function testCustomClientAssertionType()
{
$request = TestRequest::createPost(array(
'grant_type' => 'authorization_code',
'client_id' =>'Test Client ID',
'code' => 'testcode',
));
// verify the mock clientAssertionType was called as expected
$clientAssertionType = $this->getMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface', array('validateRequest', 'getClientId'));
$clientAssertionType
->expects($this->once())
->method('validateRequest')
->will($this->returnValue(true));
$clientAssertionType
->expects($this->once())
->method('getClientId')
->will($this->returnValue('Test Client ID'));
// create mock storage
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server(array($storage), array(), array(), array(), null, null, $clientAssertionType);
$server->handleTokenRequest($request, $response = new Response());
}
public function testHttpBasicConfig()
{
// create mock storage
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server(array($storage), array(
'allow_credentials_in_request_body' => false,
'allow_public_clients' => false
));
$server->getTokenController();
$httpBasic = $server->getClientAssertionType();
$reflection = new \ReflectionClass($httpBasic);
$prop = $reflection->getProperty('config');
$prop->setAccessible(true);
$config = $prop->getValue($httpBasic); // get the private "config" property
$this->assertEquals($config['allow_credentials_in_request_body'], false);
$this->assertEquals($config['allow_public_clients'], false);
}
public function testRefreshTokenConfig()
{
// create mock storage
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server1 = new Server(array($storage));
$server2 = new Server(array($storage), array('always_issue_new_refresh_token' => true, 'unset_refresh_token_after_use' => false));
$server1->getTokenController();
$refreshToken1 = $server1->getGrantType('refresh_token');
$server2->getTokenController();
$refreshToken2 = $server2->getGrantType('refresh_token');
$reflection1 = new \ReflectionClass($refreshToken1);
$prop1 = $reflection1->getProperty('config');
$prop1->setAccessible(true);
$reflection2 = new \ReflectionClass($refreshToken2);
$prop2 = $reflection2->getProperty('config');
$prop2->setAccessible(true);
// get the private "config" property
$config1 = $prop1->getValue($refreshToken1);
$config2 = $prop2->getValue($refreshToken2);
$this->assertEquals($config1['always_issue_new_refresh_token'], false);
$this->assertEquals($config2['always_issue_new_refresh_token'], true);
$this->assertEquals($config1['unset_refresh_token_after_use'], true);
$this->assertEquals($config2['unset_refresh_token_after_use'], false);
}
/**
* Test setting "always_issue_new_refresh_token" on a server level
*
* @see test/OAuth2/GrantType/RefreshTokenTest::testValidRefreshTokenWithNewRefreshTokenInResponse
**/
public function testValidRefreshTokenWithNewRefreshTokenInResponse()
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, array('always_issue_new_refresh_token' => true));
$request = TestRequest::createPost(array(
'grant_type' => 'refresh_token', // valid grant type
'client_id' => 'Test Client ID', // valid client id
'client_secret' => 'TestSecret', // valid client secret
'refresh_token' => 'test-refreshtoken', // valid refresh token
));
$token = $server->grantAccessToken($request, new Response());
$this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
$refresh_token = $storage->getRefreshToken($token['refresh_token']);
$this->assertNotNull($refresh_token);
$this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
$this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
$this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
$used_token = $storage->getRefreshToken('test-refreshtoken');
$this->assertFalse($used_token, 'the refresh token used is no longer valid');
}
/**
* @expectedException InvalidArgumentException OAuth2\ResponseType\AuthorizationCodeInterface
**/
public function testAddingUnknownResponseTypeThrowsException()
{
$server = new Server();
$server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
}
/**
* @expectedException LogicException OAuth2\Storage\PublicKeyInterface
**/
public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
{
$server = new Server(array(), array('use_jwt_access_tokens' => true));
$server->addGrantType($this->getMock('OAuth2\GrantType\GrantTypeInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$this->assertNotNull($server->getResourceController());
$this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
}
/**
* @expectedException LogicException OAuth2\Storage\ClientInterface
**/
public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException grant_types
**/
public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$server->getTokenController();
}
public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
$this->assertNotNull($server->getAuthorizeController());
$this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
}
/**
* @expectedException LogicException UserClaims
**/
public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$server = new Server($client, array('use_openid_connect' => true));
$server->getAuthorizeController();
}
/**
* @expectedException LogicException PublicKeyInterface
**/
public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OPenID\Storage\UserClaimsInterface');
$server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
$server->getAuthorizeController();
}
/**
* @expectedException LogicException issuer
**/
public function testUsingOpenIDConnectWithoutIssuerThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
$server->getAuthorizeController();
}
public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
));
$server->getAuthorizeController();
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertNull($server->getResponseType('id_token token'));
}
/**
* @expectedException LogicException OAuth2\ResponseType\AccessTokenInterface
**/
public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
'allow_implicit' => true,
));
$server->getAuthorizeController();
}
public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
'allow_implicit' => true,
'use_jwt_access_tokens' => true,
));
$server->getAuthorizeController();
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
'allow_implicit' => true,
));
$server->getAuthorizeController();
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
// $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
'allow_implicit' => true,
));
$token = $this->getMock('OAuth2\ResponseType\AccessTokenInterface');
$server->addResponseType($token, 'token');
$server->getAuthorizeController();
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}
/**
* @expectedException LogicException OAuth2\OpenID\Storage\AuthorizationCodeInterface
**/
public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->getMock('OAuth2\Storage\AuthorizationCodeInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
'use_openid_connect' => true,
'issuer' => 'someguy'
));
$server->getTokenController();
$this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
}
public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
{
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->getMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
'use_openid_connect' => true,
'issuer' => 'someguy'
));
$server->getTokenController();
$this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
}
public function testMultipleValuedResponseTypeOrderDoesntMatter()
{
$responseType = $this->getMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
$server = new Server(array(), array(), array(), array(
'token id_token' => $responseType,
));
$this->assertEquals($responseType, $server->getResponseType('id_token token'));
}
public function testAddGrantTypeWithoutKey()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')));
$grantTypes = $server->getGrantTypes();
$this->assertEquals('authorization_code', key($grantTypes));
}
public function testAddGrantTypeWithKey()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
$grantTypes = $server->getGrantTypes();
$this->assertEquals('ac', key($grantTypes));
}
public function testAddGrantTypeWithKeyNotString()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
$grantTypes = $server->getGrantTypes();
$this->assertEquals('authorization_code', key($grantTypes));
}
}

View file

@ -0,0 +1,82 @@
<?php
namespace OAuth2\Storage;
class AccessTokenTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testSetAccessToken(AccessTokenInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// assert token we are about to add does not exist
$token = $storage->getAccessToken('newtoken');
$this->assertFalse($token);
// add new token
$expires = time() + 20;
$success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEUSERID', $expires);
$this->assertTrue($success);
$token = $storage->getAccessToken('newtoken');
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('client_id', $token);
$this->assertArrayHasKey('user_id', $token);
$this->assertArrayHasKey('expires', $token);
$this->assertEquals($token['access_token'], 'newtoken');
$this->assertEquals($token['client_id'], 'client ID');
$this->assertEquals($token['user_id'], 'SOMEUSERID');
$this->assertEquals($token['expires'], $expires);
// change existing token
$expires = time() + 42;
$success = $storage->setAccessToken('newtoken', 'client ID2', 'SOMEOTHERID', $expires);
$this->assertTrue($success);
$token = $storage->getAccessToken('newtoken');
$this->assertNotNull($token);
$this->assertArrayHasKey('access_token', $token);
$this->assertArrayHasKey('client_id', $token);
$this->assertArrayHasKey('user_id', $token);
$this->assertArrayHasKey('expires', $token);
$this->assertEquals($token['access_token'], 'newtoken');
$this->assertEquals($token['client_id'], 'client ID2');
$this->assertEquals($token['user_id'], 'SOMEOTHERID');
$this->assertEquals($token['expires'], $expires);
// add token with scope having an empty string value
$expires = time() + 42;
$success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEOTHERID', $expires, '');
$this->assertTrue($success);
}
/** @dataProvider provideStorage */
public function testUnsetAccessToken(AccessTokenInterface $storage)
{
if ($storage instanceof NullStorage || !method_exists($storage, 'unsetAccessToken')) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// assert token we are unset does not exist
$token = $storage->getAccessToken('revokabletoken');
$this->assertFalse($token);
// add new token
$expires = time() + 20;
$success = $storage->setAccessToken('revokabletoken', 'client ID', 'SOMEUSERID', $expires);
$this->assertTrue($success);
$storage->unsetAccessToken('revokabletoken');
// assert token we are unset does not exist
$token = $storage->getAccessToken('revokabletoken');
$this->assertFalse($token);
}
}

View file

@ -0,0 +1,106 @@
<?php
namespace OAuth2\Storage;
class AuthorizationCodeTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testGetAuthorizationCode(AuthorizationCodeInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// nonexistant client_id
$details = $storage->getAuthorizationCode('faketoken');
$this->assertFalse($details);
// valid client_id
$details = $storage->getAuthorizationCode('testtoken');
$this->assertNotNull($details);
}
/** @dataProvider provideStorage */
public function testSetAuthorizationCode(AuthorizationCodeInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// assert code we are about to add does not exist
$code = $storage->getAuthorizationCode('newcode');
$this->assertFalse($code);
// add new code
$expires = time() + 20;
$success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires);
$this->assertTrue($success);
$code = $storage->getAuthorizationCode('newcode');
$this->assertNotNull($code);
$this->assertArrayHasKey('authorization_code', $code);
$this->assertArrayHasKey('client_id', $code);
$this->assertArrayHasKey('user_id', $code);
$this->assertArrayHasKey('redirect_uri', $code);
$this->assertArrayHasKey('expires', $code);
$this->assertEquals($code['authorization_code'], 'newcode');
$this->assertEquals($code['client_id'], 'client ID');
$this->assertEquals($code['user_id'], 'SOMEUSERID');
$this->assertEquals($code['redirect_uri'], 'http://example.com');
$this->assertEquals($code['expires'], $expires);
// change existing code
$expires = time() + 42;
$success = $storage->setAuthorizationCode('newcode', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires);
$this->assertTrue($success);
$code = $storage->getAuthorizationCode('newcode');
$this->assertNotNull($code);
$this->assertArrayHasKey('authorization_code', $code);
$this->assertArrayHasKey('client_id', $code);
$this->assertArrayHasKey('user_id', $code);
$this->assertArrayHasKey('redirect_uri', $code);
$this->assertArrayHasKey('expires', $code);
$this->assertEquals($code['authorization_code'], 'newcode');
$this->assertEquals($code['client_id'], 'client ID2');
$this->assertEquals($code['user_id'], 'SOMEOTHERID');
$this->assertEquals($code['redirect_uri'], 'http://example.org');
$this->assertEquals($code['expires'], $expires);
// add new code with scope having an empty string value
$expires = time() + 20;
$success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, '');
$this->assertTrue($success);
}
/** @dataProvider provideStorage */
public function testExpireAccessToken(AccessTokenInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// create a valid code
$expires = time() + 20;
$success = $storage->setAuthorizationCode('code-to-expire', 'client ID', 'SOMEUSERID', 'http://example.com', time() + 20);
$this->assertTrue($success);
// verify the new code exists
$code = $storage->getAuthorizationCode('code-to-expire');
$this->assertNotNull($code);
$this->assertArrayHasKey('authorization_code', $code);
$this->assertEquals($code['authorization_code'], 'code-to-expire');
// now expire the code and ensure it's no longer available
$storage->expireAuthorizationCode('code-to-expire');
$code = $storage->getAuthorizationCode('code-to-expire');
$this->assertFalse($code);
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace OAuth2\Storage;
class ClientCredentialsTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testCheckClientCredentials(ClientCredentialsInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// nonexistant client_id
$pass = $storage->checkClientCredentials('fakeclient', 'testpass');
$this->assertFalse($pass);
// invalid password
$pass = $storage->checkClientCredentials('oauth_test_client', 'invalidcredentials');
$this->assertFalse($pass);
// valid credentials
$pass = $storage->checkClientCredentials('oauth_test_client', 'testpass');
$this->assertTrue($pass);
}
}

View file

@ -0,0 +1,87 @@
<?php
namespace OAuth2\Storage;
class ClientTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testGetClientDetails(ClientInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// nonexistant client_id
$details = $storage->getClientDetails('fakeclient');
$this->assertFalse($details);
// valid client_id
$details = $storage->getClientDetails('oauth_test_client');
$this->assertNotNull($details);
$this->assertArrayHasKey('client_id', $details);
$this->assertArrayHasKey('client_secret', $details);
$this->assertArrayHasKey('redirect_uri', $details);
}
/** @dataProvider provideStorage */
public function testCheckRestrictedGrantType(ClientInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// Check invalid
$pass = $storage->checkRestrictedGrantType('oauth_test_client', 'authorization_code');
$this->assertFalse($pass);
// Check valid
$pass = $storage->checkRestrictedGrantType('oauth_test_client', 'implicit');
$this->assertTrue($pass);
}
/** @dataProvider provideStorage */
public function testGetAccessToken(ClientInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// nonexistant client_id
$details = $storage->getAccessToken('faketoken');
$this->assertFalse($details);
// valid client_id
$details = $storage->getAccessToken('testtoken');
$this->assertNotNull($details);
}
/** @dataProvider provideStorage */
public function testSaveClient(ClientInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
$clientId = 'some-client-'.rand();
// create a new client
$success = $storage->setClientDetails($clientId, 'somesecret', 'http://test.com', 'client_credentials', 'clientscope1', 'brent@brentertainment.com');
$this->assertTrue($success);
// valid client_id
$details = $storage->getClientDetails($clientId);
$this->assertEquals($details['client_secret'], 'somesecret');
$this->assertEquals($details['redirect_uri'], 'http://test.com');
$this->assertEquals($details['grant_types'], 'client_credentials');
$this->assertEquals($details['scope'], 'clientscope1');
$this->assertEquals($details['user_id'], 'brent@brentertainment.com');
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace OAuth2\Storage;
class DynamoDBTest extends BaseTest
{
public function testGetDefaultScope()
{
$client = $this->getMockBuilder('\Aws\DynamoDb\DynamoDbClient')
->disableOriginalConstructor()
->setMethods(array('query'))
->getMock();
$return = $this->getMockBuilder('\Guzzle\Service\Resource\Model')
->setMethods(array('count', 'toArray'))
->getMock();
$data = array(
'Items' => array(),
'Count' => 0,
'ScannedCount'=> 0
);
$return->expects($this->once())
->method('count')
->will($this->returnValue(count($data)));
$return->expects($this->once())
->method('toArray')
->will($this->returnValue($data));
// should return null default scope if none is set in database
$client->expects($this->once())
->method('query')
->will($this->returnValue($return));
$storage = new DynamoDB($client);
$this->assertNull($storage->getDefaultScope());
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace OAuth2\Storage;
use OAuth2\Encryption\Jwt;
class JwtAccessTokenTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testSetAccessToken($storage)
{
if (!$storage instanceof PublicKey) {
// incompatible storage
return;
}
$crypto = new jwtAccessToken($storage);
$publicKeyStorage = Bootstrap::getInstance()->getMemoryStorage();
$encryptionUtil = new Jwt();
$jwtAccessToken = array(
'access_token' => rand(),
'expires' => time() + 100,
'scope' => 'foo',
);
$token = $encryptionUtil->encode($jwtAccessToken, $storage->getPrivateKey(), $storage->getEncryptionAlgorithm());
$this->assertNotNull($token);
$tokenData = $crypto->getAccessToken($token);
$this->assertTrue(is_array($tokenData));
/* assert the decoded token is the same */
$this->assertEquals($tokenData['access_token'], $jwtAccessToken['access_token']);
$this->assertEquals($tokenData['expires'], $jwtAccessToken['expires']);
$this->assertEquals($tokenData['scope'], $jwtAccessToken['scope']);
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace OAuth2\Storage;
class JwtBearerTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testGetClientKey(JwtBearerInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// nonexistant client_id
$key = $storage->getClientKey('this-is-not-real', 'nor-is-this');
$this->assertFalse($key);
// valid client_id and subject
$key = $storage->getClientKey('oauth_test_client', 'test_subject');
$this->assertNotNull($key);
$this->assertEquals($key, Bootstrap::getInstance()->getTestPublicKey());
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace OAuth2\Storage;
class PdoTest extends BaseTest
{
public function testCreatePdoStorageUsingPdoClass()
{
$pdo = new \PDO(sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir()));
$storage = new Pdo($pdo);
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
}
public function testCreatePdoStorageUsingDSN()
{
$dsn = sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir());
$storage = new Pdo($dsn);
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
}
public function testCreatePdoStorageUsingConfig()
{
$config = array('dsn' => sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir()));
$storage = new Pdo($config);
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
}
/**
* @expectedException InvalidArgumentException dsn
*/
public function testCreatePdoStorageWithoutDSNThrowsException()
{
$config = array('username' => 'brent', 'password' => 'brentisaballer');
$storage = new Pdo($config);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace OAuth2\Storage;
class PublicKeyTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testSetAccessToken($storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
if (!$storage instanceof PublicKeyInterface) {
// incompatible storage
return;
}
$configDir = Bootstrap::getInstance()->getConfigDir();
$globalPublicKey = file_get_contents($configDir.'/keys/id_rsa.pub');
$globalPrivateKey = file_get_contents($configDir.'/keys/id_rsa');
/* assert values from storage */
$this->assertEquals($storage->getPublicKey(), $globalPublicKey);
$this->assertEquals($storage->getPrivateKey(), $globalPrivateKey);
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace OAuth2\Storage;
class RefreshTokenTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testSetRefreshToken(RefreshTokenInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// assert token we are about to add does not exist
$token = $storage->getRefreshToken('refreshtoken');
$this->assertFalse($token);
// add new token
$expires = time() + 20;
$success = $storage->setRefreshToken('refreshtoken', 'client ID', 'SOMEUSERID', $expires);
$this->assertTrue($success);
$token = $storage->getRefreshToken('refreshtoken');
$this->assertNotNull($token);
$this->assertArrayHasKey('refresh_token', $token);
$this->assertArrayHasKey('client_id', $token);
$this->assertArrayHasKey('user_id', $token);
$this->assertArrayHasKey('expires', $token);
$this->assertEquals($token['refresh_token'], 'refreshtoken');
$this->assertEquals($token['client_id'], 'client ID');
$this->assertEquals($token['user_id'], 'SOMEUSERID');
$this->assertEquals($token['expires'], $expires);
// add token with scope having an empty string value
$expires = time() + 20;
$success = $storage->setRefreshToken('refreshtoken2', 'client ID', 'SOMEUSERID', $expires, '');
$this->assertTrue($success);
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace OAuth2\Storage;
use OAuth2\Scope;
class ScopeTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testScopeExists($storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
if (!$storage instanceof ScopeInterface) {
// incompatible storage
return;
}
//Test getting scopes
$scopeUtil = new Scope($storage);
$this->assertTrue($scopeUtil->scopeExists('supportedscope1'));
$this->assertTrue($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3'));
$this->assertFalse($scopeUtil->scopeExists('fakescope'));
$this->assertFalse($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3 fakescope'));
}
/** @dataProvider provideStorage */
public function testGetDefaultScope($storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
if (!$storage instanceof ScopeInterface) {
// incompatible storage
return;
}
// test getting default scope
$scopeUtil = new Scope($storage);
$expected = explode(' ', $scopeUtil->getDefaultScope());
$actual = explode(' ', 'defaultscope1 defaultscope2');
sort($expected);
sort($actual);
$this->assertEquals($expected, $actual);
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace OAuth2\Storage;
class UserCredentialsTest extends BaseTest
{
/** @dataProvider provideStorage */
public function testCheckUserCredentials(UserCredentialsInterface $storage)
{
if ($storage instanceof NullStorage) {
$this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
return;
}
// create a new user for testing
$success = $storage->setUser('testusername', 'testpass', 'Test', 'User');
$this->assertTrue($success);
// correct credentials
$this->assertTrue($storage->checkUserCredentials('testusername', 'testpass'));
// invalid password
$this->assertFalse($storage->checkUserCredentials('testusername', 'fakepass'));
// invalid username
$this->assertFalse($storage->checkUserCredentials('fakeusername', 'testpass'));
// invalid username
$this->assertFalse($storage->getUserDetails('fakeusername'));
// ensure all properties are set
$user = $storage->getUserDetails('testusername');
$this->assertTrue($user !== false);
$this->assertArrayHasKey('user_id', $user);
$this->assertArrayHasKey('first_name', $user);
$this->assertArrayHasKey('last_name', $user);
$this->assertEquals($user['user_id'], 'testusername');
$this->assertEquals($user['first_name'], 'Test');
$this->assertEquals($user['last_name'], 'User');
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace OAuth2\TokenType;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
class BearerTest extends \PHPUnit_Framework_TestCase
{
public function testValidContentTypeWithCharset()
{
$bearer = new Bearer();
$request = TestRequest::createPost(array(
'access_token' => 'ThisIsMyAccessToken'
));
$request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
$this->assertEquals($param, 'ThisIsMyAccessToken');
}
public function testInvalidContentType()
{
$bearer = new Bearer();
$request = TestRequest::createPost(array(
'access_token' => 'ThisIsMyAccessToken'
));
$request->server['CONTENT_TYPE'] = 'application/json; charset=UTF-8';
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
$this->assertNull($param);
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_request');
$this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
}
public function testValidRequestUsingAuthorizationHeader()
{
$bearer = new Bearer();
$request = new TestRequest();
$request->headers['AUTHORIZATION'] = 'Bearer MyToken';
$request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
$this->assertEquals('MyToken', $param);
}
public function testValidRequestUsingAuthorizationHeaderCaseInsensitive()
{
$bearer = new Bearer();
$request = new TestRequest();
$request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
$request->headers['Authorization'] = 'Bearer MyToken';
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
$this->assertEquals('MyToken', $param);
}
}