Fixed capitalization, tests

This commit is contained in:
Chris 2023-04-09 02:40:21 +02:00
parent 6b1d3178cf
commit 953e831d84
25 changed files with 199 additions and 161 deletions

View File

@ -1,4 +1,4 @@
# SimpleJwt # SimpleJWT
This is a simple library for generating (signing) and verifying JWT tokens. It This is a simple library for generating (signing) and verifying JWT tokens. It
is by no means an advanced library. If you just need to sign and refresh tokens is by no means an advanced library. If you just need to sign and refresh tokens
@ -27,23 +27,23 @@ Install using composer:
## Usage ## Usage
You need a key for both generating and parsing tokens. Create a `JwtDerivedKey` You need a key for both generating and parsing tokens. Create a `JWTDerivedKey`
or a `JwtPlaintextKey` and pass it to the `JwtToken` constructor: or a `JWTPlaintextKey` and pass it to the `JWTToken` constructor:
use NoccyLabs\SimpleJwt\Key\{JwtDerivedKey,JwtPlaintextKey} use NoccyLabs\SimpleJWT\Key\{JWTDerivedKey,JWTPlaintextKey}
// Derive a key using secret and salt... // Derive a key using secret and salt...
$key = new JwtDerivedKey("secret", "salt"); $key = new JWTDerivedKey("secret", "salt");
// ...or use a prepared plaintext key // ...or use a prepared plaintext key
$key = new JwtPlaintextKey("This Should Be Binary Data.."); $key = new JWTPlaintextKey("This Should Be Binary Data..");
### Generating tokens ### Generating tokens
use NoccyLabs\SimpleJwt\JwtToken; use NoccyLabs\SimpleJWT\JWTToken;
$tok = new JwtToken($key); $tok = new JWTToken($key);
$tok->setExpiry("1h"); $tok->setExpiry("1h");
$tok->claims->add("some/claim/MaxItems", 8); $tok->claims->add("some/claim/MaxItems", 8);
@ -54,11 +54,11 @@ or a `JwtPlaintextKey` and pass it to the `JwtToken` constructor:
Parsing is done by passing the raw token as the 2nd parameter Parsing is done by passing the raw token as the 2nd parameter
use NoccyLabs\SimpleJwt\JwtToken; use NoccyLabs\SimpleJWT\JWTToken;
$str = "...received token..."; $str = "...received token...";
$tok = new JwtToken($key, $str); $tok = new JWTToken($key, $str);
if (!$tok->isValid()) { if (!$tok->isValid()) {
// This check works, but using the validator might be better // This check works, but using the validator might be better
@ -75,9 +75,9 @@ Parsing is done by passing the raw token as the 2nd parameter
### Validating tokens ### Validating tokens
use NoccyLabs\SimpleJwt\Validator\JwtValidator; use NoccyLabs\SimpleJWT\Validator\JWTValidator;
$validator = new JwtValidator(); $validator = new JWTValidator();
// Require that some claim exists // Require that some claim exists
$validator $validator
->requireIssuer("api.issuer.tld") ->requireIssuer("api.issuer.tld")
@ -85,11 +85,11 @@ Parsing is done by passing the raw token as the 2nd parameter
->addRequiredClaim("some/required/Claim"); ->addRequiredClaim("some/required/Claim");
try { try {
// Pass a JwtToken to validateToken()... // Pass a JWTToken to validateToken()...
$valid = $validator->validateToken($tok); $valid = $validator->validateToken($tok);
// ...or pass a JwtKeyInterface and the raw string to validate() // ...or pass a JWTKeyInterface and the raw string to validate()
$valid = $validator->validate($key, $tokenstr); $valid = $validator->validate($key, $tokenstr);
} }
catch (JwtValidatorException $e) { catch (JWTValidatorException $e) {
// validation failed // validation failed
} }

View File

@ -11,7 +11,15 @@
], ],
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"NoccyLabs\\SimpleJwt\\": "src/" "NoccyLabs\\SimpleJWT\\": "src/"
} }
},
"require": {
"php": "^7.4|^8.0",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.10"
} }
} }

12
phpstan.neon Normal file
View File

@ -0,0 +1,12 @@
parameters:
level: 5
excludePaths:
- doc
- vendor
- tests
# Paths to include in the analysis
paths:
- src

View File

@ -1,22 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" beStrictAboutOutputDuringTests="true" cacheDirectory=".phpunit.cache" requireCoverageMetadata="true" beStrictAboutCoverageMetadata="true">
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd" <coverage>
bootstrap="vendor/autoload.php" <include>
executionOrder="depends,defects" <directory suffix=".php">src</directory>
forceCoversAnnotation="true" </include>
beStrictAboutCoversAnnotation="true" </coverage>
beStrictAboutOutputDuringTests="true" <testsuites>
beStrictAboutTodoAnnotatedTests="true" <testsuite name="default">
verbose="true"> <directory suffix="Test.php">tests</directory>
<testsuites> </testsuite>
<testsuite name="default"> </testsuites>
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit> </phpunit>

View File

@ -1,6 +1,6 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Collection; namespace NoccyLabs\SimpleJWT\Collection;
use ArrayAccess; use ArrayAccess;
use Countable; use Countable;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Collection; namespace NoccyLabs\SimpleJWT\Collection;
class PropertyException extends \RuntimeException class PropertyException extends \RuntimeException

View File

@ -1,9 +1,9 @@
<?php <?php
namespace NoccyLabs\SimpleJwt; namespace NoccyLabs\SimpleJWT;
use NoccyLabs\SimpleJwt\Collection\PropertyBag; use NoccyLabs\SimpleJWT\Collection\PropertyBag;
use NoccyLabs\SimpleJwt\Key\KeyInterface; use NoccyLabs\SimpleJWT\Key\KeyInterface;
/** /**
* *
@ -13,7 +13,7 @@ use NoccyLabs\SimpleJwt\Key\KeyInterface;
* @property-read header PropertyBag * @property-read header PropertyBag
* @property-read claim PropertyBag * @property-read claim PropertyBag
*/ */
class JwtToken class JWTToken
{ {
/** @var PropertyBag */ /** @var PropertyBag */
private $header; private $header;
@ -54,13 +54,13 @@ class JwtToken
$this->generated = false; $this->generated = false;
[ $header, $payload, $signature ] = explode(".", trim($token), 3); [ $header, $payload, $signature ] = explode(".", trim($token), 3);
$hash = JwtUtil::encode(hash_hmac("sha256", $header.".".$payload, $this->key->getBinaryKey(), true)); $hash = JWTUtil::encode(hash_hmac("sha256", $header.".".$payload, $this->key->getBinaryKey(), true));
if ($signature == $hash) { if ($signature == $hash) {
$this->valid = true; $this->valid = true;
} }
$this->header = new PropertyBag(json_decode(JwtUtil::decode($header), true)); $this->header = new PropertyBag(json_decode(JWTUtil::decode($header), true));
$this->claims = new PropertyBag(json_decode(JwtUtil::decode($payload), true)); $this->claims = new PropertyBag(json_decode(JWTUtil::decode($payload), true));
if ($this->header->has('exp')) { if ($this->header->has('exp')) {
$exp = intval($this->header->get('exp')); $exp = intval($this->header->get('exp'));
@ -136,9 +136,9 @@ class JwtToken
public function getSignedToken(): string public function getSignedToken(): string
{ {
$header = JwtUtil::encode($this->header->getJson()); $header = JWTUtil::encode($this->header->getJson());
$payload = JwtUtil::encode($this->claims->getJson()); $payload = JWTUtil::encode($this->claims->getJson());
$hash = JwtUtil::encode(hash_hmac("sha256", $header.".".$payload, $this->key->getBinaryKey(), true)); $hash = JWTUtil::encode(hash_hmac("sha256", $header.".".$payload, $this->key->getBinaryKey(), true));
return $header.".".$payload.".".$hash; return $header.".".$payload.".".$hash;
} }

View File

@ -1,9 +1,9 @@
<?php <?php
namespace NoccyLabs\SimpleJwt; namespace NoccyLabs\SimpleJWT;
class JwtUtil class JWTUtil
{ {
public static function encode($data) { public static function encode($data) {
return rtrim(str_replace(['+', '/'], ['-', '_'], base64_encode($data)), "="); return rtrim(str_replace(['+', '/'], ['-', '_'], base64_encode($data)), "=");

View File

@ -1,8 +1,8 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Key; namespace NoccyLabs\SimpleJWT\Key;
class JwtDerivedKey implements KeyInterface class JWTDerivedKey implements KeyInterface
{ {
private $key; private $key;

View File

@ -1,8 +1,8 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Key; namespace NoccyLabs\SimpleJWT\Key;
class JwtPlaintextKey implements KeyInterface class JWTPlaintextKey implements KeyInterface
{ {
private $key; private $key;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Key; namespace NoccyLabs\SimpleJWT\Key;
interface KeyInterface interface KeyInterface
{ {

View File

@ -0,0 +1,9 @@
<?php
namespace NoccyLabs\SimpleJWT\Validator;
class JWTClaimException extends JWTValidatorException
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\SimpleJWT\Validator;
class JWTHeaderException extends JWTValidatorException
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\SimpleJWT\Validator;
class JWTTokenException extends JWTValidatorException
{
}

View File

@ -1,11 +1,11 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Validator; namespace NoccyLabs\SimpleJWT\Validator;
use NoccyLabs\SimpleJwt\JwtToken; use NoccyLabs\SimpleJWT\JWTToken;
use NoccyLabs\SimpleJwt\Key\KeyInterface; use NoccyLabs\SimpleJWT\Key\KeyInterface;
class JwtValidator class JWTValidator
{ {
private $requireHeaders = []; private $requireHeaders = [];
@ -41,32 +41,32 @@ class JwtValidator
$this->requireAudience = (array)$audience; $this->requireAudience = (array)$audience;
} }
public function validateToken(JwtToken $token) public function validateToken(JWTToken $token)
{ {
if (!$token->isValid()) { if (!$token->isValid()) {
throw new JwtTokenException("The token is not valid"); throw new JWTTokenException("The token is not valid");
} }
if (!$token->header->hasAll($this->requireHeaders)) { if (!$token->header->hasAll($this->requireHeaders)) {
throw new JwtHeaderException("The token is missing one or more required headers"); throw new JWTHeaderException("The token is missing one or more required headers");
} }
if (!$token->claims->hasAll($this->requireClaims)) { if (!$token->claims->hasAll($this->requireClaims)) {
throw new JwtHeaderException("The token is missing one or more required claims"); throw new JWTHeaderException("The token is missing one or more required claims");
} }
if ($this->requireIssuer) { if ($this->requireIssuer) {
$hasIssuer = $token->header->has("iss"); $hasIssuer = $token->header->has("iss");
if ((!$hasIssuer) if ((!$hasIssuer)
|| (!in_array($token->header->get("iss"), $this->requireIssuer))) || (!in_array($token->header->get("iss"), $this->requireIssuer)))
throw new JwtTokenException("Invalid issuer"); throw new JWTTokenException("Invalid issuer");
} }
if ($this->requireAudience) { if ($this->requireAudience) {
$hasAudience = $token->header->has("aud"); $hasAudience = $token->header->has("aud");
if ((!$hasAudience) if ((!$hasAudience)
|| (!in_array($token->header->get("aud"), $this->requireAudience))) || (!in_array($token->header->get("aud"), $this->requireAudience)))
throw new JwtTokenException("Invalid audience"); throw new JWTTokenException("Invalid audience");
} }
return true; return true;
@ -74,7 +74,7 @@ class JwtValidator
public function validate(KeyInterface $key, string $raw) public function validate(KeyInterface $key, string $raw)
{ {
$token = new JwtToken($key, $raw); $token = new JWTToken($key, $raw);
if ($this->validateToken($token)) { if ($this->validateToken($token)) {
return $token; return $token;
} }

View File

@ -0,0 +1,8 @@
<?php
namespace NoccyLabs\SimpleJWT\Validator;
class JWTValidatorException extends \RuntimeException
{
}

View File

@ -1,9 +0,0 @@
<?php
namespace NoccyLabs\SimpleJwt\Validator;
class JwtClaimException extends JwtValidatorException
{
}

View File

@ -1,8 +0,0 @@
<?php
namespace NoccyLabs\SimpleJwt\Validator;
class JwtHeaderException extends JwtValidatorException
{
}

View File

@ -1,8 +0,0 @@
<?php
namespace NoccyLabs\SimpleJwt\Validator;
class JwtTokenException extends JwtValidatorException
{
}

View File

@ -1,8 +0,0 @@
<?php
namespace NoccyLabs\SimpleJwt\Validator;
class JwtValidatorException extends \RuntimeException
{
}

View File

@ -1,17 +1,20 @@
<?php <?php
namespace NoccyLabs\SimpleJwt; namespace NoccyLabs\SimpleJWT;
use NoccyLabs\SimpleJwt\Key\JwtPlaintextKey; use NoccyLabs\SimpleJWT\Key\JWTPlaintextKey;
class JwtTokenTest extends \PhpUnit\Framework\TestCase class JWTTokenTest extends \PHPUnit\Framework\TestCase
{ {
/**
* @covers
*/
public function testGeneratingTokens() public function testGeneratingTokens()
{ {
$key = new JwtPlaintextKey("test"); $key = new JWTPlaintextKey("test");
$tok = new JwtToken($key); $tok = new JWTToken($key);
$tok->addClaim("foo", true); $tok->addClaim("foo", true);
$token = $tok->getSignedToken(); $token = $tok->getSignedToken();
@ -20,19 +23,22 @@ class JwtTokenTest extends \PhpUnit\Framework\TestCase
$this->assertTrue($tok->isGenerated()); $this->assertTrue($tok->isGenerated());
} }
/**
* @covers
*/
public function testParsingTokens() public function testParsingTokens()
{ {
$key = new JwtPlaintextKey("test"); $key = new JWTPlaintextKey("test");
$tok = new JwtToken($key); $tok = new JWTToken($key);
$tok->addClaim("foo", true); $tok->addClaim("foo", true);
$token = $tok->getSignedToken(); $token = $tok->getSignedToken();
$parsed = new JwtToken($key, $token); $parsed = new JWTToken($key, $token);
$this->assertTrue($parsed->isValid()); $this->assertTrue($parsed->isValid());
$this->assertFalse($parsed->isGenerated()); $this->assertFalse($parsed->isGenerated());
} }
} }

View File

@ -1,18 +1,21 @@
<?php <?php
namespace NoccyLabs\SimpleJwt; namespace NoccyLabs\SimpleJWT;
class JwtUtilTest extends \PhpUnit\Framework\TestCase class JWTUtilTest extends \PHPUnit\Framework\TestCase
{ {
/**
* @covers
*/
public function testTheEncodingShouldBeSymmetric() public function testTheEncodingShouldBeSymmetric()
{ {
$v1a = "HelloWorld"; $v1a = "HelloWorld";
$v1b = JwtUtil::encode($v1a); $v1b = JWTUtil::encode($v1a);
$v1c = JwtUtil::decode($v1b); $v1c = JWTUtil::decode($v1b);
$this->assertEquals($v1a, $v1c); $this->assertEquals($v1a, $v1c);
$this->assertNotEquals($v1a, $v1b); $this->assertNotEquals($v1a, $v1b);
} }
} }

View File

@ -1,37 +1,43 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Key; namespace NoccyLabs\SimpleJWT\Key;
class JwtDerivedKeyTest extends \PhpUnit\Framework\TestCase class JWTDerivedKeyTest extends \PHPUnit\Framework\TestCase
{ {
/**
* @covers
*/
public function testTheDerivedKeysShouldBeConsistent() public function testTheDerivedKeysShouldBeConsistent()
{ {
$key1a = new JwtDerivedKey("foo", "foosalt"); $key1a = new JWTDerivedKey("foo", "foosalt");
$key1b = new JwtDerivedKey("foo", "foosalt"); $key1b = new JWTDerivedKey("foo", "foosalt");
$this->assertNotNull($key1a); $this->assertNotNull($key1a);
$this->assertEquals($key1a->getBinaryKey(), $key1b->getBinaryKey()); $this->assertEquals($key1a->getBinaryKey(), $key1b->getBinaryKey());
$key2a = new JwtDerivedKey("bar", "foosalt"); $key2a = new JWTDerivedKey("bar", "foosalt");
$key2b = new JwtDerivedKey("bar", "barsalt"); $key2b = new JWTDerivedKey("bar", "barsalt");
$key2c = new JwtDerivedKey("bar", "barsalt"); $key2c = new JWTDerivedKey("bar", "barsalt");
$this->assertNotNull($key2a); $this->assertNotNull($key2a);
$this->assertNotEquals($key2a->getBinaryKey(), $key2b->getBinaryKey()); $this->assertNotEquals($key2a->getBinaryKey(), $key2b->getBinaryKey());
$this->assertEquals($key2b->getBinaryKey(), $key2c->getBinaryKey()); $this->assertEquals($key2b->getBinaryKey(), $key2c->getBinaryKey());
} }
/**
* @covers
*/
public function testTheDerivedKeysShouldBeUnique() public function testTheDerivedKeysShouldBeUnique()
{ {
$keys = []; $keys = [];
$keys[] = (new JwtDerivedKey("foo", "foosalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("foo", "foosalt"))->getBinaryKey();
$keys[] = (new JwtDerivedKey("foo", "barsalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("foo", "barsalt"))->getBinaryKey();
$keys[] = (new JwtDerivedKey("foo", "bazsalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("foo", "bazsalt"))->getBinaryKey();
$keys[] = (new JwtDerivedKey("bar", "foosalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("bar", "foosalt"))->getBinaryKey();
$keys[] = (new JwtDerivedKey("bar", "barsalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("bar", "barsalt"))->getBinaryKey();
$keys[] = (new JwtDerivedKey("bar", "bazsalt"))->getBinaryKey(); $keys[] = (new JWTDerivedKey("bar", "bazsalt"))->getBinaryKey();
$unique = array_unique($keys); $unique = array_unique($keys);
$this->assertEquals(count($keys), count($unique)); $this->assertEquals(count($keys), count($unique));
} }
} }

View File

@ -1,16 +1,19 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Key; namespace NoccyLabs\SimpleJWT\Key;
class JwtPlaintextKeyTest extends \PhpUnit\Framework\TestCase class JWTPlaintextKeyTest extends \PHPUnit\Framework\TestCase
{ {
/**
* @covers
*/
public function testThePlaintextKeyShouldBeReturned() public function testThePlaintextKeyShouldBeReturned()
{ {
$key = new JwtPlaintextKey("foo"); $key = new JWTPlaintextKey("foo");
$this->assertEquals("foo", $key->getBinaryKey()); $this->assertEquals("foo", $key->getBinaryKey());
$key = new JwtPlaintextKey("bar"); $key = new JWTPlaintextKey("bar");
$this->assertEquals("bar", $key->getBinaryKey()); $this->assertEquals("bar", $key->getBinaryKey());
} }
} }

View File

@ -1,49 +1,56 @@
<?php <?php
namespace NoccyLabs\SimpleJwt\Validator; namespace NoccyLabs\SimpleJWT\Validator;
use NoccyLabs\SimpleJwt\JwtToken; use NoccyLabs\SimpleJWT\JWTToken;
use NoccyLabs\SimpleJwt\Key\JwtPlaintextKey; use NoccyLabs\SimpleJWT\Key\JWTPlaintextKey;
class JwtValidatorTest extends \PhpUnit\Framework\TestCase class JWTValidatorTest extends \PHPUnit\Framework\TestCase
{ {
/**
* @covers
*/
public function testValidTokensShouldPassWithDefaultConfiguration() public function testValidTokensShouldPassWithDefaultConfiguration()
{ {
$key = new JwtPlaintextKey("key"); $key = new JWTPlaintextKey("key");
$token = new JwtToken($key); $token = new JWTToken($key);
$validator = new JwtValidator(); $validator = new JWTValidator();
$valid = $validator->validateToken($token); $valid = $validator->validateToken($token);
$this->assertEquals(true, $valid); $this->assertEquals(true, $valid);
} }
/**
* @covers
*/
public function testExpiredTokensShouldFailWithException() public function testExpiredTokensShouldFailWithException()
{ {
$key = new JwtPlaintextKey("key"); $key = new JWTPlaintextKey("key");
$token = new JwtToken($key); $token = new JWTToken($key);
$token->header->set("exp", 0); $token->header->set("exp", 0);
$token = new JwtToken($key, $token->getSignedToken()); $token = new JWTToken($key, $token->getSignedToken());
$validator = new JwtValidator(); $validator = new JWTValidator();
$this->expectException(JwtTokenException::class); $this->expectException(JWTTokenException::class);
$valid = $validator->validateToken($token); $valid = $validator->validateToken($token);
} }
/** /**
* @covers
* @dataProvider tokenGenerator * @dataProvider tokenGenerator
*/ */
public function testPinningIssuer($issuer,$audience,$key,$token) public function testPinningIssuer($issuer,$audience,$key,$token)
{ {
$goodIssuer = "a-dom.tld"; $goodIssuer = "a-dom.tld";
$jwtKey = new JwtPlaintextKey($key); $jwtKey = new JWTPlaintextKey($key);
$jwtToken = new JwtToken($jwtKey, $token); $jwtToken = new JWTToken($jwtKey, $token);
$validator = new JwtValidator(); $validator = new JWTValidator();
$validator->requireIssuer($goodIssuer); $validator->requireIssuer($goodIssuer);
if ($goodIssuer != $issuer) { if ($goodIssuer != $issuer) {
$this->expectException(JwtTokenException::class); $this->expectException(JWTTokenException::class);
} }
$valid = $validator->validateToken($jwtToken); $valid = $validator->validateToken($jwtToken);
if ($goodIssuer == $issuer) { if ($goodIssuer == $issuer) {
@ -52,18 +59,19 @@ class JwtValidatorTest extends \PhpUnit\Framework\TestCase
} }
/** /**
* @covers
* @dataProvider tokenGenerator * @dataProvider tokenGenerator
*/ */
public function testPinningAudience($issuer,$audience,$key,$token) public function testPinningAudience($issuer,$audience,$key,$token)
{ {
$goodAudience = [ "a-dom.tld", "app.a-dom.tld" ]; $goodAudience = [ "a-dom.tld", "app.a-dom.tld" ];
$jwtKey = new JwtPlaintextKey($key); $jwtKey = new JWTPlaintextKey($key);
$jwtToken = new JwtToken($jwtKey, $token); $jwtToken = new JWTToken($jwtKey, $token);
$validator = new JwtValidator(); $validator = new JWTValidator();
$validator->requireAudience($goodAudience); $validator->requireAudience($goodAudience);
if (!in_array($audience, $goodAudience)) { if (!in_array($audience, $goodAudience)) {
$this->expectException(JwtTokenException::class); $this->expectException(JWTTokenException::class);
} }
$valid = $validator->validateToken($jwtToken); $valid = $validator->validateToken($jwtToken);
if (in_array($audience, $goodAudience)) { if (in_array($audience, $goodAudience)) {
@ -72,20 +80,21 @@ class JwtValidatorTest extends \PhpUnit\Framework\TestCase
} }
/** /**
* @covers
* @dataProvider tokenGenerator * @dataProvider tokenGenerator
*/ */
public function testPinningBoth($issuer,$audience,$key,$token) public function testPinningBoth($issuer,$audience,$key,$token)
{ {
$goodIssuer = "a-dom.tld"; $goodIssuer = "a-dom.tld";
$goodAudience = [ "a-dom.tld", "app.a-dom.tld" ]; $goodAudience = [ "a-dom.tld", "app.a-dom.tld" ];
$jwtKey = new JwtPlaintextKey($key); $jwtKey = new JWTPlaintextKey($key);
$jwtToken = new JwtToken($jwtKey, $token); $jwtToken = new JWTToken($jwtKey, $token);
$validator = new JwtValidator(); $validator = new JWTValidator();
$validator->requireIssuer($goodIssuer); $validator->requireIssuer($goodIssuer);
$validator->requireAudience($goodAudience); $validator->requireAudience($goodAudience);
if (($goodIssuer != $issuer) || (!in_array($audience, $goodAudience))) { if (($goodIssuer != $issuer) || (!in_array($audience, $goodAudience))) {
$this->expectException(JwtTokenException::class); $this->expectException(JWTTokenException::class);
} }
$valid = $validator->validateToken($jwtToken); $valid = $validator->validateToken($jwtToken);
if (($goodIssuer == $issuer) && (in_array($audience, $goodAudience))) { if (($goodIssuer == $issuer) && (in_array($audience, $goodAudience))) {
@ -93,21 +102,21 @@ class JwtValidatorTest extends \PhpUnit\Framework\TestCase
} }
} }
public function tokenGenerator() public static function tokenGenerator()
{ {
$keyrand = function () { $keyrand = function () {
return substr(sha1(microtime(true).rand(0,65535)), 5, 10); return substr(sha1(microtime(true).rand(0,65535)), 5, 10);
}; };
$token = function ($head,$claims,$key) { $token = function ($head,$claims,$key) {
$jwtKey = new JwtPlaintextKey($key); $jwtKey = new JWTPlaintextKey($key);
$tok = new JwtToken($jwtKey); $tok = new JWTToken($jwtKey);
$tok->header->setAll($head); $tok->header->setAll($head);
$tok->claims->setAll($claims); $tok->claims->setAll($claims);
return $tok->getSignedToken(); return $tok->getSignedToken();
}; };
$row = function ($iss, $aud, array $claims) use ($keyrand, $token) { $row = function ($iss, $aud, array $claims) use ($keyrand, $token) {
$key = $keyrand(); $key = $keyrand();
$jwtKey = new JwtPlaintextKey($key); $jwtKey = new JWTPlaintextKey($key);
return [ return [
$iss, $iss,
$aud, $aud,