diff --git a/CHANGELOG.md b/CHANGELOG.md index 468f1426..af06df1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.2 (released 2014-04-16) + +* Added the ability to change the algorithm that is used to generate the token strings (Issue #151) + ## 3.1.2 (released 2014-02-26) * Support Authorization being an environment variable. [See more](http://fortrabbit.com/docs/essentials/quirks-and-constraints#authorization-header) diff --git a/composer.json b/composer.json index f16fd43a..ae7a8170 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "league/oauth2-server", "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", - "version": "3.1.2", + "version": "3.2", "license": "MIT", "require": { "php": ">=5.4.0" diff --git a/src/League/OAuth2/Server/Util/KeyAlgorithm/DefaultAlgorithm.php b/src/League/OAuth2/Server/Util/KeyAlgorithm/DefaultAlgorithm.php new file mode 100644 index 00000000..de9aaff1 --- /dev/null +++ b/src/League/OAuth2/Server/Util/KeyAlgorithm/DefaultAlgorithm.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2013 PHP League of Extraordinary Packages + * @license http://mit-license.org/ + * @link http://github.com/php-loep/oauth2-server + */ + +namespace League\OAuth2\Server\Util\KeyAlgorithm; + + +class DefaultAlgorithm implements KeyAlgorithmInterface +{ + /** + * @param int $len + * @return string + * @throws \Exception + */ + public function make($len = 40) + { + // We generate twice as many bytes here because we want to ensure we have + // enough after we base64 encode it to get the length we need because we + // take out the "/", "+", and "=" characters. + $bytes = openssl_random_pseudo_bytes($len * 2, $strong); + + // We want to stop execution if the key fails because, well, that is bad. + if ($bytes === false || $strong === false) { + // @codeCoverageIgnoreStart + throw new \Exception('Error Generating Key'); + // @codeCoverageIgnoreEnd + } + + return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $len); + } +} \ No newline at end of file diff --git a/src/League/OAuth2/Server/Util/KeyAlgorithm/KeyAlgorithmInterface.php b/src/League/OAuth2/Server/Util/KeyAlgorithm/KeyAlgorithmInterface.php new file mode 100644 index 00000000..583daf71 --- /dev/null +++ b/src/League/OAuth2/Server/Util/KeyAlgorithm/KeyAlgorithmInterface.php @@ -0,0 +1,18 @@ + + * @copyright Copyright (c) 2013 PHP League of Extraordinary Packages + * @license http://mit-license.org/ + * @link http://github.com/php-loep/oauth2-server + */ + +namespace League\OAuth2\Server\Util\KeyAlgorithm; + + +interface KeyAlgorithmInterface +{ + public function make($len = 40); +} \ No newline at end of file diff --git a/src/League/OAuth2/Server/Util/SecureKey.php b/src/League/OAuth2/Server/Util/SecureKey.php index 8ff762c3..cd1fffd5 100644 --- a/src/League/OAuth2/Server/Util/SecureKey.php +++ b/src/League/OAuth2/Server/Util/SecureKey.php @@ -11,11 +11,16 @@ namespace League\OAuth2\Server\Util; +use League\OAuth2\Server\Util\KeyAlgorithm\DefaultAlgorithm; +use League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface; + /** * SecureKey class */ class SecureKey { + protected static $algorithm; + /** * Generate a new unique code * @param integer $len Length of the generated code @@ -23,18 +28,27 @@ class SecureKey */ public static function make($len = 40) { - // We generate twice as many bytes here because we want to ensure we have - // enough after we base64 encode it to get the length we need because we - // take out the "/", "+", and "=" characters. - $bytes = openssl_random_pseudo_bytes($len * 2, $strong); + return self::getAlgorithm()->make($len); + } - // We want to stop execution if the key fails because, well, that is bad. - if ($bytes === false || $strong === false) { - // @codeCoverageIgnoreStart - throw new \Exception('Error Generating Key'); - // @codeCoverageIgnoreEnd + /** + * @param KeyAlgorithmInterface $algorithm + */ + public static function setAlgorithm(KeyAlgorithmInterface $algorithm) + { + self::$algorithm = $algorithm; + } + + /** + * @return KeyAlgorithmInterface + */ + public static function getAlgorithm() + { + if (!self::$algorithm) { + + self::$algorithm = new DefaultAlgorithm(); } - return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $len); + return self::$algorithm; } } \ No newline at end of file diff --git a/tests/util/SecureKeyTest.php b/tests/util/SecureKeyTest.php index 3d60f6db..2ce8659e 100644 --- a/tests/util/SecureKeyTest.php +++ b/tests/util/SecureKeyTest.php @@ -12,4 +12,21 @@ class Secure_Key_test extends PHPUnit_Framework_TestCase $this->assertTrue($v1 !== $v2); $this->assertEquals(50, strlen($v3)); } + + public function test_make_with_different_algorithm() + { + $algorithm = $this->getMock('League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface'); + + $result = 'dasdsdsaads'; + $algorithm + ->expects($this->once()) + ->method('make') + ->with(11) + ->will($this->returnValue($result)) + ; + + League\OAuth2\Server\Util\SecureKey::setAlgorithm($algorithm); + $this->assertSame($algorithm, League\OAuth2\Server\Util\SecureKey::getAlgorithm()); + $this->assertEquals($result, League\OAuth2\Server\Util\SecureKey::make(11)); + } } \ No newline at end of file diff --git a/tests/util/key_algorithm/DefaultAlgorithmTest.php b/tests/util/key_algorithm/DefaultAlgorithmTest.php new file mode 100644 index 00000000..2e78ea1b --- /dev/null +++ b/tests/util/key_algorithm/DefaultAlgorithmTest.php @@ -0,0 +1,22 @@ +make(); + $v2 = $algorithm->make(); + $v3 = $algorithm->make(50); + + $this->assertEquals(40, strlen($v1)); + $this->assertTrue($v1 !== $v2); + $this->assertEquals(50, strlen($v3)); + } +} \ No newline at end of file