Skip to content

Commit 1b9d33a

Browse files
nicumiclepandanicu
authored andcommitted
Add error codes to all exceptions
1 parent f7886d5 commit 1b9d33a

File tree

8 files changed

+254
-50
lines changed

8 files changed

+254
-50
lines changed

src/BeforeValidException.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44

55
class BeforeValidException extends \UnexpectedValueException
66
{
7+
public const NBF_PRIOR_TO_DATE = 1;
8+
const IAT_PRIOR_TO_DATE = 2;
79
}

src/CachedKeySet.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ public function __construct(
9999
public function offsetGet($keyId): Key
100100
{
101101
if (!$this->keyIdExists($keyId)) {
102-
throw new OutOfBoundsException('Key ID not found');
102+
throw new OutOfBoundsException(
103+
'Key ID not found',
104+
ExceptionCodes::KEY_ID_NOT_FOUND
105+
);
103106
}
104107
return $this->keySet[$keyId];
105108
}
@@ -119,15 +122,21 @@ public function offsetExists($keyId): bool
119122
*/
120123
public function offsetSet($offset, $value): void
121124
{
122-
throw new LogicException('Method not implemented');
125+
throw new LogicException(
126+
'Method not implemented',
127+
ExceptionCodes::OFFSET_SET_METHOD_NOT_IMPLEMENTED
128+
);
123129
}
124130

125131
/**
126132
* @param string $offset
127133
*/
128134
public function offsetUnset($offset): void
129135
{
130-
throw new LogicException('Method not implemented');
136+
throw new LogicException(
137+
'Method not implemented',
138+
ExceptionCodes::OFFSET_UNSET_METHOD_NOT_IMPLEMENTED
139+
);
131140
}
132141

133142
private function keyIdExists(string $keyId): bool
@@ -198,7 +207,10 @@ private function getCacheItem(): CacheItemInterface
198207
private function setCacheKeys(): void
199208
{
200209
if (empty($this->jwksUri)) {
201-
throw new RuntimeException('JWKS URI is empty');
210+
throw new RuntimeException(
211+
'JWKS URI is empty',
212+
ExceptionCodes::JWKS_URI_IS_EMPTY
213+
);
202214
}
203215

204216
// ensure we do not have illegal characters

src/ExceptionCodes.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
6+
namespace Firebase\JWT;
7+
8+
class ExceptionCodes
9+
{
10+
public const KEY_NOT_EMPTY = 1;
11+
public const WRONG_NUMBER_OF_SEGMENTS = 2;
12+
public const INVALID_HEADER_ENCODING = 3;
13+
public const INVALID_CLAIMS_ENCODING = 4;
14+
public const PAYLOAD_NOT_JSON = 5;
15+
public const EMPTY_ALGORITHM = 6;
16+
public const DECODE_ALGORITHM_NOT_SUPPORTED = 7;
17+
public const INCORRECT_KEY_FOR_ALGORITHM = 8;
18+
public const SIGN_ALGORITHM_NOT_SUPPORTED = 9;
19+
public const KEY_IS_NOT_STRING = 10;
20+
const OPENSSL_CAN_NOT_SIGN_DATA = 11;
21+
const SODIUM_KEY_IS_NOT_STRING = 12;
22+
const SODIUM_EXCEPTION = 13;
23+
const SIGN_GENERAL_EXCEPTION = 14;
24+
const VERIFY_ALGORITHM_NOT_SUPPORTED = 15;
25+
const VERIFY_OPEN_SSL_ERROR = 16;
26+
const VERIFY_SODIUM_NOT_AVAILABLE = 17;
27+
const VERIFY_KEY_MATERIAL_IS_NOT_STRING = 18;
28+
const VERIFY_SODIUM_EXCEPTION = 19;
29+
const VERIFY_KEY_IS_NOT_STRING = 20;
30+
const DECODED_JSON_IS_NULL = 21;
31+
const ENCODED_JSON_IS_NULL = 22;
32+
const INVALID_JSON = 23;
33+
const KID_IS_EMPTY = 24;
34+
const KID_IS_INVALID = 25;
35+
const JSON_ERROR = 26;
36+
37+
const KEY_ID_NOT_FOUND = 27;
38+
const OFFSET_SET_METHOD_NOT_IMPLEMENTED = 28;
39+
const OFFSET_UNSET_METHOD_NOT_IMPLEMENTED = 29;
40+
41+
const JWKS_URI_IS_EMPTY = 30;
42+
43+
const JWK_MISSING_KEYS = 31;
44+
const JWT_KEYS_IS_EMPTY = 32;
45+
const JWT_ALGORITHM_NOT_SUPPORTED = 33;
46+
const JWK_IS_EMPTY = 34;
47+
const JWT_MISSING_KTY_PARAMETER = 35;
48+
const JWT_MISSING_ALG_PARAMETER = 36;
49+
const JWT_RSA_KEYS_NOT_SUPPORTED = 37;
50+
const JWT_RSA_KEYS_MISSING_N_AND_E = 38;
51+
const JWT_OPEN_SSL_ERROR = 39;
52+
const JWK_EC_D_IS_NOT_SET = 40;
53+
const JWT_EC_CRV_IS_EMPTY = 41;
54+
const JWK_UNSUPPORTED_EC_CURVE = 42;
55+
const JWT_X_AND_Y_ARE_EMPTY = 42;
56+
57+
const KEY_MATERIAL_IS_INVALID = 43;
58+
const KEY_MATERIAL_IS_EMPTY = 44;
59+
const KEY_ALGORITHM_IS_EMPTY = 45;
60+
}

src/ExpiredException.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44

55
class ExpiredException extends \UnexpectedValueException
66
{
7+
public const TOKEN_EXPIRED = 1;
78
}

src/JWK.php

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@ public static function parseKeySet(array $jwks, string $defaultAlg = null): arra
5050
$keys = [];
5151

5252
if (!isset($jwks['keys'])) {
53-
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
53+
throw new UnexpectedValueException(
54+
'"keys" member must exist in the JWK Set',
55+
ExceptionCodes::JWK_MISSING_KEYS
56+
);
5457
}
5558

5659
if (empty($jwks['keys'])) {
57-
throw new InvalidArgumentException('JWK Set did not contain any keys');
60+
throw new InvalidArgumentException(
61+
'JWK Set did not contain any keys',
62+
ExceptionCodes::JWT_KEYS_IS_EMPTY
63+
);
5864
}
5965

6066
foreach ($jwks['keys'] as $k => $v) {
@@ -65,7 +71,11 @@ public static function parseKeySet(array $jwks, string $defaultAlg = null): arra
6571
}
6672

6773
if (0 === \count($keys)) {
68-
throw new UnexpectedValueException('No supported algorithms found in JWK Set');
74+
throw new UnexpectedValueException(
75+
'No supported algorithms found in JWK Set',
76+
ExceptionCodes::JWT_ALGORITHM_NOT_SUPPORTED
77+
78+
);
6979
}
7080

7181
return $keys;
@@ -89,11 +99,17 @@ public static function parseKeySet(array $jwks, string $defaultAlg = null): arra
8999
public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
90100
{
91101
if (empty($jwk)) {
92-
throw new InvalidArgumentException('JWK must not be empty');
102+
throw new InvalidArgumentException(
103+
'JWK must not be empty',
104+
ExceptionCodes::JWK_IS_EMPTY
105+
);
93106
}
94107

95108
if (!isset($jwk['kty'])) {
96-
throw new UnexpectedValueException('JWK must contain a "kty" parameter');
109+
throw new UnexpectedValueException(
110+
'JWK must contain a "kty" parameter',
111+
ExceptionCodes::JWT_MISSING_KTY_PARAMETER
112+
);
97113
}
98114

99115
if (!isset($jwk['alg'])) {
@@ -102,44 +118,66 @@ public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
102118
// for parsing in this library. Use the $defaultAlg parameter when parsing the
103119
// key set in order to prevent this error.
104120
// @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
105-
throw new UnexpectedValueException('JWK must contain an "alg" parameter');
121+
throw new UnexpectedValueException(
122+
'JWK must contain an "alg" parameter',
123+
ExceptionCodes::JWT_MISSING_ALG_PARAMETER
124+
);
106125
}
107126
$jwk['alg'] = $defaultAlg;
108127
}
109128

110129
switch ($jwk['kty']) {
111130
case 'RSA':
112131
if (!empty($jwk['d'])) {
113-
throw new UnexpectedValueException('RSA private keys are not supported');
132+
throw new UnexpectedValueException(
133+
'RSA private keys are not supported',
134+
ExceptionCodes::JWT_RSA_KEYS_NOT_SUPPORTED
135+
);
114136
}
115137
if (!isset($jwk['n']) || !isset($jwk['e'])) {
116-
throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"');
138+
throw new UnexpectedValueException(
139+
'RSA keys must contain values for both "n" and "e"',
140+
ExceptionCodes::JWT_RSA_KEYS_MISSING_N_AND_E
141+
);
117142
}
118143

119144
$pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']);
120145
$publicKey = \openssl_pkey_get_public($pem);
121146
if (false === $publicKey) {
122147
throw new DomainException(
123-
'OpenSSL error: ' . \openssl_error_string()
148+
'OpenSSL error: ' . \openssl_error_string(),
149+
ExceptionCodes::JWT_OPEN_SSL_ERROR
124150
);
125151
}
126152
return new Key($publicKey, $jwk['alg']);
127153
case 'EC':
128154
if (isset($jwk['d'])) {
129155
// The key is actually a private key
130-
throw new UnexpectedValueException('Key data must be for a public key');
156+
throw new UnexpectedValueException(
157+
'Key data must be for a public key',
158+
ExceptionCodes::JWK_EC_D_IS_NOT_SET
159+
);
131160
}
132161

133162
if (empty($jwk['crv'])) {
134-
throw new UnexpectedValueException('crv not set');
163+
throw new UnexpectedValueException(
164+
'crv not set',
165+
ExceptionCodes::JWT_EC_CRV_IS_EMPTY
166+
);
135167
}
136168

137169
if (!isset(self::EC_CURVES[$jwk['crv']])) {
138-
throw new DomainException('Unrecognised or unsupported EC curve');
170+
throw new DomainException(
171+
'Unrecognised or unsupported EC curve',
172+
ExceptionCodes::JWK_UNSUPPORTED_EC_CURVE
173+
);
139174
}
140175

141176
if (empty($jwk['x']) || empty($jwk['y'])) {
142-
throw new UnexpectedValueException('x and y not set');
177+
throw new UnexpectedValueException(
178+
'x and y not set',
179+
ExceptionCodes::JWT_X_AND_Y_ARE_EMPTY
180+
);
143181
}
144182

145183
$publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']);

0 commit comments

Comments
 (0)