summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/OAuth2/Controller/AuthorizeControllerTest.php6
-rw-r--r--test/OAuth2/Controller/ResourceControllerTest.php4
-rw-r--r--test/OAuth2/Controller/TokenControllerTest.php2
-rw-r--r--test/OAuth2/GrantType/UserCredentialsTest.php1
-rw-r--r--test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php156
-rw-r--r--test/OAuth2/OpenID/Controller/UserInfoControllerTest.php14
-rw-r--r--test/OAuth2/OpenID/ResponseType/TokenIdTokenTest.php2
-rw-r--r--test/OAuth2/ResponseTest.php2
-rw-r--r--test/OAuth2/ResponseType/CryptoTokenTest.php43
-rw-r--r--test/OAuth2/ScopeTest.php1
-rw-r--r--test/OAuth2/ServerTest.php28
-rw-r--r--test/OAuth2/Storage/PdoTest.php2
-rw-r--r--test/OAuth2/Storage/ScopeTest.php6
-rw-r--r--test/cleanup.php15
-rw-r--r--test/config/storage.json2
-rw-r--r--test/lib/OAuth2/Storage/BaseTest.php6
-rw-r--r--test/lib/OAuth2/Storage/Bootstrap.php421
-rw-r--r--test/lib/OAuth2/Storage/NullStorage.php2
18 files changed, 672 insertions, 41 deletions
diff --git a/test/OAuth2/Controller/AuthorizeControllerTest.php b/test/OAuth2/Controller/AuthorizeControllerTest.php
index 1bce0ef..c2745d6 100644
--- a/test/OAuth2/Controller/AuthorizeControllerTest.php
+++ b/test/OAuth2/Controller/AuthorizeControllerTest.php
@@ -203,7 +203,7 @@ class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
$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',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true',
'state' => 'xyz',
));
@@ -221,7 +221,7 @@ class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
$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&hereisa=querystring',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
));
$server->handleAuthorizeRequest($request, $response = new Response(), true);
@@ -239,7 +239,7 @@ class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
$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&hereisa=querystring',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
'state' => 'xyz',
));
diff --git a/test/OAuth2/Controller/ResourceControllerTest.php b/test/OAuth2/Controller/ResourceControllerTest.php
index fb25550..ee6d96f 100644
--- a/test/OAuth2/Controller/ResourceControllerTest.php
+++ b/test/OAuth2/Controller/ResourceControllerTest.php
@@ -100,7 +100,7 @@ class ResourceControllerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'invalid_token');
+ $this->assertEquals($response->getParameter('error'), 'expired_token');
$this->assertEquals($response->getParameter('error_description'), 'The access token provided has expired');
}
@@ -132,7 +132,7 @@ class ResourceControllerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($allow);
$this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'invalid_token');
+ $this->assertEquals($response->getParameter('error'), 'malformed_token');
$this->assertEquals($response->getParameter('error_description'), 'Malformed token (missing "expires")');
}
diff --git a/test/OAuth2/Controller/TokenControllerTest.php b/test/OAuth2/Controller/TokenControllerTest.php
index f41a95c..d53181d 100644
--- a/test/OAuth2/Controller/TokenControllerTest.php
+++ b/test/OAuth2/Controller/TokenControllerTest.php
@@ -11,7 +11,7 @@ use OAuth2\Scope;
use OAuth2\Request\TestRequest;
use OAuth2\Response;
-class Controller_TokenControllerTest extends \PHPUnit_Framework_TestCase
+class TokenControllerTest extends \PHPUnit_Framework_TestCase
{
public function testNoGrantType()
{
diff --git a/test/OAuth2/GrantType/UserCredentialsTest.php b/test/OAuth2/GrantType/UserCredentialsTest.php
index 447caf5..18943d0 100644
--- a/test/OAuth2/GrantType/UserCredentialsTest.php
+++ b/test/OAuth2/GrantType/UserCredentialsTest.php
@@ -138,7 +138,6 @@ class UserCredentialsTest extends \PHPUnit_Framework_TestCase
'password' => 'testpass', // valid password
));
-
$token = $server->grantAccessToken($request, $response = new Response());
$this->assertNotNull($token);
diff --git a/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php b/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
new file mode 100644
index 0000000..4b217c5
--- /dev/null
+++ b/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace OAuth2\OpenID\Controller;
+
+use OAuth2\OpenID\Controller\AuthorizeController;
+use OAuth2\OpenID\ResponseType\IdToken;
+use OAuth2\OpenID\ResponseType\TokenIdToken;
+use OAuth2\ResponseType\AccessToken;
+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'] = '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' response type
+ $request->query['response_type'] = 'token id_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' => 'anzev',
+ 'allow_implicit' => true
+ );
+
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ return $server;
+ }
+}
diff --git a/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php b/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
index 939b715..90fdd0b 100644
--- a/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
+++ b/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
@@ -2,14 +2,25 @@
namespace OAuth2\OpenID\Controller;
+use OAuth2\OpenID\Controller\UserInfoController;
use OAuth2\Storage\Bootstrap;
use OAuth2\Server;
-use OAuth2\GrantType\AuthorizationCode;
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();
@@ -28,6 +39,7 @@ class UserInfoControllerTest extends \PHPUnit_Framework_TestCase
{
$storage = Bootstrap::getInstance()->getMemoryStorage();
$server = new Server($storage, $config);
+
return $server;
}
}
diff --git a/test/OAuth2/OpenID/ResponseType/TokenIdTokenTest.php b/test/OAuth2/OpenID/ResponseType/TokenIdTokenTest.php
index 488eb08..f687cff 100644
--- a/test/OAuth2/OpenID/ResponseType/TokenIdTokenTest.php
+++ b/test/OAuth2/OpenID/ResponseType/TokenIdTokenTest.php
@@ -50,7 +50,7 @@ class TokenIdTokenTest extends \PHPUnit_Framework_TestCase
// Each part is a base64url encoded json string.
$part = str_replace(array('-', '_'), array('+', '/'), $part);
$part = base64_decode($part);
- $part = json_decode($part, TRUE);
+ $part = json_decode($part, true);
}
list($header, $claims, $signature) = $parts;
diff --git a/test/OAuth2/ResponseTest.php b/test/OAuth2/ResponseTest.php
index c36156f..b814900 100644
--- a/test/OAuth2/ResponseTest.php
+++ b/test/OAuth2/ResponseTest.php
@@ -12,6 +12,6 @@ class ResponseTest extends \PHPUnit_Framework_TestCase
));
$string = $response->getResponseBody('xml');
- $this->assertContains('<response><bar>foo</bar><oates>halland</oates></response>', $string);
+ $this->assertContains('<response><foo>bar</foo><halland>oates</halland></response>', $string);
}
}
diff --git a/test/OAuth2/ResponseType/CryptoTokenTest.php b/test/OAuth2/ResponseType/CryptoTokenTest.php
index 560890b..d1ab89e 100644
--- a/test/OAuth2/ResponseType/CryptoTokenTest.php
+++ b/test/OAuth2/ResponseType/CryptoTokenTest.php
@@ -8,6 +8,8 @@ use OAuth2\Request\TestRequest;
use OAuth2\Storage\Bootstrap;
use OAuth2\Storage\CryptoToken as CryptoTokenStorage;
use OAuth2\GrantType\ClientCredentials;
+use OAuth2\GrantType\UserCredentials;
+use OAuth2\GrantType\RefreshToken;
class CryptoTokenTest extends \PHPUnit_Framework_TestCase
{
@@ -69,6 +71,47 @@ class CryptoTokenTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($resourceServer->verifyResourceRequest($request));
}
+ public function testCryptoTokenWithRefreshToken()
+ {
+ $server = $this->getTestServer();
+
+ // add "UserCredentials" grant type and "CryptoToken" response type
+ // and ensure "CryptoToken" response type has "RefreshToken" storage
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+ $server->addGrantType(new UserCredentials($memoryStorage));
+ $server->addGrantType(new RefreshToken($memoryStorage));
+ $server->addResponseType(new CryptoToken($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($cryptoToken = $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('.', $cryptoToken);
+ $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();
diff --git a/test/OAuth2/ScopeTest.php b/test/OAuth2/ScopeTest.php
index 00ec7b6..99f9cf6 100644
--- a/test/OAuth2/ScopeTest.php
+++ b/test/OAuth2/ScopeTest.php
@@ -3,7 +3,6 @@
namespace OAuth2;
use OAuth2\Storage\Memory;
-use OAuth2\Storage\Bootstrap;
class ScopeTest extends \PHPUnit_Framework_TestCase
{
diff --git a/test/OAuth2/ServerTest.php b/test/OAuth2/ServerTest.php
index d3c8069..fd824fc 100644
--- a/test/OAuth2/ServerTest.php
+++ b/test/OAuth2/ServerTest.php
@@ -389,6 +389,34 @@ class ServerTest extends \PHPUnit_Framework_TestCase
}
/**
+ * 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()
diff --git a/test/OAuth2/Storage/PdoTest.php b/test/OAuth2/Storage/PdoTest.php
index f6c0549..57eb390 100644
--- a/test/OAuth2/Storage/PdoTest.php
+++ b/test/OAuth2/Storage/PdoTest.php
@@ -2,8 +2,6 @@
namespace OAuth2\Storage;
-use OAuth2\Encryption\Jwt;
-
class PdoTest extends BaseTest
{
public function testCreatePdoStorageUsingPdoClass()
diff --git a/test/OAuth2/Storage/ScopeTest.php b/test/OAuth2/Storage/ScopeTest.php
index 2f7a588..fd1edeb 100644
--- a/test/OAuth2/Storage/ScopeTest.php
+++ b/test/OAuth2/Storage/ScopeTest.php
@@ -44,6 +44,10 @@ class ScopeTest extends BaseTest
// test getting default scope
$scopeUtil = new Scope($storage);
- $this->assertEquals($scopeUtil->getDefaultScope(), 'defaultscope1 defaultscope2');
+ $expected = explode(' ', $scopeUtil->getDefaultScope());
+ $actual = explode(' ', 'defaultscope1 defaultscope2');
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual);
}
}
diff --git a/test/cleanup.php b/test/cleanup.php
new file mode 100644
index 0000000..4042eb2
--- /dev/null
+++ b/test/cleanup.php
@@ -0,0 +1,15 @@
+<?php
+
+require_once(dirname(__FILE__).'/../src/OAuth2/Autoloader.php');
+OAuth2\Autoloader::register();
+
+// register test classes
+OAuth2\Autoloader::register(dirname(__FILE__).'/lib');
+
+// register vendors if possible
+if (file_exists(__DIR__.'/../vendor/autoload.php')) {
+ require_once(__DIR__.'/../vendor/autoload.php');
+}
+
+// remove the dynamoDB database that was created for this build
+OAuth2\Storage\Bootstrap::getInstance()->cleanupTravisDynamoDb(); \ No newline at end of file
diff --git a/test/config/storage.json b/test/config/storage.json
index 82a7924..2d43c07 100644
--- a/test/config/storage.json
+++ b/test/config/storage.json
@@ -48,7 +48,7 @@
},
"Test Client ID with Redirect Uri Parts": {
"client_secret": "TestSecret4",
- "redirect_uri": "http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth"
+ "redirect_uri": "http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true"
},
"Test Some Other Client": {
"client_secret": "TestSecret3"
diff --git a/test/lib/OAuth2/Storage/BaseTest.php b/test/lib/OAuth2/Storage/BaseTest.php
index f7de3c7..579997c 100644
--- a/test/lib/OAuth2/Storage/BaseTest.php
+++ b/test/lib/OAuth2/Storage/BaseTest.php
@@ -6,13 +6,14 @@ abstract class BaseTest extends \PHPUnit_Framework_TestCase
{
public function provideStorage()
{
+ $memory = Bootstrap::getInstance()->getMemoryStorage();
+ $sqlite = Bootstrap::getInstance()->getSqlitePdo();
$mysql = Bootstrap::getInstance()->getMysqlPdo();
$postgres = Bootstrap::getInstance()->getPostgresPdo();
- $sqlite = Bootstrap::getInstance()->getSqlitePdo();
$mongo = Bootstrap::getInstance()->getMongo();
$redis = Bootstrap::getInstance()->getRedisStorage();
$cassandra = Bootstrap::getInstance()->getCassandraStorage();
- $memory = Bootstrap::getInstance()->getMemoryStorage();
+ $dynamodb = Bootstrap::getInstance()->getDynamoDbStorage();
/* hack until we can fix "default_scope" dependencies in other tests */
$memory->defaultScope = 'defaultscope1 defaultscope2';
@@ -25,6 +26,7 @@ abstract class BaseTest extends \PHPUnit_Framework_TestCase
array($mongo),
array($redis),
array($cassandra),
+ array($dynamodb),
);
}
}
diff --git a/test/lib/OAuth2/Storage/Bootstrap.php b/test/lib/OAuth2/Storage/Bootstrap.php
index 8d7fe0d..129ca2f 100644
--- a/test/lib/OAuth2/Storage/Bootstrap.php
+++ b/test/lib/OAuth2/Storage/Bootstrap.php
@@ -4,6 +4,8 @@ namespace OAuth2\Storage;
class Bootstrap
{
+ const DYNAMODB_PHP_VERSION = '5.5';
+
protected static $instance;
private $mysql;
private $sqlite;
@@ -12,6 +14,7 @@ class Bootstrap
private $redis;
private $cassandra;
private $configDir;
+ private $dynamodb;
public function __construct()
{
@@ -51,8 +54,6 @@ class Bootstrap
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->populatePostgresDb($pdo);
$this->postgres = new Pdo($pdo);
- } else {
- $this->postgres = new NullStorage('Postgres', 'Unable to connect to postgres on localhost with user "postgres"');
}
} else {
$this->postgres = new NullStorage('Postgres', 'Missing postgres PDO extension.');
@@ -69,7 +70,7 @@ class Bootstrap
return $pdo;
} catch (\PDOException $e) {
- exit($e->getMessage());
+ $this->postgres = new NullStorage('Postgres', $e->getMessage());
}
}
@@ -113,12 +114,20 @@ class Bootstrap
public function getMysqlPdo()
{
if (!$this->mysql) {
- $pdo = new \PDO('mysql:host=localhost;', 'root');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
- $this->removeMysqlDb($pdo);
- $this->createMysqlDb($pdo);
+ $pdo = null;
+ try {
+ $pdo = new \PDO('mysql:host=localhost;', 'root');
+ } catch (\PDOException $e) {
+ $this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
+ }
- $this->mysql = new Pdo($pdo);
+ if ($pdo) {
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $this->removeMysqlDb($pdo);
+ $this->createMysqlDb($pdo);
+
+ $this->mysql = new Pdo($pdo);
+ }
}
return $this->mysql;
@@ -127,7 +136,7 @@ class Bootstrap
public function getMongo()
{
if (!$this->mongo) {
- $skipMongo = isset($_SERVER['SKIP_MONGO_TESTS']) && $_SERVER['SKIP_MONGO_TESTS'];
+ $skipMongo = $this->getEnvVar('SKIP_MONGO_TESTS');
if (!$skipMongo && class_exists('MongoClient')) {
$mongo = new \MongoClient('mongodb://localhost:27017', array('connect' => false));
if ($this->testMongoConnection($mongo)) {
@@ -277,14 +286,10 @@ class Bootstrap
public function runPdoSql(\PDO $pdo)
{
- $pdo->exec('CREATE TABLE oauth_clients (client_id TEXT, client_secret TEXT, redirect_uri TEXT, grant_types TEXT, scope TEXT, user_id TEXT, public_key TEXT)');
- $pdo->exec('CREATE TABLE oauth_access_tokens (access_token TEXT, client_id TEXT, user_id TEXT, expires TIMESTAMP, scope TEXT)');
- $pdo->exec('CREATE TABLE oauth_authorization_codes (authorization_code TEXT, client_id TEXT, user_id TEXT, redirect_uri TEXT, expires TIMESTAMP, scope TEXT, id_token TEXT)');
- $pdo->exec('CREATE TABLE oauth_users (username TEXT, password TEXT, first_name TEXT, last_name TEXT, scope TEXT, email TEXT, email_verified BOOLEAN)');
- $pdo->exec('CREATE TABLE oauth_refresh_tokens (refresh_token TEXT, client_id TEXT, user_id TEXT, expires TIMESTAMP, scope TEXT)');
- $pdo->exec('CREATE TABLE oauth_scopes (scope TEXT, is_default BOOLEAN)');
- $pdo->exec('CREATE TABLE oauth_public_keys (client_id TEXT, public_key TEXT, private_key TEXT, encryption_algorithm VARCHAR(100) DEFAULT \'RS256\')');
- $pdo->exec('CREATE TABLE oauth_jwt (client_id VARCHAR(80), subject VARCHAR(80), public_key VARCHAR(2000))');
+ $storage = new Pdo($pdo);
+ foreach (explode(';', $storage->getBuildSql()) as $statement) {
+ $result = $pdo->exec($statement);
+ }
// set up scopes
$sql = 'INSERT INTO oauth_scopes (scope) VALUES (?)';
@@ -305,12 +310,12 @@ class Bootstrap
$pdo->prepare($sql)->execute(array('oauth_test_client', 'testpass', null, 'implicit password'));
// set up misc
- $sql = 'INSERT INTO oauth_access_tokens (access_token, client_id, user_id) VALUES (?, ?, ?)';
- $pdo->prepare($sql)->execute(array('testtoken', 'Some Client', null));
- $pdo->prepare($sql)->execute(array('accesstoken-openid-connect', 'Some Client', 'testuser'));
+ $sql = 'INSERT INTO oauth_access_tokens (access_token, client_id, expires, user_id) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('testtoken', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), null));
+ $pdo->prepare($sql)->execute(array('accesstoken-openid-connect', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), 'testuser'));
- $sql = 'INSERT INTO oauth_authorization_codes (authorization_code, client_id) VALUES (?, ?)';
- $pdo->prepare($sql)->execute(array('testcode', 'Some Client'));
+ $sql = 'INSERT INTO oauth_authorization_codes (authorization_code, client_id, expires) VALUES (?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('testcode', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour'))));
$sql = 'INSERT INTO oauth_users (username, password, email, email_verified) VALUES (?, ?, ?, ?)';
$pdo->prepare($sql)->execute(array('testuser', 'password', 'testuser@test.com', true));
@@ -326,7 +331,6 @@ class Bootstrap
$pdo->prepare($sql)->execute(array('oauth_test_client', 'test_subject', $this->getTestPublicKey()));
}
-
public function getSqliteDir()
{
return $this->configDir. '/test.sqlite';
@@ -407,4 +411,375 @@ class Bootstrap
{
return file_get_contents(__DIR__.'/../../../config/keys/id_rsa');
}
+
+ public function getDynamoDbStorage()
+ {
+ if (!$this->dynamodb) {
+ // only run once per travis build
+ if (true == $this->getEnvVar('TRAVIS')) {
+ if (self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'Skipping for travis.ci - only run once per build');
+
+ return;
+ }
+ }
+ if (class_exists('\Aws\DynamoDb\DynamoDbClient')) {
+ if ($client = $this->getDynamoDbClient()) {
+ // travis runs a unique set of tables per build, to avoid conflict
+ $prefix = '';
+ if ($build_id = $this->getEnvVar('TRAVIS_JOB_NUMBER')) {
+ $prefix = sprintf('build_%s_', $build_id);
+ } else {
+ if (!$this->deleteDynamoDb($client, $prefix, true)) {
+ return $this->dynamodb = new NullStorage('DynamoDb', 'Timed out while waiting for DynamoDB deletion (30 seconds)');
+ }
+ }
+ $this->createDynamoDb($client, $prefix);
+ $this->populateDynamoDb($client, $prefix);
+ $config = array(
+ 'client_table' => $prefix.'oauth_clients',
+ 'access_token_table' => $prefix.'oauth_access_tokens',
+ 'refresh_token_table' => $prefix.'oauth_refresh_tokens',
+ 'code_table' => $prefix.'oauth_authorization_codes',
+ 'user_table' => $prefix.'oauth_users',
+ 'jwt_table' => $prefix.'oauth_jwt',
+ 'scope_table' => $prefix.'oauth_scopes',
+ 'public_key_table' => $prefix.'oauth_public_keys',
+ );
+ $this->dynamodb = new DynamoDB($client, $config);
+ } elseif (!$this->dynamodb) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'unable to connect to DynamoDB');
+ }
+ } else {
+ $this->dynamodb = new NullStorage('DynamoDb', 'Missing DynamoDB library. Please run "composer.phar require aws/aws-sdk-php:dev-master');
+ }
+ }
+
+ return $this->dynamodb;
+ }
+
+ private function getDynamoDbClient()
+ {
+ $config = array();
+ // check for environment variables
+ if (($key = $this->getEnvVar('AWS_ACCESS_KEY_ID')) && ($secret = $this->getEnvVar('AWS_SECRET_KEY'))) {
+ $config['key'] = $key;
+ $config['secret'] = $secret;
+ } else {
+ // fall back on ~/.aws/credentials file
+ // @see http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#credential-profiles
+ if (!file_exists($this->getEnvVar('HOME') . '/.aws/credentials')) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'No aws credentials file found, and no AWS_ACCESS_KEY_ID or AWS_SECRET_KEY environment variable set');
+
+ return;
+ }
+
+ // set profile in AWS_PROFILE environment variable, defaults to "default"
+ $config['profile'] = $this->getEnvVar('AWS_PROFILE', 'default');
+ }
+
+ // set region in AWS_REGION environment variable, defaults to "us-east-1"
+ $config['region'] = $this->getEnvVar('AWS_REGION', \Aws\Common\Enum\Region::US_EAST_1);
+
+ return \Aws\DynamoDb\DynamoDbClient::factory($config);
+ }
+
+ private function deleteDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null, $waitForDeletion = false)
+ {
+ $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
+ $nbTables = count($tablesList);
+
+ // Delete all table.
+ foreach ($tablesList as $key => $table) {
+ try {
+ $client->deleteTable(array('TableName' => $prefix.$table));
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ }
+ }
+
+ // Wait for deleting
+ if ($waitForDeletion) {
+ $retries = 5;
+ $nbTableDeleted = 0;
+ while ($nbTableDeleted != $nbTables) {
+ $nbTableDeleted = 0;
+ foreach ($tablesList as $key => $table) {
+ try {
+ $result = $client->describeTable(array('TableName' => $prefix.$table));
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ $nbTableDeleted++;
+ }
+ }
+ if ($nbTableDeleted != $nbTables) {
+ if ($retries < 0) {
+ // we are tired of waiting
+ return false;
+ }
+ sleep(5);
+ echo "Sleeping 5 seconds for DynamoDB ($retries more retries)...\n";
+ $retries--;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private function createDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null)
+ {
+ $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
+ $nbTables = count($tablesList);
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'access_token','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'access_token','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_authorization_codes',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'authorization_code','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'authorization_code','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_jwt',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S'),
+ array('AttributeName' => 'subject','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(
+ array('AttributeName' => 'client_id','KeyType' => 'HASH'),
+ array('AttributeName' => 'subject','KeyType' => 'RANGE')
+ ),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_refresh_tokens',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'refresh_token','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'refresh_token','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'scope','AttributeType' => 'S'),
+ array('AttributeName' => 'is_default','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'scope','KeyType' => 'HASH')),
+ 'GlobalSecondaryIndexes' => array(
+ array(
+ 'IndexName' => 'is_default-index',
+ 'KeySchema' => array(array('AttributeName' => 'is_default', 'KeyType' => 'HASH')),
+ 'Projection' => array('ProjectionType' => 'ALL'),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ),
+ ),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_users',
+ 'AttributeDefinitions' => array(array('AttributeName' => 'username','AttributeType' => 'S')),
+ 'KeySchema' => array(array('AttributeName' => 'username','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ // Wait for creation
+ $nbTableCreated = 0;
+ while ($nbTableCreated != $nbTables) {
+ $nbTableCreated = 0;
+ foreach ($tablesList as $key => $table) {
+ try {
+ $result = $client->describeTable(array('TableName' => $prefix.$table));
+ if ($result['Table']['TableStatus'] == 'ACTIVE') {
+ $nbTableCreated++;
+ }
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ $nbTableCreated++;
+ }
+ }
+ if ($nbTableCreated != $nbTables) {
+ sleep(1);
+ }
+ }
+ }
+
+ private function populateDynamoDb($client, $prefix = null)
+ {
+ // set up scopes
+ foreach (explode(' ', 'supportedscope1 supportedscope2 supportedscope3 supportedscope4 clientscope1 clientscope2 clientscope3') as $supportedScope) {
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'Item' => array('scope' => array('S' => $supportedScope))
+ ));
+ }
+
+ foreach (array('defaultscope1', 'defaultscope2') as $defaultScope) {
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'Item' => array('scope' => array('S' => $defaultScope), 'is_default' => array('S' => "true"))
+ ));
+ }
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Client ID'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Client ID 2'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2 clientscope3')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Default Scope Client ID'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'oauth_test_client'),
+ 'client_secret' => array('S' => 'testpass'),
+ 'grant_types' => array('S' => 'implicit password')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'Item' => array(
+ 'access_token' => array('S' => 'testtoken'),
+ 'client_id' => array('S' => 'Some Client'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'Item' => array(
+ 'access_token' => array('S' => 'accesstoken-openid-connect'),
+ 'client_id' => array('S' => 'Some Client'),
+ 'user_id' => array('S' => 'testuser'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_authorization_codes',
+ 'Item' => array(
+ 'authorization_code' => array('S' => 'testcode'),
+ 'client_id' => array('S' => 'Some Client'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_users',
+ 'Item' => array(
+ 'username' => array('S' => 'testuser'),
+ 'password' => array('S' => 'password'),
+ 'email' => array('S' => 'testuser@test.com'),
+ 'email_verified' => array('S' => 'true'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => 'ClientID_One'),
+ 'public_key' => array('S' => 'client_1_public'),
+ 'private_key' => array('S' => 'client_1_private'),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => 'ClientID_Two'),
+ 'public_key' => array('S' => 'client_2_public'),
+ 'private_key' => array('S' => 'client_2_private'),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => '0'),
+ 'public_key' => array('S' => $this->getTestPublicKey()),
+ 'private_key' => array('S' => $this->getTestPrivateKey()),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_jwt',
+ 'Item' => array(
+ 'client_id' => array('S' => 'oauth_test_client'),
+ 'subject' => array('S' => 'test_subject'),
+ 'public_key' => array('S' => $this->getTestPublicKey()),
+ )
+ ));
+ }
+
+ public function cleanupTravisDynamoDb($prefix = null)
+ {
+ if (is_null($prefix)) {
+ // skip this when not applicable
+ if (!$this->getEnvVar('TRAVIS') || self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
+ return;
+ }
+
+ $prefix = sprintf('build_%s_', $this->getEnvVar('TRAVIS_JOB_NUMBER'));
+ }
+
+ $client = $this->getDynamoDbClient();
+ $this->deleteDynamoDb($client, $prefix);
+ }
+
+ private function getEnvVar($var, $default = null)
+ {
+ return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
+ }
}
diff --git a/test/lib/OAuth2/Storage/NullStorage.php b/test/lib/OAuth2/Storage/NullStorage.php
index 46a200c..6caa620 100644
--- a/test/lib/OAuth2/Storage/NullStorage.php
+++ b/test/lib/OAuth2/Storage/NullStorage.php
@@ -29,4 +29,4 @@ class NullStorage extends Memory
return $this->name;
}
-} \ No newline at end of file
+}