diff --git a/README.md b/README.md index b74d8a35..fc9a23a1 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,10 @@ $token = (new Builder())->setIssuer('http://example.com') // Configures the issu ->getToken(); // Retrieves the generated token -$token->getHeader(); // Retrieves the token header +$token->getHeaders(); // Retrieves the token headers $token->getClaims(); // Retrieves the token claims +echo $token->getHeader('jti'); // will print "4f1g23a12aa" echo $token->getClaim('iss'); // will print "http://example.com" echo $token->getClaim('uid'); // will print "1" echo $token; // The string representation of the object is a JWT string (pretty easy, right?) @@ -64,9 +65,10 @@ Use the parser to create a new token from a JWT string (using the previous token use Lcobucci\JWT\Parser; $token = (new Parser())->parse((string) $token); // Parses from a string -$token->getHeader(); // Retrieves the token header +$token->getHeaders(); // Retrieves the token header $token->getClaims(); // Retrieves the token claims +echo $token->getHeader('jti'); // will print "4f1g23a12aa" echo $token->getClaim('iss'); // will print "http://example.com" echo $token->getClaim('uid'); // will print "1" ``` @@ -102,6 +104,8 @@ Hmac signatures are really simple to be used: use Lcobucci\JWT\Builder; use Lcobucci\JWT\Signer\Hmac\Sha256; +$signer = new Sha256(); + $token = (new Builder())->setIssuer('http://example.com') // Configures the issuer (iss claim) ->setAudience('http://example.org') // Configures the audience (aud claim) ->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item @@ -109,12 +113,12 @@ $token = (new Builder())->setIssuer('http://example.com') // Configures the issu ->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim) ->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim) ->set('uid', 1) // Configures a new claim, called "uid" - ->sign(new Sha256(), 'testing') // creates a signature using "testing" as key + ->sign($signer, 'testing') // creates a signature using "testing" as key ->getToken(); // Retrieves the generated token -var_dump($token->verify('testing 1')); // false, because the key is different -var_dump($token->verify('testing')); // true, because the key is the same +var_dump($token->verify($signer, 'testing 1')); // false, because the key is different +var_dump($token->verify($signer, 'testing')); // true, because the key is the same ``` ### RSA and ECDSA @@ -126,6 +130,8 @@ use Lcobucci\JWT\Builder; use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys +$signer = new Sha256(); + $keychain = new Keychain(); $token = (new Builder())->setIssuer('http://example.com') // Configures the issuer (iss claim) @@ -135,11 +141,11 @@ $token = (new Builder())->setIssuer('http://example.com') // Configures the issu ->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim) ->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim) ->set('uid', 1) // Configures a new claim, called "uid" - ->sign(new Sha256(), $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key + ->sign($signer, $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key ->getToken(); // Retrieves the generated token -var_dump($token->verify($keychain->getPublicKey('file://{path to your public key}')); // true when the public key was generated by the private one =) +var_dump($token->verify($signer, $keychain->getPublicKey('file://{path to your public key}')); // true when the public key was generated by the private one =) ``` **It's important to say that if you're using RSA keys you shouldn't invoke ECDSA signers (and vice-versa), otherwise ```sign()``` and ```verify()``` will raise an exception!** diff --git a/composer.lock b/composer.lock index 3237deb1..ede998bf 100644 --- a/composer.lock +++ b/composer.lock @@ -151,16 +151,16 @@ }, { "name": "phpmd/phpmd", - "version": "2.2.1", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "58c4b00f924d301e8c5281f40cfa9a66f3df9eee" + "reference": "7dc4a6b5c07b119ab5da7960b56303fa6855eb84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/58c4b00f924d301e8c5281f40cfa9a66f3df9eee", - "reference": "58c4b00f924d301e8c5281f40cfa9a66f3df9eee", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/7dc4a6b5c07b119ab5da7960b56303fa6855eb84", + "reference": "7dc4a6b5c07b119ab5da7960b56303fa6855eb84", "shasum": "" }, "require": { @@ -209,25 +209,26 @@ "phpmd", "pmd" ], - "time": "2015-03-02 10:26:50" + "time": "2015-03-26 07:47:05" }, { "name": "phpspec/prophecy", - "version": "v1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", + "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", - "phpdocumentor/reflection-docblock": "~2.0" + "doctrine/instantiator": "^1.0.2", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -235,7 +236,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { @@ -259,7 +260,7 @@ } ], "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "http://phpspec.org", + "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", @@ -268,7 +269,7 @@ "spy", "stub" ], - "time": "2014-11-17 16:23:49" + "time": "2015-03-27 19:31:25" }, { "name": "phpunit/php-code-coverage", @@ -562,16 +563,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.5.0", + "version": "4.5.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5" + "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5", - "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4", + "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4", "shasum": "" }, "require": { @@ -581,8 +582,8 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpspec/prophecy": "~1.3.1", - "phpunit/php-code-coverage": "~2.0", + "phpspec/prophecy": "~1.3,>=1.3.1", + "phpunit/php-code-coverage": "~2.0,>=2.0.11", "phpunit/php-file-iterator": "~1.3.2", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "~1.0.2", @@ -630,7 +631,7 @@ "testing", "xunit" ], - "time": "2015-02-05 15:51:19" + "time": "2015-03-29 09:24:05" }, { "name": "phpunit/phpunit-mock-objects", @@ -1134,23 +1135,26 @@ }, { "name": "symfony/config", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408" + "reference": "7a47189c7667ca69bcaafd19ef8a8941db449a2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/a9f781ba1221067d1f07c8cec0bc50f81b8d7408", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408", + "url": "https://api.github.com/repos/symfony/Config/zipball/7a47189c7667ca69bcaafd19ef8a8941db449a2c", + "reference": "7a47189c7667ca69bcaafd19ef8a8941db449a2c", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/filesystem": "~2.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -1178,21 +1182,21 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2015-01-21 20:57:55" + "time": "2015-03-12 10:28:44" }, { "name": "symfony/dependency-injection", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "42bbb43fab66292a1865dc9616c299904c3d4d14" + "reference": "a49245b2beebe332924561c30772b16e1d32f13a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/42bbb43fab66292a1865dc9616c299904c3d4d14", - "reference": "42bbb43fab66292a1865dc9616c299904c3d4d14", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/a49245b2beebe332924561c30772b16e1d32f13a", + "reference": "a49245b2beebe332924561c30772b16e1d32f13a", "shasum": "" }, "require": { @@ -1204,6 +1208,7 @@ "require-dev": { "symfony/config": "~2.2", "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.1" }, "suggest": { @@ -1238,26 +1243,29 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-17 12:44:40" }, { "name": "symfony/filesystem", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7" + "reference": "fdc5f151bc2db066b51870d5bea3773d915ced0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a1f566d1f92e142fa1593f4555d6d89e3044a9b7", - "reference": "a1f566d1f92e142fa1593f4555d6d89e3044a9b7", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/fdc5f151bc2db066b51870d5bea3773d915ced0b", + "reference": "fdc5f151bc2db066b51870d5bea3773d915ced0b", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -1285,26 +1293,29 @@ ], "description": "Symfony Filesystem Component", "homepage": "http://symfony.com", - "time": "2015-01-03 21:13:09" + "time": "2015-03-12 10:28:44" }, { "name": "symfony/yaml", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8" + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d", + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -1332,7 +1343,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-12 10:28:44" } ], "aliases": [], diff --git a/src/Builder.php b/src/Builder.php index c6b92687..c2b1e2a4 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -24,7 +24,7 @@ class Builder * * @var array */ - private $header; + private $headers; /** * The token claim set @@ -66,7 +66,7 @@ public function __construct( ) { $this->encoder = $encoder ?: new Encoder(); $this->claimFactory = $claimFactory ?: new ClaimFactory(); - $this->header = ['typ'=> 'JWT', 'alg' => 'none']; + $this->headers = ['typ'=> 'JWT', 'alg' => 'none']; $this->claims = []; } @@ -175,7 +175,7 @@ protected function setRegisteredClaim($name, $value, $replicate) $this->set($name, $value); if ($replicate) { - $this->header[$name] = $this->claims[$name]; + $this->headers[$name] = $this->claims[$name]; } return $this; @@ -212,7 +212,7 @@ public function set($name, $value) */ public function sign(Signer $signer, $key) { - $signer->modifyHeader($this->header); + $signer->modifyHeader($this->headers); $this->signature = $signer->sign( $this->getToken()->getPayload(), @@ -241,7 +241,7 @@ public function unsign() */ public function getToken() { - $token = new Token($this->header, $this->claims, $this->signature); + $token = new Token($this->headers, $this->claims, $this->signature); $token->setEncoder($this->encoder); return $token; diff --git a/src/Parser.php b/src/Parser.php index ba54d4b2..03be11e7 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -11,7 +11,6 @@ use Lcobucci\JWT\Claim\Factory as ClaimFactory; use Lcobucci\JWT\Parsing\Decoder; use Lcobucci\JWT\Parsing\Encoder; -use Lcobucci\JWT\Signer\Factory as SignerFactory; /** * This class parses the JWT strings and convert them into tokens @@ -35,13 +34,6 @@ class Parser */ private $decoder; - /** - * The signer factory - * - * @var SignerFactory - */ - private $signerFactory; - /** * The claims factory * @@ -54,18 +46,15 @@ class Parser * * @param Encoder $encoder * @param Decoder $decoder - * @param SignerFactory $signerFactory * @param ClaimFactory $claimFactory */ public function __construct( Encoder $encoder = null, Decoder $decoder = null, - SignerFactory $signerFactory = null, ClaimFactory $claimFactory = null ) { $this->encoder = $encoder ?: new Encoder(); $this->decoder = $decoder ?: new Decoder(); - $this->signerFactory = $signerFactory ?: new SignerFactory(); $this->claimFactory = $claimFactory ?: new ClaimFactory(); } @@ -141,7 +130,7 @@ protected function splitJwt($jwt) */ protected function parseHeader($data) { - $header = $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data)); + $header = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data)); if (isset($header['enc'])) { throw new InvalidArgumentException('Encryption is not supported yet'); @@ -159,7 +148,7 @@ protected function parseHeader($data) */ protected function parseClaims($data) { - $claims = $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data)); + $claims = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data)); foreach ($claims as $name => &$value) { $value = $this->claimFactory->create($name, $value); @@ -184,6 +173,6 @@ protected function parseSignature(array $header, $data) $hash = $this->decoder->base64UrlDecode($data); - return new Signature($this->signerFactory->create($header['alg']), $hash); + return new Signature($hash); } } diff --git a/src/Parsing/Decoder.php b/src/Parsing/Decoder.php index 854ac9ee..86336b08 100644 --- a/src/Parsing/Decoder.php +++ b/src/Parsing/Decoder.php @@ -30,16 +30,12 @@ class Decoder */ public function jsonDecode($json) { - $data = json_decode($json, true); + $data = json_decode($json); if (json_last_error() != JSON_ERROR_NONE) { throw new RuntimeException('Error while decoding to JSON: ' . json_last_error_msg()); } - if (!is_array($data)) { - throw new RuntimeException('The decoded data must be an array'); - } - return $data; } diff --git a/src/Signature.php b/src/Signature.php index e5efb71c..42f2b22a 100644 --- a/src/Signature.php +++ b/src/Signature.php @@ -15,13 +15,6 @@ */ class Signature { - /** - * The signer that created this signature - * - * @var Signer - */ - protected $signer; - /** * The resultant hash * @@ -32,12 +25,10 @@ class Signature /** * Initializes the object * - * @param Signer $signer * @param string $hash */ - public function __construct(Signer $signer, $hash) + public function __construct($hash) { - $this->signer = $signer; $this->hash = $hash; } @@ -45,14 +36,15 @@ public function __construct(Signer $signer, $hash) * Verifies if the current hash matches with with the result of the creation of * a new signature with given data * + * @param Signer $signer * @param string $payload * @param string $key * * @return boolean */ - public function verify($payload, $key) + public function verify(Signer $signer, $payload, $key) { - return $this->signer->verify($this->hash, $payload, $key); + return $signer->verify($this->hash, $payload, $key); } /** diff --git a/src/Signer/BaseSigner.php b/src/Signer/BaseSigner.php index 68507db4..a7faef3f 100644 --- a/src/Signer/BaseSigner.php +++ b/src/Signer/BaseSigner.php @@ -32,7 +32,7 @@ public function modifyHeader(array &$headers) */ public function sign($payload, $key) { - return new Signature($this, $this->createHash($payload, $key)); + return new Signature($this->createHash($payload, $key)); } /** diff --git a/src/Signer/Factory.php b/src/Signer/Factory.php deleted file mode 100644 index 84fa6a63..00000000 --- a/src/Signer/Factory.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @since 0.1.0 - */ -class Factory -{ - /** - * The list of signers callbacks - * - * @var array - */ - private $callbacks; - - /** - * Initializes the factory, registering the default callbacks - * - * @param array $callbacks - */ - public function __construct(array $callbacks = []) - { - $this->callbacks = array_merge( - [ - 'HS256' => [$this, 'createHmacSha256'], - 'HS384' => [$this, 'createHmacSha384'], - 'HS512' => [$this, 'createHmacSha512'], - 'ES256' => [$this, 'createEcdsaSha256'], - 'ES384' => [$this, 'createEcdsaSha384'], - 'ES512' => [$this, 'createEcdsaSha512'], - 'RS256' => [$this, 'createRsaSha256'], - 'RS384' => [$this, 'createRsaSha384'], - 'RS512' => [$this, 'createRsaSha512'] - ], - $callbacks - ); - } - - /** - * Retrieves a signer instance - * - * @param string $id - * - * @return Signer - * - * @throws InvalidArgumentException When signer is not implemented or invalid - */ - public function create($id) - { - if (isset($this->callbacks[$id])) { - return call_user_func($this->callbacks[$id]); - } - - throw new InvalidArgumentException('Invalid signer'); - } - - /** - * @return HmacSha256 - */ - private function createHmacSha256() - { - return new HmacSha256(); - } - - /** - * @return HmacSha384 - */ - private function createHmacSha384() - { - return new HmacSha384(); - } - - /** - * @return HmacSha512 - */ - private function createHmacSha512() - { - return new HmacSha512(); - } - - /** - * @return RsaSha256 - */ - private function createRsaSha256() - { - return new RsaSha256(); - } - - /** - * @return RsaSha384 - */ - private function createRsaSha384() - { - return new RsaSha384(); - } - - /** - * @return RsaSha512 - */ - private function createRsaSha512() - { - return new RsaSha512(); - } - - /** - * @return EcdsaSha256 - */ - private function createEcdsaSha256() - { - return new EcdsaSha256(); - } - - /** - * @return EcdsaSha384 - */ - private function createEcdsaSha384() - { - return new EcdsaSha384(); - } - - /** - * @return EcdsaSha512 - */ - private function createEcdsaSha512() - { - return new EcdsaSha512(); - } -} diff --git a/src/Token.php b/src/Token.php index 4236d3fa..fe791a31 100644 --- a/src/Token.php +++ b/src/Token.php @@ -22,11 +22,11 @@ class Token { /** - * The token header + * The token headers * * @var array */ - private $header; + private $headers; /** * The token claim set @@ -52,16 +52,16 @@ class Token /** * Initializes the object * - * @param array $header + * @param array $headers * @param array $claims * @param Signature $signature */ public function __construct( - array $header = ['alg' => 'none'], + array $headers = ['alg' => 'none'], array $claims = [], Signature $signature = null ) { - $this->header = $header; + $this->headers = $headers; $this->claims = $claims; $this->signature = $signature; } @@ -77,13 +77,37 @@ public function setEncoder(Encoder $encoder) } /** - * Returns the token header + * Returns the token headers * * @return array */ - public function getHeader() + public function getHeaders() { - return $this->header; + return $this->headers; + } + + /** + * Returns the value of a token header + * + * @param string $name + * + * @return mixed + * + * @throws OutOfBoundsException + */ + public function getHeader($name) + { + if (!isset($this->headers[$name])) { + throw new OutOfBoundsException('Requested header is not configured'); + } + + $header = $this->headers[$name]; + + if ($header instanceof Claim) { + return $header->getValue(); + } + + return $header; } /** @@ -114,32 +138,27 @@ public function getClaim($name) return $this->claims[$name]->getValue(); } - /** - * Returns the token signature - * - * @return Signature - */ - public function getSignature() - { - return $this->signature; - } - /** * Verify if the key matches with the one that created the signature * + * @param Signer $signer * @param string $key * * @return boolean * * @throws BadMethodCallException When token is not signed */ - public function verify($key) + public function verify(Signer $signer, $key) { if ($this->signature === null) { throw new BadMethodCallException('This token is not signed'); } - return $this->signature->verify($this->getPayload(), $key); + if ($this->headers['alg'] !== $signer->getAlgorithmId()) { + return false; + } + + return $this->signature->verify($signer, $this->getPayload(), $key); } /** @@ -189,7 +208,7 @@ public function getPayload() return sprintf( '%s.%s', - $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->header)), + $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)), $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims)) ); } diff --git a/test/BuilderTest.php b/test/BuilderTest.php index c3c94137..cbcb3a8a 100644 --- a/test/BuilderTest.php +++ b/test/BuilderTest.php @@ -62,7 +62,7 @@ public function constructMustInitializeTheAttributes() { $builder = $this->createBuilder(); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals([], 'claims', $builder); $this->assertAttributeEquals(null, 'signature', $builder); $this->assertAttributeSame($this->encoder, 'encoder', $builder); @@ -83,7 +83,7 @@ public function setAudienceMustChangeTheAudClaim() $builder = $this->createBuilder(); $builder->setAudience('test'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['aud' => $this->defaultClaim], 'claims', $builder); } @@ -105,7 +105,7 @@ public function setAudienceCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'aud' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -140,7 +140,7 @@ public function setExpirationMustChangeTheExpClaim() $builder = $this->createBuilder(); $builder->setExpiration('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['exp' => $this->defaultClaim], 'claims', $builder); } @@ -162,7 +162,7 @@ public function setExpirationCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'exp' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -197,7 +197,7 @@ public function setIdMustChangeTheJtiClaim() $builder = $this->createBuilder(); $builder->setId('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['jti' => $this->defaultClaim], 'claims', $builder); } @@ -219,7 +219,7 @@ public function setIdCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'jti' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -254,7 +254,7 @@ public function setIssuedAtMustChangeTheIatClaim() $builder = $this->createBuilder(); $builder->setIssuedAt('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['iat' => $this->defaultClaim], 'claims', $builder); } @@ -276,7 +276,7 @@ public function setIssuedAtCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'iat' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -311,7 +311,7 @@ public function setIssuerMustChangeTheIssClaim() $builder = $this->createBuilder(); $builder->setIssuer('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['iss' => $this->defaultClaim], 'claims', $builder); } @@ -333,7 +333,7 @@ public function setIssuerCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'iss' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -368,7 +368,7 @@ public function setNotBeforeMustChangeTheNbfClaim() $builder = $this->createBuilder(); $builder->setNotBefore('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['nbf' => $this->defaultClaim], 'claims', $builder); } @@ -390,7 +390,7 @@ public function setNotBeforeCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'nbf' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -425,7 +425,7 @@ public function setSubjectMustChangeTheSubClaim() $builder = $this->createBuilder(); $builder->setSubject('2'); - $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'header', $builder); + $this->assertAttributeEquals(['alg' => 'none', 'typ' => 'JWT'], 'headers', $builder); $this->assertAttributeEquals(['sub' => $this->defaultClaim], 'claims', $builder); } @@ -447,7 +447,7 @@ public function setSubjectCanReplicateItemOnHeader() $this->assertAttributeEquals( ['alg' => 'none', 'typ' => 'JWT', 'sub' => $this->defaultClaim], - 'header', + 'headers', $builder ); } @@ -504,9 +504,8 @@ public function setMustKeepAFluentInterface() * @uses Lcobucci\JWT\Builder::set * @uses Lcobucci\JWT\Token::__construct * @uses Lcobucci\JWT\Token::setEncoder - * @uses Lcobucci\JWT\Token::getHeader + * @uses Lcobucci\JWT\Token::getHeaders * @uses Lcobucci\JWT\Token::getClaims - * @uses Lcobucci\JWT\Token::getSignature * * @covers Lcobucci\JWT\Builder::getToken */ @@ -515,9 +514,12 @@ public function getTokenMustReturnANewTokenWithCurrentConfiguration() $builder = $this->createBuilder(); $token = $builder->set('test', 123)->getToken(); - $this->assertAttributeEquals($token->getHeader(), 'header', $builder); + $signatureAttr = new \ReflectionProperty($token, 'signature'); + $signatureAttr->setAccessible(true); + + $this->assertAttributeEquals($token->getHeaders(), 'headers', $builder); $this->assertAttributeEquals($token->getClaims(), 'claims', $builder); - $this->assertAttributeSame($token->getSignature(), 'signature', $builder); + $this->assertAttributeSame($signatureAttr->getValue($token), 'signature', $builder); } /** diff --git a/test/FunctionalTests/EcdsaTokenTest.php b/test/FunctionalTests/EcdsaTokenTest.php index de92689d..739b9155 100644 --- a/test/FunctionalTests/EcdsaTokenTest.php +++ b/test/FunctionalTests/EcdsaTokenTest.php @@ -13,6 +13,7 @@ use Lcobucci\JWT\Signature; use Lcobucci\JWT\Signer\Ecdsa\Sha256; use Lcobucci\JWT\EcdsaKeys; +use Lcobucci\JWT\Signer\Ecdsa\Sha512; /** * @author Luís Otávio Cobucci Oblonczyk @@ -22,6 +23,19 @@ class EcdsaTokenTest extends \PHPUnit_Framework_TestCase { use EcdsaKeys; + /** + * @var Sha256 + */ + private $signer; + + /** + * @before + */ + public function createSigner() + { + $this->signer = new Sha256(); + } + /** * @test * @@ -38,13 +52,13 @@ class EcdsaTokenTest extends \PHPUnit_Framework_TestCase */ public function builderCanGenerateAToken() { - $user = ['name' => 'testing', 'email' => 'testing@abc.com']; + $user = (object) ['name' => 'testing', 'email' => 'testing@abc.com']; $token = (new Builder())->setId(1) ->setAudience('http://client.abc.com') ->setIssuer('http://api.abc.com') ->set('user', $user) - ->sign(new Sha256(), $this->privateEcdsa()) + ->sign($this->signer, $this->privateEcdsa()) ->getToken(); $this->assertAttributeInstanceOf(Signature::class, 'signature', $token); @@ -68,13 +82,13 @@ public function builderCanGenerateAToken() * @covers Lcobucci\JWT\Claim\Basic * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ public function parserCanReadAToken(Token $generated) { $read = (new Parser())->parse((string) $generated); $this->assertEquals($generated, $read); + $this->assertEquals('testing', $read->getClaim('user')->name); } /** @@ -89,14 +103,35 @@ public function parserCanReadAToken(Token $generated) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\OpenSSL * @covers Lcobucci\JWT\Signer\Ecdsa * @covers Lcobucci\JWT\Signer\Ecdsa\Sha256 */ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) { - $this->assertFalse($token->verify($this->otherPublicEcdsa())); + $this->assertFalse($token->verify($this->signer, $this->otherPublicEcdsa())); + } + + /** + * @test + * + * @depends builderCanGenerateAToken + * + * @covers Lcobucci\JWT\Builder + * @covers Lcobucci\JWT\Parser + * @covers Lcobucci\JWT\Token + * @covers Lcobucci\JWT\Signature + * @covers Lcobucci\JWT\Parsing\Encoder + * @covers Lcobucci\JWT\Claim\Factory + * @covers Lcobucci\JWT\Claim\Basic + * @covers Lcobucci\JWT\Signer\OpenSSL + * @covers Lcobucci\JWT\Signer\Ecdsa + * @covers Lcobucci\JWT\Signer\Ecdsa\Sha256 + * @covers Lcobucci\JWT\Signer\Ecdsa\Sha512 + */ + public function verifyShouldReturnFalseWhenAlgorithmIsDifferent(Token $token) + { + $this->assertFalse($token->verify(new Sha512(), $this->publicEcdsa())); } /** @@ -111,13 +146,12 @@ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\OpenSSL * @covers Lcobucci\JWT\Signer\Ecdsa * @covers Lcobucci\JWT\Signer\Ecdsa\Sha256 */ public function verifyShouldReturnTrueWhenKeyIsRight(Token $token) { - $this->assertTrue($token->verify($this->publicEcdsa())); + $this->assertTrue($token->verify($this->signer, $this->publicEcdsa())); } } diff --git a/test/FunctionalTests/HmacTokenTest.php b/test/FunctionalTests/HmacTokenTest.php index 18047c09..81af4d3f 100644 --- a/test/FunctionalTests/HmacTokenTest.php +++ b/test/FunctionalTests/HmacTokenTest.php @@ -12,6 +12,7 @@ use Lcobucci\JWT\Token; use Lcobucci\JWT\Signature; use Lcobucci\JWT\Signer\Hmac\Sha256; +use Lcobucci\JWT\Signer\Hmac\Sha512; /** * @author Luís Otávio Cobucci Oblonczyk @@ -19,6 +20,19 @@ */ class HmacTokenTest extends \PHPUnit_Framework_TestCase { + /** + * @var Sha256 + */ + private $signer; + + /** + * @before + */ + public function createSigner() + { + $this->signer = new Sha256(); + } + /** * @test * @@ -34,13 +48,13 @@ class HmacTokenTest extends \PHPUnit_Framework_TestCase */ public function builderCanGenerateAToken() { - $user = ['name' => 'testing', 'email' => 'testing@abc.com']; + $user = (object) ['name' => 'testing', 'email' => 'testing@abc.com']; $token = (new Builder())->setId(1) ->setAudience('http://client.abc.com') ->setIssuer('http://api.abc.com') ->set('user', $user) - ->sign(new Sha256(), 'testing') + ->sign($this->signer, 'testing') ->getToken(); $this->assertAttributeInstanceOf(Signature::class, 'signature', $token); @@ -64,13 +78,13 @@ public function builderCanGenerateAToken() * @covers Lcobucci\JWT\Claim\Basic * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ public function parserCanReadAToken(Token $generated) { $read = (new Parser())->parse((string) $generated); $this->assertEquals($generated, $read); + $this->assertEquals('testing', $read->getClaim('user')->name); } /** @@ -85,13 +99,34 @@ public function parserCanReadAToken(Token $generated) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\Hmac * @covers Lcobucci\JWT\Signer\Hmac\Sha256 */ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) { - $this->assertFalse($token->verify('testing1')); + $this->assertFalse($token->verify($this->signer, 'testing1')); + } + + /** + * @test + * + * @depends builderCanGenerateAToken + * + * @covers Lcobucci\JWT\Builder + * @covers Lcobucci\JWT\Parser + * @covers Lcobucci\JWT\Token + * @covers Lcobucci\JWT\Signature + * @covers Lcobucci\JWT\Parsing\Encoder + * @covers Lcobucci\JWT\Claim\Factory + * @covers Lcobucci\JWT\Claim\Basic + * @covers Lcobucci\JWT\Signer\OpenSSL + * @covers Lcobucci\JWT\Signer\Hmac + * @covers Lcobucci\JWT\Signer\Hmac\Sha256 + * @covers Lcobucci\JWT\Signer\Hmac\Sha512 + */ + public function verifyShouldReturnFalseWhenAlgorithmIsDifferent(Token $token) + { + $this->assertFalse($token->verify(new Sha512(), 'testing')); } /** @@ -106,12 +141,11 @@ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\Hmac * @covers Lcobucci\JWT\Signer\Hmac\Sha256 */ public function verifyShouldReturnTrueWhenKeyIsRight(Token $token) { - $this->assertTrue($token->verify('testing')); + $this->assertTrue($token->verify($this->signer, 'testing')); } } diff --git a/test/FunctionalTests/RsaTokenTest.php b/test/FunctionalTests/RsaTokenTest.php index 37b8d702..b19ef53a 100644 --- a/test/FunctionalTests/RsaTokenTest.php +++ b/test/FunctionalTests/RsaTokenTest.php @@ -13,6 +13,7 @@ use Lcobucci\JWT\Signature; use Lcobucci\JWT\Signer\Rsa\Sha256; use Lcobucci\JWT\RsaKeys; +use Lcobucci\JWT\Signer\Rsa\Sha512; /** * @author Luís Otávio Cobucci Oblonczyk @@ -22,6 +23,19 @@ class RsaTokenTest extends \PHPUnit_Framework_TestCase { use RsaKeys; + /** + * @var Sha256 + */ + private $signer; + + /** + * @before + */ + public function createSigner() + { + $this->signer = new Sha256(); + } + /** * @test * @@ -38,13 +52,13 @@ class RsaTokenTest extends \PHPUnit_Framework_TestCase */ public function builderCanGenerateAToken() { - $user = ['name' => 'testing', 'email' => 'testing@abc.com']; + $user = (object) ['name' => 'testing', 'email' => 'testing@abc.com']; $token = (new Builder())->setId(1) ->setAudience('http://client.abc.com') ->setIssuer('http://api.abc.com') ->set('user', $user) - ->sign(new Sha256(), $this->privateRsa()) + ->sign($this->signer, $this->privateRsa()) ->getToken(); $this->assertAttributeInstanceOf(Signature::class, 'signature', $token); @@ -68,13 +82,13 @@ public function builderCanGenerateAToken() * @covers Lcobucci\JWT\Claim\Basic * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ public function parserCanReadAToken(Token $generated) { $read = (new Parser())->parse((string) $generated); $this->assertEquals($generated, $read); + $this->assertEquals('testing', $read->getClaim('user')->name); } /** @@ -89,14 +103,35 @@ public function parserCanReadAToken(Token $generated) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\OpenSSL * @covers Lcobucci\JWT\Signer\Rsa * @covers Lcobucci\JWT\Signer\Rsa\Sha256 */ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) { - $this->assertFalse($token->verify($this->encryptedPublicRsa())); + $this->assertFalse($token->verify($this->signer, $this->encryptedPublicRsa())); + } + + /** + * @test + * + * @depends builderCanGenerateAToken + * + * @covers Lcobucci\JWT\Builder + * @covers Lcobucci\JWT\Parser + * @covers Lcobucci\JWT\Token + * @covers Lcobucci\JWT\Signature + * @covers Lcobucci\JWT\Parsing\Encoder + * @covers Lcobucci\JWT\Claim\Factory + * @covers Lcobucci\JWT\Claim\Basic + * @covers Lcobucci\JWT\Signer\OpenSSL + * @covers Lcobucci\JWT\Signer\Rsa + * @covers Lcobucci\JWT\Signer\Rsa\Sha256 + * @covers Lcobucci\JWT\Signer\Rsa\Sha512 + */ + public function verifyShouldReturnFalseWhenAlgorithmIsDifferent(Token $token) + { + $this->assertFalse($token->verify(new Sha512(), $this->publicRsa())); } /** @@ -111,13 +146,12 @@ public function verifyShouldReturnFalseWhenKeyIsNotRight(Token $token) * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Claim\Factory * @covers Lcobucci\JWT\Claim\Basic - * @covers Lcobucci\JWT\Signer\Factory * @covers Lcobucci\JWT\Signer\OpenSSL * @covers Lcobucci\JWT\Signer\Rsa * @covers Lcobucci\JWT\Signer\Rsa\Sha256 */ public function verifyShouldReturnTrueWhenKeyIsRight(Token $token) { - $this->assertTrue($token->verify($this->publicRsa())); + $this->assertTrue($token->verify($this->signer, $this->publicRsa())); } } diff --git a/test/FunctionalTests/UnsignedTokenTest.php b/test/FunctionalTests/UnsignedTokenTest.php index e3bda3a3..a6280b88 100644 --- a/test/FunctionalTests/UnsignedTokenTest.php +++ b/test/FunctionalTests/UnsignedTokenTest.php @@ -30,7 +30,7 @@ class UnsignedTokenTest extends \PHPUnit_Framework_TestCase */ public function builderCanGenerateAToken() { - $user = ['name' => 'testing', 'email' => 'testing@abc.com']; + $user = (object) ['name' => 'testing', 'email' => 'testing@abc.com']; $token = (new Builder())->setId(1) ->setAudience('http://client.abc.com') @@ -60,13 +60,13 @@ public function builderCanGenerateAToken() * @covers Lcobucci\JWT\Claim\Basic * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ public function parserCanReadAToken(Token $generated) { $read = (new Parser())->parse((string) $generated); $this->assertEquals($generated, $read); + $this->assertEquals('testing', $read->getClaim('user')->name); } /** @@ -84,9 +84,8 @@ public function parserCanReadAToken(Token $generated) * @covers Lcobucci\JWT\Claim\GreaterOrEqualsTo * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ - public function tokenValidationShouldReturnWhenEverythingIsFile(Token $generated) + public function tokenValidationShouldReturnWhenEverythingIsFine(Token $generated) { $data = new ValidationData(self::CURRENT_TIME - 10); $data->setAudience('http://client.abc.com'); @@ -112,7 +111,6 @@ public function tokenValidationShouldReturnWhenEverythingIsFile(Token $generated * @covers Lcobucci\JWT\Claim\GreaterOrEqualsTo * @covers Lcobucci\JWT\Parsing\Encoder * @covers Lcobucci\JWT\Parsing\Decoder - * @covers Lcobucci\JWT\Signer\Factory */ public function tokenValidationShouldReturnFalseWhenExpectedDataDontMatch(ValidationData $data, Token $generated) { diff --git a/test/ParserTest.php b/test/ParserTest.php index 90c04a1b..2c315c36 100644 --- a/test/ParserTest.php +++ b/test/ParserTest.php @@ -10,7 +10,6 @@ use Lcobucci\JWT\Claim\Factory as ClaimFactory; use Lcobucci\JWT\Parsing\Decoder; use Lcobucci\JWT\Parsing\Encoder; -use Lcobucci\JWT\Signer\Factory as SignerFactory; use RuntimeException; /** @@ -29,11 +28,6 @@ class ParserTest extends \PHPUnit_Framework_TestCase */ protected $decoder; - /** - * @var SignerFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $signerFactory; - /** * @var ClaimFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -51,7 +45,6 @@ protected function setUp() { $this->encoder = $this->getMock(Encoder::class); $this->decoder = $this->getMock(Decoder::class); - $this->signerFactory = $this->getMock(SignerFactory::class, [], [], '', false); $this->claimFactory = $this->getMock(ClaimFactory::class, [], [], '', false); $this->defaultClaim = $this->getMock(Claim::class); @@ -68,7 +61,6 @@ private function createParser() return new Parser( $this->encoder, $this->decoder, - $this->signerFactory, $this->claimFactory ); } @@ -84,7 +76,6 @@ public function constructMustConfigureTheAttributes() $this->assertAttributeSame($this->encoder, 'encoder', $parser); $this->assertAttributeSame($this->decoder, 'decoder', $parser); - $this->assertAttributeSame($this->signerFactory, 'signerFactory', $parser); $this->assertAttributeSame($this->claimFactory, 'claimFactory', $parser); } @@ -192,7 +183,7 @@ public function parseMustReturnANonSignedTokenWhenSignatureIsNotInformed() $parser = $this->createParser(); $token = $parser->parse('a.a.'); - $this->assertAttributeEquals(['typ' => 'JWT', 'alg' => 'none'], 'header', $token); + $this->assertAttributeEquals(['typ' => 'JWT', 'alg' => 'none'], 'headers', $token); $this->assertAttributeEquals(['aud' => $this->defaultClaim], 'claims', $token); $this->assertAttributeEquals(null, 'signature', $token); $this->assertAttributeSame($this->encoder, 'encoder', $token); @@ -227,7 +218,7 @@ public function parseShouldReplicateClaimValueOnHeaderWhenNeeded() $this->assertAttributeEquals( ['typ' => 'JWT', 'alg' => 'none', 'aud' => $this->defaultClaim], - 'header', + 'headers', $token ); @@ -253,8 +244,6 @@ public function parseShouldReplicateClaimValueOnHeaderWhenNeeded() */ public function parseMustReturnASignedTokenWhenSignatureIsInformed() { - $signer = $this->getMock(Signer::class); - $this->decoder->expects($this->at(1)) ->method('jsonDecode') ->willReturn(['typ' => 'JWT', 'alg' => 'HS256']); @@ -267,16 +256,12 @@ public function parseMustReturnASignedTokenWhenSignatureIsInformed() ->method('base64UrlDecode') ->willReturn('aaa'); - $this->signerFactory->expects($this->any()) - ->method('create') - ->willReturn($signer); - $parser = $this->createParser(); $token = $parser->parse('a.a.a'); - $this->assertAttributeEquals(['typ' => 'JWT', 'alg' => 'HS256'], 'header', $token); + $this->assertAttributeEquals(['typ' => 'JWT', 'alg' => 'HS256'], 'headers', $token); $this->assertAttributeEquals(['aud' => $this->defaultClaim], 'claims', $token); - $this->assertAttributeEquals(new Signature($signer, 'aaa'), 'signature', $token); + $this->assertAttributeEquals(new Signature('aaa'), 'signature', $token); $this->assertAttributeSame($this->encoder, 'encoder', $token); } } diff --git a/test/Parsing/DecoderTest.php b/test/Parsing/DecoderTest.php index e737b24c..51d727bd 100644 --- a/test/Parsing/DecoderTest.php +++ b/test/Parsing/DecoderTest.php @@ -22,21 +22,10 @@ public function jsonDecodeMustReturnTheDecodedData() { $decoder = new Decoder(); - $this->assertEquals(['test' => 'test'], $decoder->jsonDecode('{"test":"test"}')); - } - - /** - * @test - * - * @covers Lcobucci\JWT\Parsing\Decoder::jsonDecode - * - * @expectedException \RuntimeException - */ - public function jsonDecodeMustRaiseExceptionWhenResultIsNotAnArray() - { - $decoder = new Decoder(); - - $decoder->jsonDecode('"test"'); + $this->assertEquals( + (object) ['test' => 'test'], + $decoder->jsonDecode('{"test":"test"}') + ); } /** diff --git a/test/SignatureTest.php b/test/SignatureTest.php index 54b36be7..c29787e1 100644 --- a/test/SignatureTest.php +++ b/test/SignatureTest.php @@ -33,9 +33,8 @@ protected function setUp() */ public function constructorMustConfigureAttributes() { - $signature = new Signature($this->signer, 'test'); + $signature = new Signature('test'); - $this->assertAttributeSame($this->signer, 'signer', $signature); $this->assertAttributeEquals('test', 'hash', $signature); } @@ -48,7 +47,7 @@ public function constructorMustConfigureAttributes() */ public function toStringMustReturnTheHash() { - $signature = new Signature($this->signer, 'test'); + $signature = new Signature('test'); $this->assertEquals('test', (string) $signature); } @@ -67,8 +66,8 @@ public function verifyMustReturnWhatSignerSays() ->method('verify') ->willReturn(true); - $signature = new Signature($this->signer, 'test'); + $signature = new Signature('test'); - $this->assertTrue($signature->verify('one', 'key')); + $this->assertTrue($signature->verify($this->signer, 'one', 'key')); } } diff --git a/test/Signer/BaseSignerTest.php b/test/Signer/BaseSignerTest.php index 58b11b59..5baf70ee 100644 --- a/test/Signer/BaseSignerTest.php +++ b/test/Signer/BaseSignerTest.php @@ -61,7 +61,7 @@ public function modifyHeaderShouldChangeAlgorithmAndType() public function signMustReturnANewSignature() { $this->assertEquals( - new Signature($this->signer, 'test'), + new Signature('test'), $this->signer->sign('test', '123') ); } diff --git a/test/Signer/FactoryTest.php b/test/Signer/FactoryTest.php deleted file mode 100644 index 8ca977ea..00000000 --- a/test/Signer/FactoryTest.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @since 0.1.0 - */ -class FactoryTest extends \PHPUnit_Framework_TestCase -{ - /** - * @test - * - * @covers Lcobucci\JWT\Signer\Factory::__construct - */ - public function constructMustConfigureTheCallbacks() - { - $callback = function () { - }; - $factory = new Factory(['test' => $callback]); - - $expected = [ - 'HS256' => [$factory, 'createHmacSha256'], - 'HS384' => [$factory, 'createHmacSha384'], - 'HS512' => [$factory, 'createHmacSha512'], - 'RS256' => [$factory, 'createRsaSha256'], - 'RS384' => [$factory, 'createRsaSha384'], - 'RS512' => [$factory, 'createRsaSha512'], - 'ES256' => [$factory, 'createEcdsaSha256'], - 'ES384' => [$factory, 'createEcdsaSha384'], - 'ES512' => [$factory, 'createEcdsaSha512'], - 'test' => $callback - ]; - - $this->assertAttributeEquals($expected, 'callbacks', $factory); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createHmacSha256 - */ - public function createMustBeAbleReturnAHmacSha256Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(HmacSha256::class, $factory->create('HS256')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createHmacSha384 - */ - public function createMustBeAbleReturnAHmacSha384Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(HmacSha384::class, $factory->create('HS384')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createHmacSha512 - */ - public function createMustBeAbleReturnAHmacSha512Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(HmacSha512::class, $factory->create('HS512')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createRsaSha256 - */ - public function createMustBeAbleReturnARsaSha256Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(RsaSha256::class, $factory->create('RS256')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createRsaSha384 - */ - public function createMustBeAbleReturnARsaSha384Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(RsaSha384::class, $factory->create('RS384')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createRsaSha512 - */ - public function createMustBeAbleReturnARsaSha512Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(RsaSha512::class, $factory->create('RS512')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createEcdsaSha256 - */ - public function createMustBeAbleReturnAEcdsaSha256Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(EcdsaSha256::class, $factory->create('ES256')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createEcdsaSha384 - */ - public function createMustBeAbleReturnAEcdsaSha384Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(EcdsaSha384::class, $factory->create('ES384')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * @covers Lcobucci\JWT\Signer\Factory::createEcdsaSha512 - */ - public function createMustBeAbleReturnAEcdsaSha512Signer() - { - $factory = new Factory(); - - $this->assertInstanceOf(EcdsaSha512::class, $factory->create('ES512')); - } - - /** - * @test - * - * @uses Lcobucci\JWT\Signer\Factory::__construct - * - * @covers Lcobucci\JWT\Signer\Factory::create - * - * @expectedException InvalidArgumentException - */ - public function createMustRaiseExceptionWhenIdIsInvalid() - { - $factory = new Factory(); - $factory->create('testing'); - } -} diff --git a/test/TokenTest.php b/test/TokenTest.php index ea961b60..ae5f1879 100644 --- a/test/TokenTest.php +++ b/test/TokenTest.php @@ -41,7 +41,7 @@ public function constructMustInitializeAnEmptyPlainTextTokenWhenNoArgumentsArePa { $token = new Token(); - $this->assertAttributeEquals(['alg' => 'none'], 'header', $token); + $this->assertAttributeEquals(['alg' => 'none'], 'headers', $token); $this->assertAttributeEquals([], 'claims', $token); $this->assertAttributeEquals(null, 'signature', $token); } @@ -67,12 +67,58 @@ public function setEncoderMustConfigureTheEncoderAttribute() * @uses Lcobucci\JWT\Token::__construct * * @covers Lcobucci\JWT\Token::getHeader + * + * @expectedException \OutOfBoundsException */ - public function getHeaderMustReturnTheConfiguredHeader() + public function getHeaderMustRaiseExceptionWhenHeaderIsNotConfigured() { $token = new Token(['test' => 'testing']); - $this->assertEquals(['test' => 'testing'], $token->getHeader()); + $token->getHeader('testing'); + } + + /** + * @test + * + * @uses Lcobucci\JWT\Token::__construct + * + * @covers Lcobucci\JWT\Token::getHeader + */ + public function getHeaderMustReturnTheRequestedHeader() + { + $token = new Token(['test' => 'testing']); + + $this->assertEquals('testing', $token->getHeader('test')); + } + + /** + * @test + * + * @uses Lcobucci\JWT\Token::__construct + * @uses Lcobucci\JWT\Claim\Basic::__construct + * @uses Lcobucci\JWT\Claim\Basic::getValue + * + * @covers Lcobucci\JWT\Token::getHeader + */ + public function getHeaderMustReturnValueWhenItIsAReplicatedClaim() + { + $token = new Token(['jti' => new EqualsTo('jti', 1)]); + + $this->assertEquals(1, $token->getHeader('jti')); + } + + /** + * @test + * + * @uses Lcobucci\JWT\Token::__construct + * + * @covers Lcobucci\JWT\Token::getHeaders + */ + public function getHeadersMustReturnTheConfiguredHeader() + { + $token = new Token(['test' => 'testing']); + + $this->assertEquals(['test' => 'testing'], $token->getHeaders()); } /** @@ -126,29 +172,43 @@ public function getClaimShouldReturnTheClaimValueWhenItExists() * * @uses Lcobucci\JWT\Token::__construct * - * @covers Lcobucci\JWT\Token::getSignature + * @covers Lcobucci\JWT\Token::verify + * + * @expectedException BadMethodCallException */ - public function getSignatureMustReturnTheConfiguredSignature() + public function verifyMustRaiseExceptionWhenTokenIsUnsigned() { - $signature = $this->getMock(Signature::class, [], [], '', false); - $token = new Token([], [], $signature); + $signer = $this->getMock(Signer::class); - $this->assertSame($signature, $token->getSignature()); + $token = new Token(); + $token->verify($signer, 'test'); } /** * @test * * @uses Lcobucci\JWT\Token::__construct + * @uses Lcobucci\JWT\Token::setEncoder + * @uses Lcobucci\JWT\Token::getPayload * * @covers Lcobucci\JWT\Token::verify - * - * @expectedException BadMethodCallException */ - public function verifyMustRaiseExceptionWhenTokenIsUnsigned() + public function verifyShouldReturnFalseWhenTokenAlgorithmIsDifferent() { - $token = new Token(); - $token->verify('test'); + $signer = $this->getMock(Signer::class); + $signature = $this->getMock(Signature::class, [], [], '', false); + + $signer->expects($this->any()) + ->method('getAlgorithmId') + ->willReturn('HS256'); + + $signature->expects($this->never()) + ->method('verify'); + + $token = new Token(['alg' => 'RS256'], [], $signature); + $token->setEncoder($this->encoder); + + $this->assertFalse($token->verify($signer, 'test')); } /** @@ -162,16 +222,22 @@ public function verifyMustRaiseExceptionWhenTokenIsUnsigned() */ public function verifyMustDelegateTheValidationToSignature() { + $signer = $this->getMock(Signer::class); $signature = $this->getMock(Signature::class, [], [], '', false); + $signer->expects($this->any()) + ->method('getAlgorithmId') + ->willReturn('HS256'); + $signature->expects($this->once()) ->method('verify') + ->with($signer, $this->isType('string'), 'test') ->willReturn(true); - $token = new Token([], [], $signature); + $token = new Token(['alg' => 'HS256'], [], $signature); $token->setEncoder($this->encoder); - $this->assertTrue($token->verify('test')); + $this->assertTrue($token->verify($signer, 'test')); } /**