primo commit
This commit is contained in:
46
libraries/vendor/web-token/jwt-library/Checker/AlgorithmChecker.php
vendored
Normal file
46
libraries/vendor/web-token/jwt-library/Checker/AlgorithmChecker.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* This class is a header parameter checker. When the "alg" header parameter is present, it will check if the value is
|
||||
* within the allowed ones.
|
||||
*/
|
||||
final class AlgorithmChecker implements HeaderChecker
|
||||
{
|
||||
private const HEADER_NAME = 'alg';
|
||||
|
||||
/**
|
||||
* @param string[] $supportedAlgorithms
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly array $supportedAlgorithms,
|
||||
private readonly bool $protectedHeader = false
|
||||
) {
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (! is_string($value)) {
|
||||
throw new InvalidHeaderException('"alg" must be a string.', self::HEADER_NAME, $value);
|
||||
}
|
||||
if (! in_array($value, $this->supportedAlgorithms, true)) {
|
||||
throw new InvalidHeaderException('Unsupported algorithm.', self::HEADER_NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::HEADER_NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeader;
|
||||
}
|
||||
}
|
||||
62
libraries/vendor/web-token/jwt-library/Checker/AudienceChecker.php
vendored
Normal file
62
libraries/vendor/web-token/jwt-library/Checker/AudienceChecker.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* This class is a header parameter and claim checker. When the "aud" header parameter or claim is present, it will
|
||||
* check if the value is within the allowed ones.
|
||||
*/
|
||||
final class AudienceChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
private const CLAIM_NAME = 'aud';
|
||||
|
||||
public function __construct(
|
||||
private readonly string $audience,
|
||||
private readonly bool $protectedHeader = false
|
||||
) {
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
$this->checkValue($value, InvalidClaimException::class);
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
$this->checkValue($value, InvalidHeaderException::class);
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return self::CLAIM_NAME;
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::CLAIM_NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeader;
|
||||
}
|
||||
|
||||
private function checkValue(mixed $value, string $class): void
|
||||
{
|
||||
if (is_string($value) && $value !== $this->audience) {
|
||||
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
|
||||
}
|
||||
if (is_array($value) && ! in_array($this->audience, $value, true)) {
|
||||
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
|
||||
}
|
||||
if (! is_array($value) && ! is_string($value)) {
|
||||
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
libraries/vendor/web-token/jwt-library/Checker/CallableChecker.php
vendored
Normal file
58
libraries/vendor/web-token/jwt-library/Checker/CallableChecker.php
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function call_user_func;
|
||||
use function is_callable;
|
||||
|
||||
/**
|
||||
* @see \Jose\Tests\Component\Checker\CallableCheckerTest
|
||||
*/
|
||||
final class CallableChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
/**
|
||||
* @param string $key The claim or header parameter name to check.
|
||||
* @param callable(mixed $value): bool $callable The callable function that will be invoked.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $key,
|
||||
private $callable,
|
||||
private readonly bool $protectedHeaderOnly = true
|
||||
) {
|
||||
if (! is_callable($this->callable)) { // @phpstan-ignore-line
|
||||
throw new InvalidArgumentException('The $callable argument must be a callable.');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
if (call_user_func($this->callable, $value) !== true) {
|
||||
throw new InvalidClaimException(sprintf('The "%s" claim is invalid.', $this->key), $this->key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (call_user_func($this->callable, $value) !== true) {
|
||||
throw new InvalidHeaderException(sprintf('The "%s" header is invalid.', $this->key), $this->key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeaderOnly;
|
||||
}
|
||||
}
|
||||
19
libraries/vendor/web-token/jwt-library/Checker/ClaimChecker.php
vendored
Normal file
19
libraries/vendor/web-token/jwt-library/Checker/ClaimChecker.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
interface ClaimChecker
|
||||
{
|
||||
/**
|
||||
* When the token has the applicable claim, the value is checked. If for some reason the value is not valid, an
|
||||
* InvalidClaimException must be thrown.
|
||||
*/
|
||||
public function checkClaim(mixed $value): void;
|
||||
|
||||
/**
|
||||
* The method returns the claim to be checked.
|
||||
*/
|
||||
public function supportedClaim(): string;
|
||||
}
|
||||
87
libraries/vendor/web-token/jwt-library/Checker/ClaimCheckerManager.php
vendored
Normal file
87
libraries/vendor/web-token/jwt-library/Checker/ClaimCheckerManager.php
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* This manager handles as many claim checkers as needed.
|
||||
*
|
||||
* @see \Jose\Tests\Component\Checker\ClaimCheckerManagerTest
|
||||
*/
|
||||
class ClaimCheckerManager
|
||||
{
|
||||
/**
|
||||
* @var ClaimChecker[]
|
||||
*/
|
||||
private array $checkers = [];
|
||||
|
||||
/**
|
||||
* @param ClaimChecker[] $checkers
|
||||
*/
|
||||
public function __construct(iterable $checkers)
|
||||
{
|
||||
foreach ($checkers as $checker) {
|
||||
$this->add($checker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all checkers handled by this manager.
|
||||
*
|
||||
* @return ClaimChecker[]
|
||||
*/
|
||||
public function getCheckers(): array
|
||||
{
|
||||
return $this->checkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks all the claims passed as argument. All claims are checked against the claim checkers. If one
|
||||
* fails, the InvalidClaimException is thrown.
|
||||
*
|
||||
* This method returns an array with all checked claims. It is up to the implementor to decide use the claims that
|
||||
* have not been checked.
|
||||
*
|
||||
* @param string[] $mandatoryClaims
|
||||
*/
|
||||
public function check(array $claims, array $mandatoryClaims = []): array
|
||||
{
|
||||
$this->checkMandatoryClaims($mandatoryClaims, $claims);
|
||||
$checkedClaims = [];
|
||||
foreach ($this->checkers as $claim => $checker) {
|
||||
if (array_key_exists($claim, $claims)) {
|
||||
$checker->checkClaim($claims[$claim]);
|
||||
$checkedClaims[$claim] = $claims[$claim];
|
||||
}
|
||||
}
|
||||
|
||||
return $checkedClaims;
|
||||
}
|
||||
|
||||
private function add(ClaimChecker $checker): void
|
||||
{
|
||||
$claim = $checker->supportedClaim();
|
||||
$this->checkers[$claim] = $checker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $mandatoryClaims
|
||||
*/
|
||||
private function checkMandatoryClaims(array $mandatoryClaims, array $claims): void
|
||||
{
|
||||
if (count($mandatoryClaims) === 0) {
|
||||
return;
|
||||
}
|
||||
$diff = array_keys(array_diff_key(array_flip($mandatoryClaims), $claims));
|
||||
if (count($diff) !== 0) {
|
||||
throw new MissingMandatoryClaimException(sprintf(
|
||||
'The following claims are mandatory: %s.',
|
||||
implode(', ', $diff)
|
||||
), $diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
libraries/vendor/web-token/jwt-library/Checker/ClaimCheckerManagerFactory.php
vendored
Normal file
68
libraries/vendor/web-token/jwt-library/Checker/ClaimCheckerManagerFactory.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @see \Jose\Tests\Component\Checker\ClaimCheckerManagerFactoryTest
|
||||
*/
|
||||
class ClaimCheckerManagerFactory
|
||||
{
|
||||
/**
|
||||
* @var ClaimChecker[]
|
||||
*/
|
||||
private array $checkers = [];
|
||||
|
||||
/**
|
||||
* This method creates a Claim Checker Manager and populate it with the claim checkers found based on the alias. If
|
||||
* the alias is not supported, an InvalidArgumentException is thrown.
|
||||
*
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
public function create(array $aliases): ClaimCheckerManager
|
||||
{
|
||||
$checkers = [];
|
||||
foreach ($aliases as $alias) {
|
||||
if (! isset($this->checkers[$alias])) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The claim checker with the alias "%s" is not supported.',
|
||||
$alias
|
||||
));
|
||||
}
|
||||
$checkers[] = $this->checkers[$alias];
|
||||
}
|
||||
|
||||
return new ClaimCheckerManager($checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds a claim checker to this factory.
|
||||
*/
|
||||
public function add(string $alias, ClaimChecker $checker): void
|
||||
{
|
||||
$this->checkers[$alias] = $checker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all claim checker aliases supported by this factory.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function aliases(): array
|
||||
{
|
||||
return array_keys($this->checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all claim checkers supported by this factory.
|
||||
*
|
||||
* @return ClaimChecker[]
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->checkers;
|
||||
}
|
||||
}
|
||||
14
libraries/vendor/web-token/jwt-library/Checker/ClaimExceptionInterface.php
vendored
Normal file
14
libraries/vendor/web-token/jwt-library/Checker/ClaimExceptionInterface.php
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Exceptions thrown by this component.
|
||||
*/
|
||||
interface ClaimExceptionInterface extends Throwable
|
||||
{
|
||||
}
|
||||
76
libraries/vendor/web-token/jwt-library/Checker/ExpirationTimeChecker.php
vendored
Normal file
76
libraries/vendor/web-token/jwt-library/Checker/ExpirationTimeChecker.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Psr\Clock\ClockInterface;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
|
||||
/**
|
||||
* This class is a claim checker. When the "exp" is present, it will compare the value with the current timestamp.
|
||||
*/
|
||||
final class ExpirationTimeChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
private const NAME = 'exp';
|
||||
|
||||
private readonly ClockInterface $clock;
|
||||
|
||||
public function __construct(
|
||||
private readonly int $allowedTimeDrift = 0,
|
||||
private readonly bool $protectedHeaderOnly = false,
|
||||
?ClockInterface $clock = null,
|
||||
) {
|
||||
if ($clock === null) {
|
||||
trigger_deprecation(
|
||||
'web-token/jwt-library',
|
||||
'3.3.0',
|
||||
'The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".'
|
||||
);
|
||||
$clock = new InternalClock();
|
||||
}
|
||||
$this->clock = $clock;
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidClaimException('"exp" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now > $value + $this->allowedTimeDrift) {
|
||||
throw new InvalidClaimException('The token expired.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidHeaderException('"exp" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now > $value + $this->allowedTimeDrift) {
|
||||
throw new InvalidHeaderException('The token expired.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeaderOnly;
|
||||
}
|
||||
}
|
||||
24
libraries/vendor/web-token/jwt-library/Checker/HeaderChecker.php
vendored
Normal file
24
libraries/vendor/web-token/jwt-library/Checker/HeaderChecker.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
interface HeaderChecker
|
||||
{
|
||||
/**
|
||||
* This method is called when the header parameter is present. If for some reason the value is not valid, an
|
||||
* InvalidHeaderException must be thrown.
|
||||
*/
|
||||
public function checkHeader(mixed $value): void;
|
||||
|
||||
/**
|
||||
* The method returns the header parameter to be checked.
|
||||
*/
|
||||
public function supportedHeader(): string;
|
||||
|
||||
/**
|
||||
* When true, the header parameter to be checked MUST be set in the protected header of the token.
|
||||
*/
|
||||
public function protectedHeaderOnly(): bool;
|
||||
}
|
||||
167
libraries/vendor/web-token/jwt-library/Checker/HeaderCheckerManager.php
vendored
Normal file
167
libraries/vendor/web-token/jwt-library/Checker/HeaderCheckerManager.php
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Jose\Component\Core\JWT;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function is_array;
|
||||
|
||||
class HeaderCheckerManager
|
||||
{
|
||||
/**
|
||||
* @var HeaderChecker[]
|
||||
*/
|
||||
private array $checkers = [];
|
||||
|
||||
/**
|
||||
* @var TokenTypeSupport[]
|
||||
*/
|
||||
private array $tokenTypes = [];
|
||||
|
||||
/**
|
||||
* HeaderCheckerManager constructor.
|
||||
*
|
||||
* @param HeaderChecker[] $checkers
|
||||
* @param TokenTypeSupport[] $tokenTypes
|
||||
*/
|
||||
public function __construct(iterable $checkers, iterable $tokenTypes)
|
||||
{
|
||||
foreach ($checkers as $checker) {
|
||||
$this->add($checker);
|
||||
}
|
||||
foreach ($tokenTypes as $tokenType) {
|
||||
$this->addTokenTypeSupport($tokenType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all checkers handled by this manager.
|
||||
*
|
||||
* @return HeaderChecker[]
|
||||
*/
|
||||
public function getCheckers(): array
|
||||
{
|
||||
return $this->checkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks all the header parameters passed as argument. All header parameters are checked against the
|
||||
* header parameter checkers. If one fails, the InvalidHeaderException is thrown.
|
||||
*
|
||||
* @param string[] $mandatoryHeaderParameters
|
||||
*/
|
||||
public function check(JWT $jwt, int $index, array $mandatoryHeaderParameters = []): void
|
||||
{
|
||||
foreach ($this->tokenTypes as $tokenType) {
|
||||
if ($tokenType->supports($jwt)) {
|
||||
$protected = [];
|
||||
$unprotected = [];
|
||||
$tokenType->retrieveTokenHeaders($jwt, $index, $protected, $unprotected);
|
||||
$this->checkDuplicatedHeaderParameters($protected, $unprotected);
|
||||
$this->checkMandatoryHeaderParameters($mandatoryHeaderParameters, $protected, $unprotected);
|
||||
$this->checkHeaders($protected, $unprotected);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Unsupported token type.');
|
||||
}
|
||||
|
||||
private function addTokenTypeSupport(TokenTypeSupport $tokenType): void
|
||||
{
|
||||
$this->tokenTypes[] = $tokenType;
|
||||
}
|
||||
|
||||
private function add(HeaderChecker $checker): void
|
||||
{
|
||||
$header = $checker->supportedHeader();
|
||||
$this->checkers[$header] = $checker;
|
||||
}
|
||||
|
||||
private function checkDuplicatedHeaderParameters(array $header1, array $header2): void
|
||||
{
|
||||
$inter = array_intersect_key($header1, $header2);
|
||||
if (count($inter) !== 0) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The header contains duplicated entries: %s.',
|
||||
implode(', ', array_keys($inter))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $mandatoryHeaderParameters
|
||||
*/
|
||||
private function checkMandatoryHeaderParameters(
|
||||
array $mandatoryHeaderParameters,
|
||||
array $protected,
|
||||
array $unprotected
|
||||
): void {
|
||||
if (count($mandatoryHeaderParameters) === 0) {
|
||||
return;
|
||||
}
|
||||
$diff = array_keys(
|
||||
array_diff_key(array_flip($mandatoryHeaderParameters), array_merge($protected, $unprotected))
|
||||
);
|
||||
if (count($diff) !== 0) {
|
||||
throw new MissingMandatoryHeaderParameterException(sprintf(
|
||||
'The following header parameters are mandatory: %s.',
|
||||
implode(', ', $diff)
|
||||
), $diff);
|
||||
}
|
||||
}
|
||||
|
||||
private function checkHeaders(array $protected, array $header): void
|
||||
{
|
||||
$checkedHeaderParameters = [];
|
||||
foreach ($this->checkers as $headerParameter => $checker) {
|
||||
if ($checker->protectedHeaderOnly()) {
|
||||
if (array_key_exists($headerParameter, $protected)) {
|
||||
$checker->checkHeader($protected[$headerParameter]);
|
||||
$checkedHeaderParameters[] = $headerParameter;
|
||||
} elseif (array_key_exists($headerParameter, $header)) {
|
||||
throw new InvalidHeaderException(sprintf(
|
||||
'The header parameter "%s" must be protected.',
|
||||
$headerParameter
|
||||
), $headerParameter, $header[$headerParameter]);
|
||||
}
|
||||
} else {
|
||||
if (array_key_exists($headerParameter, $protected)) {
|
||||
$checker->checkHeader($protected[$headerParameter]);
|
||||
$checkedHeaderParameters[] = $headerParameter;
|
||||
} elseif (array_key_exists($headerParameter, $header)) {
|
||||
$checker->checkHeader($header[$headerParameter]);
|
||||
$checkedHeaderParameters[] = $headerParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->checkCriticalHeader($protected, $header, $checkedHeaderParameters);
|
||||
}
|
||||
|
||||
private function checkCriticalHeader(array $protected, array $header, array $checkedHeaderParameters): void
|
||||
{
|
||||
if (array_key_exists('crit', $protected)) {
|
||||
if (! is_array($protected['crit'])) {
|
||||
throw new InvalidHeaderException(
|
||||
'The header "crit" must be a list of header parameters.',
|
||||
'crit',
|
||||
$protected['crit']
|
||||
);
|
||||
}
|
||||
$diff = array_diff($protected['crit'], $checkedHeaderParameters);
|
||||
if (count($diff) !== 0) {
|
||||
throw new InvalidHeaderException(sprintf(
|
||||
'One or more header parameters are marked as critical, but they are missing or have not been checked: %s.',
|
||||
implode(', ', array_values($diff))
|
||||
), 'crit', $protected['crit']);
|
||||
}
|
||||
} elseif (array_key_exists('crit', $header)) {
|
||||
throw new InvalidHeaderException('The header parameter "crit" must be protected.', 'crit', $header['crit']);
|
||||
}
|
||||
}
|
||||
}
|
||||
82
libraries/vendor/web-token/jwt-library/Checker/HeaderCheckerManagerFactory.php
vendored
Normal file
82
libraries/vendor/web-token/jwt-library/Checker/HeaderCheckerManagerFactory.php
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @see \Jose\Tests\Component\Checker\HeaderCheckerManagerFactoryTest
|
||||
*/
|
||||
class HeaderCheckerManagerFactory
|
||||
{
|
||||
/**
|
||||
* @var HeaderChecker[]
|
||||
*/
|
||||
private array $checkers = [];
|
||||
|
||||
/**
|
||||
* @var TokenTypeSupport[]
|
||||
*/
|
||||
private array $tokenTypes = [];
|
||||
|
||||
/**
|
||||
* This method creates a Header Checker Manager and populate it with the header parameter checkers found based on
|
||||
* the alias. If the alias is not supported, an InvalidArgumentException is thrown.
|
||||
*
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
public function create(array $aliases): HeaderCheckerManager
|
||||
{
|
||||
$checkers = [];
|
||||
foreach ($aliases as $alias) {
|
||||
if (! isset($this->checkers[$alias])) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'The header checker with the alias "%s" is not supported.',
|
||||
$alias
|
||||
));
|
||||
}
|
||||
$checkers[] = $this->checkers[$alias];
|
||||
}
|
||||
|
||||
return new HeaderCheckerManager($checkers, $this->tokenTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds a header parameter checker to this factory. The checker is uniquely identified by an alias. This
|
||||
* allows the same header parameter checker to be added twice (or more) using several configuration options.
|
||||
*/
|
||||
public function add(string $alias, HeaderChecker $checker): void
|
||||
{
|
||||
$this->checkers[$alias] = $checker;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds a token type support to this factory.
|
||||
*/
|
||||
public function addTokenTypeSupport(TokenTypeSupport $tokenType): void
|
||||
{
|
||||
$this->tokenTypes[] = $tokenType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all header parameter checker aliases supported by this factory.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function aliases(): array
|
||||
{
|
||||
return array_keys($this->checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all header parameter checkers supported by this factory.
|
||||
*
|
||||
* @return HeaderChecker[]
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->checkers;
|
||||
}
|
||||
}
|
||||
19
libraries/vendor/web-token/jwt-library/Checker/InternalClock.php
vendored
Normal file
19
libraries/vendor/web-token/jwt-library/Checker/InternalClock.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Psr\Clock\ClockInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class InternalClock implements ClockInterface
|
||||
{
|
||||
public function now(): DateTimeImmutable
|
||||
{
|
||||
return new DateTimeImmutable();
|
||||
}
|
||||
}
|
||||
37
libraries/vendor/web-token/jwt-library/Checker/InvalidClaimException.php
vendored
Normal file
37
libraries/vendor/web-token/jwt-library/Checker/InvalidClaimException.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown by claim checkers when a claim check failed.
|
||||
*/
|
||||
class InvalidClaimException extends Exception implements ClaimExceptionInterface
|
||||
{
|
||||
public function __construct(
|
||||
string $message,
|
||||
private readonly string $claim,
|
||||
private readonly mixed $value
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the claim that caused the exception.
|
||||
*/
|
||||
public function getClaim(): string
|
||||
{
|
||||
return $this->claim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the claim value that caused the exception.
|
||||
*/
|
||||
public function getValue(): mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
37
libraries/vendor/web-token/jwt-library/Checker/InvalidHeaderException.php
vendored
Normal file
37
libraries/vendor/web-token/jwt-library/Checker/InvalidHeaderException.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown by header parameter checkers when a header parameter check failed.
|
||||
*/
|
||||
class InvalidHeaderException extends Exception
|
||||
{
|
||||
public function __construct(
|
||||
string $message,
|
||||
private readonly string $header,
|
||||
private readonly mixed $value
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header parameter that caused the exception.
|
||||
*/
|
||||
public function getHeader(): string
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header parameter value that caused the exception.
|
||||
*/
|
||||
public function getValue(): mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
53
libraries/vendor/web-token/jwt-library/Checker/IsEqualChecker.php
vendored
Normal file
53
libraries/vendor/web-token/jwt-library/Checker/IsEqualChecker.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
/**
|
||||
* @see \Jose\Tests\Component\Checker\IsEqualCheckerTest
|
||||
*/
|
||||
final class IsEqualChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
/**
|
||||
* @param string $key The claim or header parameter name to check.
|
||||
* @param mixed $value The expected value.
|
||||
* @param bool $protectedHeaderOnly [optional] Whether the header parameter MUST be protected.
|
||||
* This option has no effect for claim checkers.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $key,
|
||||
private readonly mixed $value,
|
||||
private readonly bool $protectedHeaderOnly = true
|
||||
) {
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
if ($value !== $this->value) {
|
||||
throw new InvalidClaimException(sprintf('The "%s" claim is invalid.', $this->key), $this->key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if ($value !== $this->value) {
|
||||
throw new InvalidHeaderException(sprintf('The "%s" header is invalid.', $this->key), $this->key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeaderOnly;
|
||||
}
|
||||
}
|
||||
76
libraries/vendor/web-token/jwt-library/Checker/IssuedAtChecker.php
vendored
Normal file
76
libraries/vendor/web-token/jwt-library/Checker/IssuedAtChecker.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Psr\Clock\ClockInterface;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
|
||||
/**
|
||||
* This class is a claim checker. When the "iat" is present, it will compare the value with the current timestamp.
|
||||
*/
|
||||
final class IssuedAtChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
private const NAME = 'iat';
|
||||
|
||||
private readonly ClockInterface $clock;
|
||||
|
||||
public function __construct(
|
||||
private readonly int $allowedTimeDrift = 0,
|
||||
private readonly bool $protectedHeaderOnly = false,
|
||||
?ClockInterface $clock = null,
|
||||
) {
|
||||
if ($clock === null) {
|
||||
trigger_deprecation(
|
||||
'web-token/jwt-library',
|
||||
'3.3.0',
|
||||
'The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".'
|
||||
);
|
||||
$clock = new InternalClock();
|
||||
}
|
||||
$this->clock = $clock;
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidClaimException('"iat" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now < $value - $this->allowedTimeDrift) {
|
||||
throw new InvalidClaimException('The JWT is issued in the future.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidHeaderException('The header "iat" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now < $value - $this->allowedTimeDrift) {
|
||||
throw new InvalidHeaderException('The JWT is issued in the future.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeaderOnly;
|
||||
}
|
||||
}
|
||||
58
libraries/vendor/web-token/jwt-library/Checker/IssuerChecker.php
vendored
Normal file
58
libraries/vendor/web-token/jwt-library/Checker/IssuerChecker.php
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* This class is a header parameter and claim checker. When the "iss" header parameter or claim is present, it will
|
||||
* check if the value is within the allowed ones.
|
||||
*/
|
||||
final class IssuerChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
private const CLAIM_NAME = 'iss';
|
||||
|
||||
public function __construct(
|
||||
private readonly array $issuers,
|
||||
private readonly bool $protectedHeader = false
|
||||
) {
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
$this->checkValue($value, InvalidClaimException::class);
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
$this->checkValue($value, InvalidHeaderException::class);
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return self::CLAIM_NAME;
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::CLAIM_NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeader;
|
||||
}
|
||||
|
||||
private function checkValue(mixed $value, string $class): void
|
||||
{
|
||||
if (! is_string($value)) {
|
||||
throw new $class('Invalid value.', self::CLAIM_NAME, $value);
|
||||
}
|
||||
if (! in_array($value, $this->issuers, true)) {
|
||||
throw new $class('Unknown issuer.', self::CLAIM_NAME, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
libraries/vendor/web-token/jwt-library/Checker/MissingMandatoryClaimException.php
vendored
Normal file
30
libraries/vendor/web-token/jwt-library/Checker/MissingMandatoryClaimException.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MissingMandatoryClaimException extends Exception implements ClaimExceptionInterface
|
||||
{
|
||||
/**
|
||||
* MissingMandatoryClaimException constructor.
|
||||
*
|
||||
* @param string[] $claims
|
||||
*/
|
||||
public function __construct(
|
||||
string $message,
|
||||
private readonly array $claims
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getClaims(): array
|
||||
{
|
||||
return $this->claims;
|
||||
}
|
||||
}
|
||||
30
libraries/vendor/web-token/jwt-library/Checker/MissingMandatoryHeaderParameterException.php
vendored
Normal file
30
libraries/vendor/web-token/jwt-library/Checker/MissingMandatoryHeaderParameterException.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MissingMandatoryHeaderParameterException extends Exception
|
||||
{
|
||||
/**
|
||||
* MissingMandatoryHeaderParameterException constructor.
|
||||
*
|
||||
* @param string[] $parameters
|
||||
*/
|
||||
public function __construct(
|
||||
string $message,
|
||||
private readonly array $parameters
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
}
|
||||
76
libraries/vendor/web-token/jwt-library/Checker/NotBeforeChecker.php
vendored
Normal file
76
libraries/vendor/web-token/jwt-library/Checker/NotBeforeChecker.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Psr\Clock\ClockInterface;
|
||||
use function is_float;
|
||||
use function is_int;
|
||||
|
||||
/**
|
||||
* This class is a claim checker. When the "nbf" is present, it will compare the value with the current timestamp.
|
||||
*/
|
||||
final class NotBeforeChecker implements ClaimChecker, HeaderChecker
|
||||
{
|
||||
private const NAME = 'nbf';
|
||||
|
||||
private readonly ClockInterface $clock;
|
||||
|
||||
public function __construct(
|
||||
private readonly int $allowedTimeDrift = 0,
|
||||
private readonly bool $protectedHeaderOnly = false,
|
||||
?ClockInterface $clock = null,
|
||||
) {
|
||||
if ($clock === null) {
|
||||
trigger_deprecation(
|
||||
'web-token/jwt-library',
|
||||
'3.3.0',
|
||||
'The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".'
|
||||
);
|
||||
$clock = new InternalClock();
|
||||
}
|
||||
$this->clock = $clock;
|
||||
}
|
||||
|
||||
public function checkClaim(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidClaimException('"nbf" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now < $value - $this->allowedTimeDrift) {
|
||||
throw new InvalidClaimException('The JWT can not be used yet.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedClaim(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (! is_float($value) && ! is_int($value)) {
|
||||
throw new InvalidHeaderException('"nbf" must be an integer.', self::NAME, $value);
|
||||
}
|
||||
|
||||
$now = $this->clock->now()
|
||||
->getTimestamp();
|
||||
if ($now < $value - $this->allowedTimeDrift) {
|
||||
throw new InvalidHeaderException('The JWT can not be used yet.', self::NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return $this->protectedHeaderOnly;
|
||||
}
|
||||
}
|
||||
31
libraries/vendor/web-token/jwt-library/Checker/TokenTypeSupport.php
vendored
Normal file
31
libraries/vendor/web-token/jwt-library/Checker/TokenTypeSupport.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use Jose\Component\Core\JWT;
|
||||
|
||||
interface TokenTypeSupport
|
||||
{
|
||||
/**
|
||||
* This method will retrieve the protect and unprotected headers of the token for the given index. The index is
|
||||
* useful when the token is serialized using the Json General Serialization mode. For example the JWE Json General
|
||||
* Serialization Mode allows several recipients to be set. The unprotected headers correspond to the share
|
||||
* unprotected header and the selected recipient header.
|
||||
*
|
||||
* @param array<string, mixed> $protectedHeader
|
||||
* @param array<string, mixed> $unprotectedHeader
|
||||
*/
|
||||
public function retrieveTokenHeaders(
|
||||
JWT $jwt,
|
||||
int $index,
|
||||
array &$protectedHeader,
|
||||
array &$unprotectedHeader
|
||||
): void;
|
||||
|
||||
/**
|
||||
* This method returns true if the token in argument is supported, otherwise false.
|
||||
*/
|
||||
public function supports(JWT $jwt): bool;
|
||||
}
|
||||
34
libraries/vendor/web-token/jwt-library/Checker/UnencodedPayloadChecker.php
vendored
Normal file
34
libraries/vendor/web-token/jwt-library/Checker/UnencodedPayloadChecker.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jose\Component\Checker;
|
||||
|
||||
use function is_bool;
|
||||
|
||||
/**
|
||||
* This class is a header parameter checker. When the "b64" is present, it will check if the value is a boolean or not.
|
||||
*
|
||||
* The use of this checker will allow the use of token with unencoded payload.
|
||||
*/
|
||||
final class UnencodedPayloadChecker implements HeaderChecker
|
||||
{
|
||||
private const HEADER_NAME = 'b64';
|
||||
|
||||
public function checkHeader(mixed $value): void
|
||||
{
|
||||
if (! is_bool($value)) {
|
||||
throw new InvalidHeaderException('"b64" must be a boolean.', self::HEADER_NAME, $value);
|
||||
}
|
||||
}
|
||||
|
||||
public function supportedHeader(): string
|
||||
{
|
||||
return self::HEADER_NAME;
|
||||
}
|
||||
|
||||
public function protectedHeaderOnly(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user