Skip to content

Commit

Permalink
makes suggested improvements on @bojanz PR and adds tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bshaffer committed Jan 30, 2014
1 parent 90b9d0b commit 2fb46d6
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 42 deletions.
112 changes: 72 additions & 40 deletions src/OAuth2/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ class Server implements ResourceControllerInterface,
*/
public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), TokenTypeInterface $tokenType = null, ScopeInterface $scopeUtil = null, ClientAssertionTypeInterface $clientAssertionType = null)
{
$storage = is_array($storage) ? $storage : array($storage);
$this->storages = array();
foreach ($storage as $key => $service) {
$this->addStorage($service, $key);
}

// merge all config values. These get passed to our controller objects
$this->config = array_merge(array(
'use_crypto_tokens' => false,
Expand All @@ -106,15 +112,6 @@ public function __construct($storage = array(), array $config = array(), array $
'always_issue_new_refresh_token' => false,
), $config);

$storage = is_array($storage) ? $storage : array($storage);
$this->storages = array();
foreach ($storage as $key => $service) {
$this->addStorage($service, $key);
}
if (!empty($this->config['use_crypto_tokens'])) {
$this->createDefaultCryptoTokenStorage();
}

foreach ($grantTypes as $key => $grantType) {
$this->addGrantType($grantType, $key);
}
Expand Down Expand Up @@ -341,19 +338,6 @@ public function addStorage($storage, $key = null)
}
}

protected function createDefaultCryptoTokenStorage()
{
if (!isset($this->storages['public_key'])) {
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
}
$tokenStorage = null;
if (!empty($this->config['store_encrypted_token_string']) && isset($this->storages['access_token'])) {
$tokenStorage = $this->storages['access_token'];
}
// wrap the access token storage as required.
$this->storages['access_token'] = new CryptoTokenStorage($this->storages['public_key'], $tokenStorage);
}

public function addResponseType(ResponseTypeInterface $responseType, $key = null)
{
if (isset($this->responseTypeMap[$key])) {
Expand Down Expand Up @@ -433,17 +417,29 @@ protected function createDefaultTokenController()
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server");
}

return new TokenController($this->getAccessTokenResponseType(), $this->storages['client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
if ($this->config['use_crypto_tokens']) {
$accessTokenResponseType = $this->getCryptoTokenResponseType();
} else {
$accessTokenResponseType = $this->getAccessTokenResponseType();
}

return new TokenController($accessTokenResponseType, $this->storages['client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
}

protected function createDefaultResourceController()
{
if (!isset($this->storages['access_token'])) {
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface to use the resource server");
if ($this->config['use_crypto_tokens']) {
$this->storages['access_token'] = $this->createDefaultCryptoTokenStorage();
} else {
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface to use the resource server");
}
}

if (!$this->tokenType) {
$this->tokenType = $this->getDefaultTokenType();
}

$config = array_intersect_key($this->config, array('www_realm' => ''));

return new ResourceController($this->tokenType, $this->storages['access_token'], $config, $this->getScopeUtil());
Expand All @@ -460,8 +456,12 @@ protected function getDefaultResponseTypes()
{
$responseTypes = array();

if (isset($this->storages['access_token'])) {
$responseTypes['token'] = $this->getAccessTokenResponseType();
if ($this->config['allow_implicit']) {
if ($this->config['use_crypto_tokens']) {
$responseTypes['token'] = $this->getCryptoTokenResponseType();
} elseif (isset($this->storages['access_token'])) {
$responseTypes['token'] = $this->getAccessTokenResponseType();
}
}

if (isset($this->storages['authorization_code'])) {
Expand All @@ -470,7 +470,7 @@ protected function getDefaultResponseTypes()
}

if (count($responseTypes) == 0) {
throw new \LogicException("You must supply an array of response_types in the constructor or implement a OAuth2\Storage\AccessTokenInterface or OAuth2\Storage\AuthorizationCodeInterface storage object");
throw new \LogicException("You must supply an array of response_types in the constructor or implement a OAuth2\Storage\AuthorizationCodeInterface storage object or set 'allow_implicit' to true and implement a OAuth2\Storage\AccessTokenInterface storage object");
}

return $responseTypes;
Expand Down Expand Up @@ -510,38 +510,70 @@ protected function getAccessTokenResponseType()
if (isset($this->responseTypes['token'])) {
return $this->responseTypes['token'];
}
if (!isset($this->storages['access_token'])) {
throw new \LogicException("You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server");
}
$refreshStorage = null;
if (isset($this->storages['refresh_token'])) {
$refreshStorage = $this->storages['refresh_token'];

return $this->createDefaultAccessTokenResponseType();
}

protected function getCryptoTokenResponseType()
{
if (isset($this->responseTypes['token'])) {
return $this->responseTypes['token'];
}

if (!empty($this->config['use_crypto_tokens'])) {
return $this->createDefaultCryptoToken($refreshStorage);
return $this->createDefaultCryptoTokenResponseType();
}

/**
* For Resource Controller
*/
protected function createDefaultCryptoTokenStorage()
{
if (!isset($this->storages['public_key'])) {
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
}
else {
return $this->createDefaultAccessToken($refreshStorage);
$tokenStorage = null;
if (!empty($this->config['store_encrypted_token_string']) && isset($this->storages['access_token'])) {
$tokenStorage = $this->storages['access_token'];
}
// wrap the access token storage as required.
return new CryptoTokenStorage($this->storages['public_key'], $tokenStorage);
}

protected function createDefaultCryptoToken($refreshStorage = null)
/**
* For Authorize and Token Controllers
*/
protected function createDefaultCryptoTokenResponseType()
{
if (!isset($this->storages['public_key'])) {
throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
}

$tokenStorage = null;
if (!empty($this->config['store_encrypted_token_string'])) {
if (isset($this->storages['access_token'])) {
$tokenStorage = $this->storages['access_token'];
}

$refreshStorage = null;
if (isset($this->storages['refresh_token'])) {
$refreshStorage = $this->storages['refresh_token'];
}

$config = array_intersect_key($this->config, array_flip(explode(' ', 'store_encrypted_token_string')));

return new CryptoToken($this->storages['public_key'], $tokenStorage, $refreshStorage, $config);
}

protected function createDefaultAccessToken($refreshStorage = null)
protected function createDefaultAccessTokenResponseType()
{
if (!isset($this->storages['access_token'])) {
throw new \LogicException("You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server");
}

$refreshStorage = null;
if (isset($this->storages['refresh_token'])) {
$refreshStorage = $this->storages['refresh_token'];
}

$config = array_intersect_key($this->config, array_flip(explode(' ', 'access_lifetime refresh_token_lifetime')));
$config['token_type'] = $this->tokenType ? $this->tokenType->getTokenType() : $this->getDefaultTokenType()->getTokenType();

Expand Down
68 changes: 66 additions & 2 deletions test/OAuth2/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,29 @@ public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeR
$this->assertNotNull($server->getAuthorizeController());
}

public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorage()
/**
* @expectedException LogicException allow_implicit
**/
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
{
// must set AccessToken or AuthorizationCode
// 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
Expand Down Expand Up @@ -308,4 +321,55 @@ public function testAddingUnknownResponseTypeThrowsException()
$server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
}

/**
* @expectedException LogicException OAuth2\Storage\PublicKeyInterface
**/
public function testUsingCryptoTokensWithoutPublicKeyStorageThrowsException()
{
$server = new Server(array(), array('use_crypto_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 testUsingJustCryptoTokenStorageWithResourceControllerIsOkay()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_crypto_tokens' => true));

$this->assertNotNull($server->getResourceController());
$this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
}

/**
* @expectedException LogicException OAuth2\Storage\ClientInterface
**/
public function testUsingJustCryptoTokenStorageWithAuthorizeControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_crypto_tokens' => true));
$this->assertNotNull($server->getAuthorizeController());
}

/**
* @expectedException LogicException grant_types
**/
public function testUsingJustCryptoTokenStorageWithTokenControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_crypto_tokens' => true));
$server->getTokenController();
}

public function testUsingCryptoTokenAndClientStorageWithAuthorizeControllerIsOk()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$server = new Server(array($pubkey, $client), array('use_crypto_tokens' => true, 'allow_implicit' => true));
$this->assertNotNull($server->getAuthorizeController());

$this->assertInstanceOf('OAuth2\ResponseType\CryptoToken', $server->getResponseType('token'));
}
}

0 comments on commit 2fb46d6

Please sign in to comment.