added predis and eseye back in.

This commit is contained in:
2020-12-25 11:28:41 +00:00
parent 0ddd298350
commit 017f72b42e
670 changed files with 60992 additions and 10 deletions

View File

@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Checker\InvalidHeaderException;
use PHPUnit\Framework\TestCase;
/**
* @group HeaderChecker
* @group functional
*
* @internal
*/
class AlgorithmHeaderCheckerTest extends TestCase
{
/**
* @test
*/
public function anAlgorithmMustBeAString(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('"alg" must be a string.');
$checker = new AlgorithmChecker(['foo']);
$checker->checkHeader(1);
}
/**
* @test
*/
public function theAlgorithmHeaderIsNotAllowed(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('Unsupported algorithm.');
$checker = new AlgorithmChecker(['foo']);
$checker->checkHeader('bar');
}
/**
* @test
*/
public function theAlgorithmHeaderIsSupported(): void
{
$checker = new AlgorithmChecker(['foo']);
$checker->checkHeader('foo');
static::assertFalse($checker->protectedHeaderOnly());
static::assertEquals('alg', $checker->supportedHeader());
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\InvalidClaimException;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group functional
*
* @internal
*/
class AudienceClaimCheckerTest extends TestCase
{
/**
* @test
*/
public function anAudienceClaimMustBeAStringOrAnArrayOfStrings(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkClaim(1);
}
/**
* @test
*/
public function theAudienceClaimIsNotKnown(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkClaim('bar');
}
/**
* @test
*/
public function theAudienceClaimListDoesNotContainTheCurrentAudience(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkClaim(['bar']);
}
/**
* @test
*/
public function theAudienceClaimIsSupported(): void
{
$checker = new AudienceChecker('foo');
$checker->checkClaim('foo');
$checker->checkClaim(['foo']);
static::assertEquals('aud', $checker->supportedClaim());
}
}

View File

@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\InvalidHeaderException;
use PHPUnit\Framework\TestCase;
/**
* @group HeaderChecker
* @group functional
*
* @internal
*/
class AudienceHeaderCheckerTest extends TestCase
{
/**
* @test
*/
public function anAudienceHeaderMustBeAStringOrAnArrayOfStrings(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkHeader(1);
}
/**
* @test
*/
public function theAudienceHeaderIsNotKnown(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkHeader('bar');
}
/**
* @test
*/
public function theAudienceHeaderListDoesNotContainTheCurrentAudience(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('Bad audience.');
$checker = new AudienceChecker('foo');
$checker->checkHeader(['bar']);
}
/**
* @test
*/
public function theAudienceHeaderIsSupported(): void
{
$checker = new AudienceChecker('foo');
$checker->checkHeader('foo');
$checker->checkHeader(['foo']);
static::assertFalse($checker->protectedHeaderOnly());
static::assertEquals('aud', $checker->supportedHeader());
}
}

View File

@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use InvalidArgumentException;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\ClaimCheckerManagerFactory;
use Jose\Component\Checker\ExpirationTimeChecker;
use Jose\Component\Checker\IssuedAtChecker;
use Jose\Component\Checker\NotBeforeChecker;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group functional
*
* @internal
*/
class ClaimCheckerManagerFactoryTest extends TestCase
{
/**
* @var null|ClaimCheckerManagerFactory
*/
private $claimCheckerManagerFactory;
/**
* @test
*/
public function theAliasListOfTheClaimCheckerManagerFactoryIsAvailable(): void
{
static::assertEquals(['exp', 'iat', 'nbf', 'aud'], $this->getClaimCheckerManagerFactory()->aliases());
}
/**
* @test
*/
public function theAliasDoesNotExist(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The claim checker with the alias "foo" is not supported.');
$this->getClaimCheckerManagerFactory()->create(['foo']);
}
/**
* @test
*/
public function iCanCreateAClaimCheckerManager(): void
{
$manager = $this->getClaimCheckerManagerFactory()->create(['exp', 'iat', 'nbf', 'aud']);
static::assertCount(4, $manager->getCheckers());
}
/**
* @test
*/
public function iCanCheckValidPayloadClaims(): void
{
$payload = [
'exp' => time() + 3600,
'iat' => time() - 1000,
'nbf' => time() - 100,
'foo' => 'bar',
];
$expected = $payload;
unset($expected['foo']);
$manager = $this->getClaimCheckerManagerFactory()->create(['exp', 'iat', 'nbf', 'aud']);
$result = $manager->check($payload);
static::assertEquals($expected, $result);
}
/**
* @test
*/
public function theMandatoryClaimsAreNotSet(): void
{
$this->expectException(\Jose\Component\Checker\MissingMandatoryClaimException::class);
$this->expectExceptionMessage('The following claims are mandatory: bar.');
$payload = [
'exp' => time() + 3600,
'iat' => time() - 1000,
'nbf' => time() - 100,
'foo' => 'bar',
];
$expected = $payload;
unset($expected['foo']);
$manager = $this->getClaimCheckerManagerFactory()->create(['exp', 'iat', 'nbf', 'aud']);
$manager->check($payload, ['exp', 'foo', 'bar']);
}
private function getClaimCheckerManagerFactory(): ClaimCheckerManagerFactory
{
if (null === $this->claimCheckerManagerFactory) {
$this->claimCheckerManagerFactory = new ClaimCheckerManagerFactory();
$this->claimCheckerManagerFactory->add('exp', new ExpirationTimeChecker());
$this->claimCheckerManagerFactory->add('iat', new IssuedAtChecker());
$this->claimCheckerManagerFactory->add('nbf', new NotBeforeChecker());
$this->claimCheckerManagerFactory->add('aud', new AudienceChecker('My Service'));
}
return $this->claimCheckerManagerFactory;
}
}

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\ClaimCheckerManager;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group unit
*
* @internal
*/
final class ClaimCheckerManagerTest extends TestCase
{
/**
* @covers \Jose\Component\Checker\AudienceChecker
* @covers \Jose\Component\Checker\ClaimCheckerManager
* @test
*/
public function getCheckers(): void
{
$checkers = [
new AudienceChecker('some-expected-audience'),
];
$expectedCheckers = [
'aud' => $checkers[0],
];
$sut = new ClaimCheckerManager($checkers);
static::assertEquals(
$expectedCheckers,
$sut->getCheckers()
);
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\ExpirationTimeChecker;
use Jose\Component\Checker\InvalidClaimException;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group functional
*
* @internal
*/
class ExpirationTimeClaimCheckerTest extends TestCase
{
/**
* @test
*/
public function theExpirationTimeClaimMustBeAnInteger(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('"exp" must be an integer.');
$checker = new ExpirationTimeChecker();
$checker->checkClaim('foo');
}
/**
* @test
*/
public function theExpirationTimeIsInThePast(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('The token expired.');
$checker = new ExpirationTimeChecker();
$checker->checkClaim(time() - 1);
}
/**
* @test
*/
public function theExpirationTimeIsInTheFutur(): void
{
$checker = new ExpirationTimeChecker();
$checker->checkClaim(time() + 3600);
static::assertEquals('exp', $checker->supportedClaim());
}
}

View File

@@ -0,0 +1,183 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use InvalidArgumentException;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\HeaderCheckerManagerFactory;
use Jose\Component\Checker\InvalidHeaderException;
use Jose\Component\Checker\IssuerChecker;
use Jose\Component\Checker\MissingMandatoryHeaderParameterException;
use Jose\Component\Checker\Tests\Stub\OtherToken;
use Jose\Component\Checker\Tests\Stub\Token;
use Jose\Component\Checker\Tests\Stub\TokenSupport;
use PHPUnit\Framework\TestCase;
/**
* @group HeaderChecker
* @group functional
*
* @internal
*/
class HeaderCheckerManagerFactoryTest extends TestCase
{
/**
* @var null|HeaderCheckerManagerFactory
*/
private $headerCheckerManagerFactory;
/**
* @test
*/
public function theAliasListOfTheHeaderCheckerManagerFactoryIsAvailable(): void
{
static::assertEquals(['aud', 'iss'], $this->getHeaderCheckerManagerFactory()->aliases());
}
/**
* @test
*/
public function aHeaderMustNotContainDuplicatedHeaderParameters(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The header contains duplicated entries: alg.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['alg' => 'foo'];
$unprotected = ['alg' => 'foo'];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theTokenHasCriticalHeaderNotSatisfied(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('One or more header parameters are marked as critical, but they are missing or have not been checked: alg.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['crit' => ['alg']];
$unprotected = [];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theHeaderIsSuccessfullyChecked(): void
{
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['crit' => ['aud'], 'aud' => 'My Service'];
$unprotected = ['iss' => 'Another Service'];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theCriticalHeaderParameterMustBeProtected(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('The header parameter "crit" must be protected.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['aud' => 'My Service'];
$unprotected = ['crit' => ['aud']];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theCriticalHeaderParameterMustBeAListOfHeaderParameters(): void
{
$this->expectException(InvalidHeaderException::class);
$this->expectExceptionMessage('The header "crit" must be a list of header parameters.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['aud' => 'My Service', 'crit' => true];
$unprotected = [];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theHeaderContainsUnknownParametersAndIsSuccessfullyChecked(): void
{
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['foo' => 'bar', 'iss' => 'Another Service'];
$unprotected = [];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
/**
* @test
*/
public function theHeaderDoesNotContainSomeMandatoryParameters(): void
{
$this->expectException(MissingMandatoryHeaderParameterException::class);
$this->expectExceptionMessage('The following header parameters are mandatory: mandatory.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['aud' => 'Audience', 'iss' => 'Another Service'];
$unprotected = ['foo' => 'bar'];
$token = new Token(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0, ['aud', 'iss', 'mandatory']);
}
/**
* @test
*/
public function iTryToCheckATokenThatIsNotSupported(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Unsupported token type.');
$headerCheckerManager = $this->getHeaderCheckerManagerFactory()->create(['aud', 'iss']);
$payload = [];
$protected = ['foo' => 'bar'];
$unprotected = [];
$token = new OtherToken(json_encode($payload), $protected, $unprotected);
$headerCheckerManager->check($token, 0);
}
private function getHeaderCheckerManagerFactory(): HeaderCheckerManagerFactory
{
if (null === $this->headerCheckerManagerFactory) {
$this->headerCheckerManagerFactory = new HeaderCheckerManagerFactory();
$this->headerCheckerManagerFactory->add('aud', new AudienceChecker('My Service', true));
$this->headerCheckerManagerFactory->add('iss', new IssuerChecker(['Another Service']));
$this->headerCheckerManagerFactory->addTokenTypeSupport(new TokenSupport());
}
return $this->headerCheckerManagerFactory;
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\InvalidClaimException;
use Jose\Component\Checker\IssuedAtChecker;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group functional
*
* @internal
*/
class IssuedAtClaimCheckerTest extends TestCase
{
/**
* @test
*/
public function anIssuedAtClaimMustBeAnInteger(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('"iat" must be an integer.');
$checker = new IssuedAtChecker();
$checker->checkClaim('foo');
}
/**
* @test
*/
public function theIssuedAtClaimIsInTheFutur(): void
{
$this->expectException(InvalidClaimException::class);
$this->expectExceptionMessage('The JWT is issued in the future.');
$checker = new IssuedAtChecker();
$checker->checkClaim(time() + 3600);
}
/**
* @test
*/
public function theIssuedAtClaimIsInThePast(): void
{
$checker = new IssuedAtChecker();
$checker->checkClaim(time() - 3600);
static::assertEquals('iat', $checker->supportedClaim());
}
}

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\NotBeforeChecker;
use PHPUnit\Framework\TestCase;
/**
* @group ClaimChecker
* @group functional
*
* @internal
*/
class NotBeforeClaimCheckerTest extends TestCase
{
/**
* @test
*/
public function theNotBeforeClaimMustBeAnInteger(): void
{
$this->expectException(\Jose\Component\Checker\InvalidClaimException::class);
$this->expectExceptionMessage('"nbf" must be an integer.');
$checker = new NotBeforeChecker();
$checker->checkClaim('foo');
}
/**
* @test
*/
public function theNotBeforeClaimIsInTheFutur(): void
{
$this->expectException(\Jose\Component\Checker\InvalidClaimException::class);
$this->expectExceptionMessage('The JWT can not be used yet.');
$checker = new NotBeforeChecker();
$checker->checkClaim(time() + 3600);
}
/**
* @test
*/
public function theNotBeforeClaimIsInThePast(): void
{
$checker = new NotBeforeChecker();
$checker->checkClaim(time() - 3600);
static::assertEquals('nbf', $checker->supportedClaim());
}
}

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests\Stub;
use Jose\Component\Core\JWT;
class OtherToken implements JWT
{
/**
* @var null|string
*/
private $payload;
/**
* @var array
*/
private $protectedHeader;
/**
* @var array
*/
private $unprotectedHeader;
public function __construct(?string $payload, array $protectedHeader, array $unprotectedHeader)
{
$this->payload = $payload;
$this->protectedHeader = $protectedHeader;
$this->unprotectedHeader = $unprotectedHeader;
}
public function getPayload(): ?string
{
return $this->payload;
}
public function getProtectedHeader(): array
{
return $this->protectedHeader;
}
public function getUnprotectedHeader(): array
{
return $this->unprotectedHeader;
}
}

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests\Stub;
use Jose\Component\Core\JWT;
class Token implements JWT
{
/**
* @var null|string
*/
private $payload;
/**
* @var array
*/
private $protectedHeader;
/**
* @var array
*/
private $unprotectedHeader;
public function __construct(?string $payload, array $protectedHeader, array $unprotectedHeader)
{
$this->payload = $payload;
$this->protectedHeader = $protectedHeader;
$this->unprotectedHeader = $unprotectedHeader;
}
public function getPayload(): ?string
{
return $this->payload;
}
public function getProtectedHeader(): array
{
return $this->protectedHeader;
}
public function getUnprotectedHeader(): array
{
return $this->unprotectedHeader;
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests\Stub;
use InvalidArgumentException;
use Jose\Component\Checker\TokenTypeSupport;
use Jose\Component\Core\JWT;
class TokenSupport implements TokenTypeSupport
{
/**
* @throws InvalidArgumentException if the token is not supported
*/
public function retrieveTokenHeaders(JWT $jwt, int $index, array &$protectedHeader, array &$unprotectedHeader): void
{
if (!$jwt instanceof Token) {
throw new InvalidArgumentException('Unsupported token.');
}
$protectedHeader = $jwt->getProtectedHeader();
$unprotectedHeader = $jwt->getUnprotectedHeader();
}
public function supports(JWT $jwt): bool
{
return $jwt instanceof Token;
}
}

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Checker\Tests;
use Jose\Component\Checker\UnencodedPayloadChecker;
use PHPUnit\Framework\TestCase;
/**
* @group HeaderChecker
* @group functional
*
* @internal
*/
class UnencodedPayloadHeaderCheckerTest extends TestCase
{
/**
* @test
*/
public function theB64HeaderMustBeAnBoolean(): void
{
$this->expectException(\Jose\Component\Checker\InvalidHeaderException::class);
$this->expectExceptionMessage('"b64" must be a boolean.');
$checker = new UnencodedPayloadChecker();
$checker->checkHeader('foo');
}
/**
* @test
*/
public function theB64HeaderIsABoolean(): void
{
$checker = new UnencodedPayloadChecker();
$checker->checkHeader(true);
$checker->checkHeader(false);
static::assertTrue($checker->protectedHeaderOnly());
static::assertEquals('b64', $checker->supportedHeader());
}
}