8000 Implemented new error codes for JWT verify functions · SHavanonda/firebase-admin-python@ec894a9 · GitHub
[go: up one dir, main page]

Skip to content

Commit ec894a9

Browse files
committed
Implemented new error codes for JWT verify functions
1 parent 216a3ce commit ec894a9

File tree

4 files changed

+51
-30
lines changed

4 files changed

+51
-30
lines changed

firebase_admin/_auth_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
])
3131
VALID_EMAIL_ACTION_TYPES = set(['VERIFY_EMAIL', 'EMAIL_SIGNIN', 'PASSWORD_RESET'])
3232

33+
# Error codes
34+
INVALID_ID_TOKEN = 'INVALID_ID_TOKEN'
35+
INVALID_SESSION_COOKIE = 'INVALID_SESSION_COOKIE'
36+
TOKEN_SIGN_FAILED = 'TOKEN_SIGN_FAILED'
37+
CERTIFICATE_FETCH_FAILED = 'CERTIFICATE_FETCH_FAILED'
38+
3339

3440
def validate_uid(uid, required=False):
3541
if uid is None and not required:

firebase_admin/_token_gen.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@
5454
METADATA_SERVICE_URL = ('http://metadata/computeMetadata/v1/instance/service-accounts/'
5555
'default/email')
5656

57-
# Error codes
58-
TOKEN_SIGN_FAILED = 'TOKEN_SIGN_FAILED'
59-
CERTIFICATE_FETCH_FAILED = 'CERTIFICATE_FETCH_FAILED'
60-
6157

6258
class _SigningProvider(object):
6359
"""Stores a reference to a google.auth.crypto.Signer."""
@@ -176,7 +172,7 @@ def create_custom_token(self, uid, developer_claims=None):
176172
exceptions.UNKNOWN,
177173
'Failed to sign custom token. {0}'.format(error),
178174
cause=error,
179-
auth_error_code=TOKEN_SIGN_FAILED)
175+
auth_error_code=_auth_utils.TOKEN_SIGN_FAILED)
180176

181177

182178
def create_session_cookie(self, id_token, expires_in):
@@ -227,11 +223,13 @@ def __init__(self, app):
227223
project_id=app.project_id, short_name='ID token',
228224
operation='verify_id_token()',
229225
doc_url='https://firebase.google.com/docs/auth/admin/verify-id-tokens',
226+
error_code=_auth_utils.INVALID_ID_TOKEN,
230227
cert_url=ID_TOKEN_CERT_URI, issuer=ID_TOKEN_ISSUER_PREFIX)
231228
self.cookie_verifier = _JWTVerifier(
232229
project_id=app.project_id, short_name='session cookie',
233230
operation='verify_session_cookie()',
234231
doc_url='https://firebase.google.com/docs/auth/admin/verify-id-tokens',
232+
error_code=_auth_utils.INVALID_SESSION_COOKIE,
235233
cert_url=COOKIE_CERT_URI, issuer=COOKIE_ISSUER_PREFIX)
236234

237235
def verify_id_token(self, id_token):
@@ -251,6 +249,7 @@ def __init__(self, **kwargs):
251249
self.url = kwargs.pop('doc_url')
252250
self.cert_url = kwargs.pop('cert_url')
253251
self.issuer = kwargs.pop('issuer')
252+
self.error_code = kwargs.pop('error_code')
254253
if self.short_name[0].lower() in 'aeiou':
255254
self.articled_short_name = 'an {0}'.format(self.short_name)
256255
else:
@@ -325,7 +324,8 @@ def verify(self, token, request):
325324
'{1}'.format(self.short_name, verify_id_token_msg))
326325

327326
if error_message:
328-
raise ValueError(error_message)
327+
raise _auth_utils.FirebaseAuthError(
328+
exceptions.INVALID_ARGUMENT, error_message, auth_error_code=self.error_code)
329329

330330
try:
331331
verified_claims = google.oauth2.id_token.verify_token(
@@ -340,4 +340,10 @@ def verify(self, token, request):
340340
exceptions.UNKNOWN,
341341
'Failed to fetch public key certificates. {0}'.format(error),
342342
cause=error,
343-
auth_error_code=CERTIFICATE_FETCH_FAILED)
343+
auth_error_code=_auth_utils.CERTIFICATE_FETCH_FAILED)
344+
except ValueError as error:
345+
raise _auth_utils.FirebaseAuthError(
346+
exceptions.INVALID_ARGUMENT,
347+
'Invalid Firebase {0}: {1}'.format(self.short_name, error),
348+
cause=error,
349+
auth_error_code=self.error_code)

firebase_admin/auth.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@
3232

3333

3434
_AUTH_ATTRIBUTE = '_auth'
35+
36+
CERTIFICATE_FETCH_FAILED = _auth_utils.CERTIFICATE_FETCH_FAILED
3537
ID_TOKEN_REVOKED = 'ID_TOKEN_REVOKED'
38+
INVALID_ID_TOKEN = _auth_utils.INVALID_ID_TOKEN
39+
INVALID_SESSION_COOKIE = _auth_utils.INVALID_SESSION_COOKIE
3640
SESSION_COOKIE_REVOKED = 'SESSION_COOKIE_REVOKED'
41+
TOKEN_SIGN_FAILED = _auth_utils.TOKEN_SIGN_FAILED
3742
UNEXPECTED_RESPONSE = _user_mgt.UNEXPECTED_RESPONSE
3843
USER_NOT_FOUND = _user_mgt.USER_NOT_FOUND
3944

tests/test_token_gen.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_sign_with_iam_error(self):
222222
with pytest.raises(auth.FirebaseAuthError) as excinfo:
223223
auth.create_custom_token(MOCK_UID, app=app)
224224
assert excinfo.value.code == exceptions.UNKNOWN
225-
assert excinfo.value._auth_error_code == _token_gen.TOKEN_SIGN_FAILED
225+
assert excinfo.value._auth_error_code == auth.TOKEN_SIGN_FAILED
226226
assert iam_resp in str(excinfo.value)
227227
finally:
228228
firebase_admin.delete_app(app)
@@ -341,14 +341,6 @@ class TestVerifyIdToken(object):
341341
'iat': int(time.time()) - 10000,
342342
'exp': int(time.time()) - 3600
343343
}),
344-
'NoneToken': None,
345-
'EmptyToken': '',
346-
'BoolToken': True,
347-
'IntToken': 1,
348-
'ListToken': [],
349-
'EmptyDictToken': {},
350-
'NonEmptyDictToken': {'a': 1},
351-
'BadFormatToken': 'foobar'
352344
}
353345

354346
@pytest.mark.parametrize('id_token', valid_tokens.values(), ids=list(valid_tokens))
@@ -390,11 +382,19 @@ def test_revoked_token_do_not_check_revoked(self, user_mgt_app, revoked_tokens,
390382
assert claims['admin'] is True
391383
assert claims['uid'] == claims['sub']
392384

385+
@pytest.mark.parametrize('id_token', [None, '', 'foobar', True, 1, [], {}, {'a': 1}])
386+
def test_invalid_jwt(self, user_mgt_app, id_token):
387+
_overwrite_cert_request(user_mgt_app, MOCK_REQUEST)
388+
with pytest.raises(ValueError):
389+
auth.verify_id_token(id_token, app=user_mgt_app)
390+
393391
@pytest.mark.parametrize('id_token', invalid_tokens.values(), ids=list(invalid_tokens))
394392
def test_invalid_token(self, user_mgt_app, id_token):
395393
_overwrite_cert_request(user_mgt_app, MOCK_REQUEST)
396-
with pytest.raises(ValueError):
394+
with pytest.raises(auth.FirebaseAuthError) as excinfo:
397395
auth.verify_id_token(id_token, app=user_mgt_app)
396+
assert excinfo.value.code == exceptions.INVALID_ARGUMENT
397+
assert excinfo.value.auth_error_code == auth.INVALID_ID_TOKEN
398398

399399
def test_project_id_option(self):
400400
app = firebase_admin.initialize_app(
@@ -419,15 +419,17 @@ def test_project_id_env_var(self, env_var_app):
419419
def test_custom_token(self, auth_app):
420420
id_token = auth.create_custom_token(MOCK_UID, app=auth_app)
421421
_overwrite_cert_request(auth_app, MOCK_REQUEST)
422-
with pytest.raises(ValueError):
422+
with pytest.raises(auth.FirebaseAuthError) as excinfo:
423423
auth.verify_id_token(id_token, app=auth_app)
424+
assert excinfo.value.code == exceptions.INVALID_ARGUMENT
425+
assert excinfo.value.auth_error_code == auth.INVALID_ID_TOKEN
424426

425427
def test_certificate_request_failure(self, user_mgt_app):
426428
_overwrite_cert_request(user_mgt_app, testutils.MockRequest(404, 'not found'))
427429
with pytest.raises(auth.FirebaseAuthError) as excinfo:
428430
auth.verify_id_token(TEST_ID_TOKEN, app=user_mgt_app)
429431
assert excinfo.value.code == exceptions.UNKNOWN
430-
assert excinfo.value.auth_error_code == 'CERTIFICATE_FETCH_FAILED'
432+
assert excinfo.value.auth_error_code == auth.CERTIFICATE_FETCH_FAILED
431433

432434

433435
class TestVerifySessionCookie(object):
@@ -452,14 +454,6 @@ class TestVerifySessionCookie(object):
452454
'iat': int(time.time()) - 10000,
453455
'exp': int(time.time()) - 3600
454456
}),
455-
'NoneCookie': None,
456-
'EmptyCookie': '',
457-
'BoolCookie': True,
458-
'IntCookie': 1,
459-
'ListCookie': [],
460-
'EmptyDictCookie': {},
461-
'NonEmptyDictCookie': {'a': 1},
462-
'BadFormatCookie': 'foobar',
463457
'IDToken': TEST_ID_TOKEN,
464458
}
465459

@@ -496,11 +490,19 @@ def test_revoked_cookie_does_not_check_revoked(self, user_mgt_app, revoked_token
496490
assert claims['admin'] is True
497491
assert claims['uid'] == claims['sub']
498492

493+
@pytest.mark.parametrize('cookie', [None, '', 'foobar', True, 1, [], {}, {'a': 1}])
494+
def test_invalid_jwt(self, user_mgt_app, cookie):
495+
_overwrite_cert_request(user_mgt_app, MOCK_REQUEST)
496+
with pytest.raises(ValueError):
497+
auth.verify_session_cookie(cookie, app=user_mgt_app)
498+
499499
@pytest.mark.parametrize('cookie', invalid_cookies.values(), ids=list(invalid_cookies))
500500
def test_invalid_cookie(self, user_mgt_app, cookie):
501501
_overwrite_cert_request(user_mgt_app, MOCK_REQUEST)
502-
with pytest.raises(ValueError):
502+
with pytest.raises(auth.FirebaseAuthError) as excinfo:
503503
auth.verify_session_cookie(cookie, app=user_mgt_app)
504+
assert excinfo.value.code == exceptions.INVALID_ARGUMENT
505+
assert excinfo.value.auth_error_code == auth.INVALID_SESSION_COOKIE
504506

505507
def test_project_id_option(self):
506508
app = firebase_admin.initialize_app(
@@ -522,15 +524,17 @@ def test_project_id_env_var(self, env_var_app):
522524
def test_custom_token(self, auth_app):
523525
custom_token = auth.create_custom_token(MOCK_UID, app=auth_app)
524526
_overwrite_cert_request(auth_app, MOCK_REQUEST)
525-
with pytest.raises(ValueError):
527+
with pytest.raises(auth.FirebaseAuthError) as excinfo:
526528
auth.verify_session_cookie(custom_token, app=auth_app)
529+
assert excinfo.value.code == exceptions.INVALID_ARGUMENT
530+
assert excinfo.value.auth_error_code == auth.INVALID_SESSION_COOKIE
527531

528532
def test_certificate_request_failure(self, user_mgt_app):
529533
_overwrite_cert_request(user_mgt_app, testutils.MockRequest(404, 'not found'))
530534
with pytest.raises(auth.FirebaseAuthError) as excinfo:
531535
auth.verify_session_cookie(TEST_SESSION_COOKIE, app=user_mgt_app)
532536
assert excinfo.value.code == exceptions.UNKNOWN
533-
assert excinfo.value.auth_error_code == 'CERTIFICATE_FETCH_FAILED'
537+
assert excinfo.value.auth_error_code == auth.CERTIFICATE_FETCH_FAILED
534538

535539

536540
class TestCertificateCaching(object):

0 commit comments

Comments
 (0)
0