Skip to content

Commit

Permalink
chore: add missed test
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasvargiu committed Jun 23, 2022
1 parent f2d9166 commit eaa8c03
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 71 deletions.
18 changes: 9 additions & 9 deletions src/AbstractTokenVerifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,26 +200,26 @@ protected function create(string $jwt): Validate

$validator = Validate::token($jwt)
->keyset($this->buildJwks($jwt))
->claim('iss', new IssuerChecker([$expectedIssuer], true))
->claim('iat', new IssuedAtChecker($this->clockTolerance, true))
->claim('aud', new AudienceChecker($this->clientId, true))
->claim('exp', new ExpirationTimeChecker($this->clockTolerance))
->claim('nbf', new NotBeforeChecker($this->clockTolerance, true));
->claim(new IssuerChecker([$expectedIssuer], true))
->claim(new IssuedAtChecker($this->clockTolerance, true))
->claim(new AudienceChecker($this->clientId, true))
->claim(new ExpirationTimeChecker($this->clockTolerance))
->claim(new NotBeforeChecker($this->clockTolerance, true));

if (null !== $this->azp) {
$validator = $validator->claim('azp', new AzpChecker($this->azp));
$validator = $validator->claim(new AzpChecker($this->azp));
}

if (null !== $this->expectedAlg) {
$validator = $validator->header('alg', new AlgorithmChecker([$this->expectedAlg], true));
$validator = $validator->header(new AlgorithmChecker([$this->expectedAlg], true));
}

if (null !== $this->nonce) {
$validator = $validator->claim('nonce', new NonceChecker($this->nonce));
$validator = $validator->claim(new NonceChecker($this->nonce));
}

if (null !== $this->maxAge) {
$validator = $validator->claim('auth_time', new AuthTimeChecker($this->maxAge, $this->clockTolerance));
$validator = $validator->claim(new AuthTimeChecker($this->maxAge, $this->clockTolerance));
}

if ((int) $this->maxAge > 0 || null !== $this->maxAge) {
Expand Down
6 changes: 3 additions & 3 deletions src/IdTokenVerifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ public function verify(string $jwt): array

if (null !== $this->accessToken) {
$requiredClaims[] = 'at_hash';
$validator = $validator->claim('at_hash', new AtHashChecker($this->accessToken, $alg ?: ''));
$validator = $validator->claim(new AtHashChecker($this->accessToken, $alg ?: ''));
}

if (null !== $this->code) {
$requiredClaims[] = 'c_hash';
$validator = $validator->claim('c_hash', new CHashChecker($this->code, $alg ?: ''));
$validator = $validator->claim(new CHashChecker($this->code, $alg ?: ''));
}

if (null !== $this->state) {
$validator = $validator->claim('s_hash', new SHashChecker($this->state, $alg ?: ''));
$validator = $validator->claim(new SHashChecker($this->state, $alg ?: ''));
}

$validator = $validator->mandatory($requiredClaims);
Expand Down
63 changes: 4 additions & 59 deletions src/Validate/Validate.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Facile\JoseVerifier\Validate;

use Facile\JoseVerifier\Checker\CallableChecker;
use Facile\JoseVerifier\Exception\RuntimeException;
use Jose\Component\Checker;
use Jose\Component\Core\AlgorithmManager;
Expand Down Expand Up @@ -125,74 +124,20 @@ public function mandatory(array $mandatoryClaims): self
return $clone;
}

/**
* @param array|Checker\ClaimChecker|mixed $checker
* @psalm-param array|Checker\ClaimChecker|mixed $checker
*/
public function claim(string $key, $checker, bool $inHeader = false): self
public function claim(Checker\ClaimChecker $checker): self
{
$clone = clone $this;
if (false === $checker) {
unset($clone->claimCheckers[$key]);

return $clone;
}

switch (true) {
case $checker instanceof Checker\ClaimChecker:
break;

case is_array($checker):
$checker = new CallableChecker($key, static function ($value) use ($checker): bool {
return in_array($value, $checker, true);
});

break;

default:
$checker = new CallableChecker($key, static function ($value) use ($checker): bool {
return $value === $checker;
});
}

$clone->claimCheckers[$key] = $checker;
if ($inHeader) {
return $clone->header($key, $checker);
}
$clone->claimCheckers[] = $checker;

return $clone;
}

/**
* @param array|Checker\HeaderChecker|false|mixed $checker
*/
public function header(string $key, $checker): self
public function header(Checker\HeaderChecker $checker): self
{
$clone = clone $this;
if (false === $checker) {
unset($clone->headerCheckers[$key]);

return $clone;
}

switch (true) {
case $checker instanceof Checker\HeaderChecker:
break;

case is_array($checker):
$checker = new CallableChecker($key, static function ($value) use ($checker): bool {
return in_array($value, $checker, true);
});

break;

default:
$checker = new CallableChecker($key, static function ($value) use ($checker): bool {
return $value === $checker;
});
}

$clone->headerCheckers[$key] = $checker;
$clone->headerCheckers[] = $checker;

return $clone;
}
Expand Down
148 changes: 148 additions & 0 deletions tests/Validate/ValidateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

declare(strict_types=1);

namespace Facile\JoseVerifierTest\Validate;

use Facile\JoseVerifier\Checker\CallableChecker;
use Facile\JoseVerifier\Exception\RuntimeException;
use Facile\JoseVerifier\Validate\Validate;
use Facile\JoseVerifierTest\AbstractJwtTestCase;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Checker\InvalidClaimException;
use Jose\Component\Checker\InvalidHeaderException;
use Jose\Component\Core\JWKSet;
use Jose\Component\KeyManagement\JWKFactory;

class ValidateTest extends AbstractJwtTestCase
{
/** @var \Jose\Component\Core\JWK */
private $jwk;

/** @var JWKSet */
private $jwks;

protected function setUp(): void
{
$this->jwk = JWKFactory::createRSAKey(2048, ['alg' => 'RS256', 'use' => 'sig']);
$this->jwks = JWKSet::createFromKeyData(['keys' => [$this->jwk->toPublic()->all()]]);
}

public function createPayload(): array
{
return [
'iss' => 'https://issuer.com',
'sub' => 'client-id',
'aud' => 'client-id',
'azp' => 'client-id',
'exp' => time() + 600,
'iat' => time(),
'auth_time' => time() - 100,
];
}

private function generateTokenWithPayload(array $payload): string
{
return $this->createSignedToken($payload, [
'alg' => 'RS256',
], $this->jwk);
}

private function generateToken(): string
{
return $this->generateTokenWithPayload([
'iss' => 'https://issuer.com',
'sub' => 'client-id',
'aud' => 'client-id',
'azp' => 'client-id',
'exp' => time() + 600,
'iat' => time(),
'auth_time' => time() - 100,
]);
}

public function testShouldValidateSignature(): void
{
$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token);
$validator = $baseValidator->keyset($this->jwks);

$this->assertNotSame($validator, $baseValidator);
$this->assertSame($payload, $validator->run());
}

public function testShouldValidateSignatureFail(): void
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Invalid signature');

$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token);

$jwk = JWKFactory::createRSAKey(2048, ['alg' => 'RS256', 'use' => 'sig']);
$jwks = JWKSet::createFromKeyData(['keys' => [$jwk->toPublic()->all()]]);

$validator = $baseValidator->keyset($jwks);

$this->assertNotSame($validator, $baseValidator);
$validator->run();
}

public function testShouldValidateClaim(): void
{
$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token)
->keyset($this->jwks);
$validator = $baseValidator->claim(new CallableChecker('aud', static function () {
return true;
}));

$this->assertNotSame($validator, $baseValidator);
$this->assertSame($payload, $validator->run());
}

public function testShouldValidateClaimFail(): void
{
$this->expectException(InvalidClaimException::class);

$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token)
->keyset($this->jwks);
$validator = $baseValidator->claim(new CallableChecker('aud', static function () {
return false;
}));

$this->assertNotSame($validator, $baseValidator);
$validator->run();
}

public function testShouldValidateHeader(): void
{
$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token)
->keyset($this->jwks);
$validator = $baseValidator->header(new AlgorithmChecker(['foo', 'RS256']));

$this->assertNotSame($validator, $baseValidator);
$this->assertSame($payload, $validator->run());
}

public function testShouldValidateHeaderFail(): void
{
$this->expectException(InvalidHeaderException::class);

$payload = $this->createPayload();
$token = $this->generateTokenWithPayload($payload);
$baseValidator = Validate::token($token)
->keyset($this->jwks);
$validator = $baseValidator->header(new AlgorithmChecker(['foo', 'bar']));

$this->assertNotSame($validator, $baseValidator);
$validator->run();
}
}

0 comments on commit eaa8c03

Please sign in to comment.