Skip to content

Commit

Permalink
Merge pull request #865 from lcobucci/improve-constraint-tracking
Browse files Browse the repository at this point in the history
Track constraint on violations
  • Loading branch information
lcobucci committed Aug 17, 2022
2 parents 587cb9b + 8f7f2c2 commit 1ec5e0a
Show file tree
Hide file tree
Showing 28 changed files with 107 additions and 26 deletions.
9 changes: 6 additions & 3 deletions src/Validation/Constraint/HasClaimWithValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,20 @@ public function __construct(string $claim, $expectedValue)
public function assert(Token $token): void
{
if (! $token instanceof UnencryptedToken) {
throw new ConstraintViolation('You should pass a plain token');
throw ConstraintViolation::error('You should pass a plain token', $this);
}

$claims = $token->claims();

if (! $claims->has($this->claim)) {
throw new ConstraintViolation('The token does not have the claim "' . $this->claim . '"');
throw ConstraintViolation::error('The token does not have the claim "' . $this->claim . '"', $this);
}

if ($claims->get($this->claim) !== $this->expectedValue) {
throw new ConstraintViolation('The claim "' . $this->claim . '" does not have the expected value');
throw ConstraintViolation::error(
'The claim "' . $this->claim . '" does not have the expected value',
$this
);
}
}
}
5 changes: 3 additions & 2 deletions src/Validation/Constraint/IdentifiedBy.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public function __construct(string $id)
public function assert(Token $token): void
{
if (! $token->isIdentifiedBy($this->id)) {
throw new ConstraintViolation(
'The token is not identified with the expected ID'
throw ConstraintViolation::error(
'The token is not identified with the expected ID',
$this
);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/Validation/Constraint/IssuedBy.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ public function __construct(string ...$issuers)
public function assert(Token $token): void
{
if (! $token->hasBeenIssuedBy(...$this->issuers)) {
throw new ConstraintViolation(
'The token was not issued by the given issuers'
throw ConstraintViolation::error(
'The token was not issued by the given issuers',
$this
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Validation/Constraint/LooseValidAt.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,23 @@ public function assert(Token $token): void
private function assertExpiration(Token $token, DateTimeInterface $now): void
{
if ($token->isExpired($now)) {
throw new ConstraintViolation('The token is expired');
throw ConstraintViolation::error('The token is expired', $this);
}
}

/** @throws ConstraintViolation */
private function assertMinimumTime(Token $token, DateTimeInterface $now): void
{
if (! $token->isMinimumTimeBefore($now)) {
throw new ConstraintViolation('The token cannot be used yet');
throw ConstraintViolation::error('The token cannot be used yet', $this);
}
}

/** @throws ConstraintViolation */
private function assertIssueTime(Token $token, DateTimeInterface $now): void
{
if (! $token->hasBeenIssuedBefore($now)) {
throw new ConstraintViolation('The token was issued in the future');
throw ConstraintViolation::error('The token was issued in the future', $this);
}
}
}
5 changes: 3 additions & 2 deletions src/Validation/Constraint/PermittedFor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public function __construct(string $audience)
public function assert(Token $token): void
{
if (! $token->isPermittedFor($this->audience)) {
throw new ConstraintViolation(
'The token is not allowed to be used by this audience'
throw ConstraintViolation::error(
'The token is not allowed to be used by this audience',
$this
);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/Validation/Constraint/RelatedTo.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public function __construct(string $subject)
public function assert(Token $token): void
{
if (! $token->isRelatedTo($this->subject)) {
throw new ConstraintViolation(
'The token is not related to the expected subject'
throw ConstraintViolation::error(
'The token is not related to the expected subject',
$this
);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Validation/Constraint/SignedWith.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ public function __construct(Signer $signer, Signer\Key $key)
public function assert(Token $token): void
{
if (! $token instanceof UnencryptedToken) {
throw new ConstraintViolation('You should pass a plain token');
throw ConstraintViolation::error('You should pass a plain token', $this);
}

if ($token->headers()->get('alg') !== $this->signer->algorithmId()) {
throw new ConstraintViolation('Token signer mismatch');
throw ConstraintViolation::error('Token signer mismatch', $this);
}

if (! $this->signer->verify($token->signature()->hash(), $token->payload(), $this->key)) {
throw new ConstraintViolation('Token signature mismatch');
throw ConstraintViolation::error('Token signature mismatch', $this);
}
}
}
14 changes: 7 additions & 7 deletions src/Validation/Constraint/StrictValidAt.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private function guardLeeway(?DateInterval $leeway): DateInterval
public function assert(Token $token): void
{
if (! $token instanceof UnencryptedToken) {
throw new ConstraintViolation('You should pass a plain token');
throw ConstraintViolation::error('You should pass a plain token', $this);
}

$now = $this->clock->now();
Expand All @@ -52,35 +52,35 @@ public function assert(Token $token): void
private function assertExpiration(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::EXPIRATION_TIME)) {
throw new ConstraintViolation('"Expiration Time" claim missing');
throw ConstraintViolation::error('"Expiration Time" claim missing', $this);
}

if ($token->isExpired($now)) {
throw new ConstraintViolation('The token is expired');
throw ConstraintViolation::error('The token is expired', $this);
}
}

/** @throws ConstraintViolation */
private function assertMinimumTime(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::NOT_BEFORE)) {
throw new ConstraintViolation('"Not Before" claim missing');
throw ConstraintViolation::error('"Not Before" claim missing', $this);
}

if (! $token->isMinimumTimeBefore($now)) {
throw new ConstraintViolation('The token cannot be used yet');
throw ConstraintViolation::error('The token cannot be used yet', $this);
}
}

/** @throws ConstraintViolation */
private function assertIssueTime(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::ISSUED_AT)) {
throw new ConstraintViolation('"Issued At" claim missing');
throw ConstraintViolation::error('"Issued At" claim missing', $this);
}

if (! $token->hasBeenIssuedBefore($now)) {
throw new ConstraintViolation('The token was issued in the future');
throw ConstraintViolation::error('The token was issued in the future', $this);
}
}
}
15 changes: 15 additions & 0 deletions src/Validation/ConstraintViolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
use Lcobucci\JWT\Exception;
use RuntimeException;

use function get_class;

final class ConstraintViolation extends RuntimeException implements Exception
{
/**
* @readonly
* @var class-string<Constraint>|null
*/
public ?string $constraint = null;

public static function error(string $message, Constraint $constraint): self
{
$exception = new self($message);
$exception->constraint = get_class($constraint);

return $exception;
}
}
1 change: 1 addition & 0 deletions test/functional/ES512TokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @covers \Lcobucci\JWT\Signer\OpenSSL
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
Expand Down
3 changes: 1 addition & 2 deletions test/functional/EcdsaTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@
* @covers \Lcobucci\JWT\Signer\OpenSSL
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
class EcdsaTokenTest extends TestCase
{
Expand Down
1 change: 1 addition & 0 deletions test/functional/EddsaTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
Expand Down
1 change: 1 addition & 0 deletions test/functional/HmacTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @covers \Lcobucci\JWT\Signer\Hmac\UnsafeSha256
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
Expand Down
1 change: 1 addition & 0 deletions test/functional/MaliciousTamperingPreventionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function createConfiguration(): void
* @covers \Lcobucci\JWT\Signer\Hmac\Sha256
* @covers \Lcobucci\JWT\Signer\Hmac\Sha512
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
* @covers \Lcobucci\JWT\Validation\Validator
*/
Expand Down
1 change: 1 addition & 0 deletions test/functional/RsaTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
* @covers \Lcobucci\JWT\Signer\Rsa\Sha512
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
Expand Down
1 change: 1 addition & 0 deletions test/functional/TimeFractionPrecisionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* @covers \Lcobucci\JWT\Signer\Key\InMemory
* @covers \Lcobucci\JWT\Signer\None
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Constraint\SignedWith
*/
Expand Down
1 change: 1 addition & 0 deletions test/functional/UnsignedTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* @covers \Lcobucci\JWT\Signer\None
* @covers \Lcobucci\JWT\Signer\Key\InMemory
* @covers \Lcobucci\JWT\SodiumBase64Polyfill
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
* @covers \Lcobucci\JWT\Validation\RequiredConstraintsViolated
* @covers \Lcobucci\JWT\Validation\Validator
* @covers \Lcobucci\JWT\Validation\Constraint\IssuedBy
Expand Down
1 change: 1 addition & 0 deletions test/unit/JwtFacadeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* @uses \Lcobucci\JWT\Validation\Constraint\IssuedBy
* @uses \Lcobucci\JWT\Validation\Constraint\SignedWith
* @uses \Lcobucci\JWT\Validation\Constraint\StrictValidAt
* @uses \Lcobucci\JWT\Validation\ConstraintViolation
* @uses \Lcobucci\JWT\Validation\RequiredConstraintsViolated
*/
final class JwtFacadeTest extends TestCase
Expand Down
3 changes: 3 additions & 0 deletions test/unit/Validation/Constraint/HasClaimWithValueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function registeredClaims(): iterable
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -58,6 +59,7 @@ public function assertShouldRaiseExceptionWhenClaimIsNotSet(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -77,6 +79,7 @@ public function assertShouldRaiseExceptionWhenClaimValueDoesNotMatch(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand Down
3 changes: 3 additions & 0 deletions test/unit/Validation/Constraint/IdentifiedByTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class IdentifiedByTest extends ConstraintTestCase
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -33,6 +34,7 @@ public function assertShouldRaiseExceptionWhenIdIsNotSet(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -52,6 +54,7 @@ public function assertShouldRaiseExceptionWhenIdDoesNotMatch(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand Down
3 changes: 3 additions & 0 deletions test/unit/Validation/Constraint/IssuedByTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class IssuedByTest extends ConstraintTestCase
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -33,6 +34,7 @@ public function assertShouldRaiseExceptionWhenIssuerIsNotSet(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -52,6 +54,7 @@ public function assertShouldRaiseExceptionWhenIssuerValueDoesNotMatch(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand Down
3 changes: 3 additions & 0 deletions test/unit/Validation/Constraint/PermittedForTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class PermittedForTest extends ConstraintTestCase
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -33,6 +34,7 @@ public function assertShouldRaiseExceptionWhenAudienceIsNotSet(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -52,6 +54,7 @@ public function assertShouldRaiseExceptionWhenAudienceValueDoesNotMatch(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand Down
2 changes: 2 additions & 0 deletions test/unit/Validation/Constraint/RelatedToTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final class RelatedToTest extends ConstraintTestCase
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand All @@ -33,6 +34,7 @@ public function assertShouldRaiseExceptionWhenSubjectIsNotSet(): void
*
* @covers ::__construct
* @covers ::assert
* @covers \Lcobucci\JWT\Validation\ConstraintViolation
*
* @uses \Lcobucci\JWT\Token\DataSet
* @uses \Lcobucci\JWT\Token\Plain
Expand Down
Loading

0 comments on commit 1ec5e0a

Please sign in to comment.