Skip to content

Commit b71ca0f

Browse files
committed
fix(jwt): remove InvalidTokenError, ExpiredTokenError based on ClaimError
1 parent a4a2e3e commit b71ca0f

3 files changed

Lines changed: 31 additions & 37 deletions

File tree

src/joserfc/_rfc7519/claims.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
MissingClaimError,
1111
InvalidClaimError,
1212
ExpiredTokenError,
13-
InvalidTokenError,
1413
)
1514

1615
Claims = dict[str, Any]
@@ -132,9 +131,9 @@ def validate_exp(self, value: int) -> None:
132131
containing a NumericDate value. Use of this claim is OPTIONAL.
133132
"""
134133
if not _validate_numeric_time(value):
135-
raise InvalidClaimError("exp")
134+
raise InvalidClaimError("exp", "Claim 'exp' must be a NumericDate value")
136135
if value < (self.now - self.leeway):
137-
raise ExpiredTokenError()
136+
raise ExpiredTokenError("exp")
138137
self.check_value("exp", value)
139138

140139
def validate_nbf(self, value: int) -> None:
@@ -147,9 +146,9 @@ def validate_nbf(self, value: int) -> None:
147146
NumericDate value. Use of this claim is OPTIONAL.
148147
"""
149148
if not _validate_numeric_time(value):
150-
raise InvalidClaimError("nbf")
149+
raise InvalidClaimError("nbf", "Claim 'nbf' must be a NumericDate value")
151150
if value > (self.now + self.leeway):
152-
raise InvalidTokenError()
151+
raise InvalidClaimError("nbf", "The token is not yet valid")
153152
self.check_value("nbf", value)
154153

155154
def validate_iat(self, value: int) -> None:
@@ -159,9 +158,9 @@ def validate_iat(self, value: int) -> None:
159158
claim is OPTIONAL.
160159
"""
161160
if not _validate_numeric_time(value):
162-
raise InvalidClaimError("iat")
161+
raise InvalidClaimError("iat", "Claim 'iat' must be a NumericDate value")
163162
if value > (self.now + self.leeway):
164-
raise InvalidTokenError()
163+
raise InvalidClaimError("iat", "The token was issued in the future")
165164
self.check_value("iat", value)
166165

167166

src/joserfc/errors.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ class ClaimError(JoseError):
201201
claim: str
202202
description = "Error claim: '{}'"
203203

204-
def __init__(self, claim: str):
204+
def __init__(self, claim: str, description: str | None = None):
205205
self.claim = claim
206-
description = self.description.format(claim)
206+
if description is None:
207+
description = self.description.format(claim)
207208
super(ClaimError, self).__init__(description=description)
208209

209210

@@ -231,22 +232,19 @@ class InsecureClaimError(ClaimError):
231232
description = "Insecure claim: '{}'"
232233

233234

234-
class ExpiredTokenError(JoseError):
235+
class ExpiredTokenError(ClaimError):
235236
"""This error is designed for JWT. It raised when the token is expired."""
236237

237238
error = "expired_token"
238239
description = "The token is expired"
239240

240241

241-
class InvalidTokenError(JoseError):
242-
"""This error is designed for JWT. It raised when the token is not valid yet."""
243-
244-
error = "invalid_token"
245-
description = "The token is not valid yet"
246-
247-
248242
class InvalidPayloadError(JoseError):
249243
"""This error is designed for JWT. It raised when the payload is
250244
not a valid JSON object."""
251245

252246
error = "invalid_payload"
247+
248+
249+
# compatibility
250+
InvalidTokenError = InvalidClaimError

tests/jwt/test_claims.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
InvalidClaimError,
1111
MissingClaimError,
1212
ExpiredTokenError,
13-
InvalidTokenError,
1413
)
1514

1615

@@ -90,7 +89,7 @@ def test_int_claims(self):
9089

9190
claims_requests.validate({"exp": now + 100, "nbf": now - 100, "iat": now})
9291
self.assertRaises(ExpiredTokenError, claims_requests.validate, {"exp": now - 100})
93-
self.assertRaises(InvalidTokenError, claims_requests.validate, {"nbf": now + 100})
92+
self.assertRaises(InvalidClaimError, claims_requests.validate, {"nbf": now + 100})
9493

9594
def test_validate_aud(self):
9695
claims_requests = jwt.JWTClaimsRegistry(aud={"essential": True, "value": "a"})
@@ -129,13 +128,13 @@ def test_validate_iat(self):
129128
claims_requests = jwt.JWTClaimsRegistry(leeway=500)
130129
now = int(time.time())
131130
claims_requests.validate({"iat": now})
132-
self.assertRaises(InvalidTokenError, claims_requests.validate, {"iat": now + 1000})
131+
self.assertRaises(InvalidClaimError, claims_requests.validate, {"iat": now + 1000})
133132

134133
def test_validate_nbf(self):
135134
claims_requests = jwt.JWTClaimsRegistry(leeway=500)
136135
now = int(time.time())
137136
claims_requests.validate({"nbf": now})
138-
self.assertRaises(InvalidTokenError, claims_requests.validate, {"nbf": now + 1000})
137+
self.assertRaises(InvalidClaimError, claims_requests.validate, {"nbf": now + 1000})
139138

140139
def test_claims_with_uuid_field(self):
141140
value = uuid.uuid4()
@@ -175,30 +174,28 @@ def test_validate_list_inclusion(self):
175174
claims_requests.validate({"custom_claim": "a"})
176175

177176
def test_validate_allow_blank(self):
177+
blank_values = ["", [], {}]
178+
178179
# Case 1: allow blank value
179180
claims_requests = jwt.JWTClaimsRegistry(custom_claim={"essential": True, "allow_blank": True})
180181
self.assertRaises(MissingClaimError, claims_requests.validate, {"custom_claim": None})
181-
claims_requests.validate({"custom_claim": ""})
182-
claims_requests.validate({"custom_claim": []})
183-
claims_requests.validate({"custom_claim": {}})
182+
for value in blank_values:
183+
claims_requests.validate({"custom_claim": value})
184184

185185
# Case 2: allow blank value without essential
186186
claims_requests = jwt.JWTClaimsRegistry(custom_claim={"allow_blank": True})
187187
claims_requests.validate({"custom_claim": None})
188-
claims_requests.validate({"custom_claim": ""})
189-
claims_requests.validate({"custom_claim": []})
190-
claims_requests.validate({"custom_claim": {}})
188+
for value in blank_values:
189+
claims_requests.validate({"custom_claim": value})
191190

192191
# Case 3: do not allow blank value
193-
claims_requests = jwt.JWTClaimsRegistry(custom_claim={"essential": True, "allow_blank": False})
194-
self.assertRaises(MissingClaimError, claims_requests.validate, {"custom_claim": None})
195-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": ""})
196-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": []})
197-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": {}})
198-
199-
# Case 4: do not allow blank value without essential
200192
claims_requests = jwt.JWTClaimsRegistry(custom_claim={"allow_blank": False})
201193
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": None})
202-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": ""})
203-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": []})
204-
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": {}})
194+
for value in blank_values:
195+
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": value})
196+
197+
# Case 4: do not allow blank value on essential claim
198+
claims_requests = jwt.JWTClaimsRegistry(custom_claim={"essential": True, "allow_blank": False})
199+
self.assertRaises(MissingClaimError, claims_requests.validate, {"custom_claim": None})
200+
for value in blank_values:
201+
self.assertRaises(InvalidClaimError, claims_requests.validate, {"custom_claim": value})

0 commit comments

Comments
 (0)