From f089b7512915d4b8f5724f33acd1f248d204c27d Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Thu, 3 Nov 2016 17:05:25 +0000 Subject: [PATCH] update python client to 2.0.0 this is to prevent 500 errors because <2.0.0 raised AssertionError if supplied JWT tokens were incorrectly formatted tests added --- app/authentication/auth.py | 12 +++--- requirements.txt | 2 +- .../app/authentication/test_authentication.py | 43 +++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/app/authentication/auth.py b/app/authentication/auth.py index 0ca700a62..ef830f6db 100644 --- a/app/authentication/auth.py +++ b/app/authentication/auth.py @@ -3,7 +3,7 @@ from sqlalchemy.exc import DataError from sqlalchemy.orm.exc import NoResultFound from notifications_python_client.authentication import decode_jwt_token, get_token_issuer -from notifications_python_client.errors import TokenDecodeError, TokenExpiredError +from notifications_python_client.errors import TokenDecodeError, TokenExpiredError, TokenIssuerError from app.dao.api_key_dao import get_model_api_keys from app.dao.services_dao import dao_fetch_service_by_id @@ -39,8 +39,10 @@ def requires_auth(): auth_token = get_auth_token(request) try: client = get_token_issuer(auth_token) - except TokenDecodeError: - raise AuthError("Invalid token: signature", 403) + except TokenDecodeError as e: + raise AuthError(e.message, 403) + except TokenIssuerError: + raise AuthError("Invalid token: iss not provided", 403) if client == current_app.config.get('ADMIN_CLIENT_USER_NAME'): return handle_admin_key(auth_token, current_app.config.get('ADMIN_CLIENT_SECRET')) @@ -76,8 +78,8 @@ def handle_admin_key(auth_token, secret): try: get_decode_errors(auth_token, secret) return - except TokenDecodeError: - raise AuthError("Invalid token: signature", 403) + except TokenDecodeError as e: + raise AuthError(e.message, 403) def get_decode_errors(auth_token, unsigned_secret): diff --git a/requirements.txt b/requirements.txt index a71037824..594f12317 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ monotonic==1.2 statsd==3.2.1 jsonschema==2.5.1 -git+https://github.com/alphagov/notifications-python-client.git@1.3.0#egg=notifications-python-client==1.3.0 +git+https://github.com/alphagov/notifications-python-client.git@2.0.0#egg=notifications-python-client==2.0.0 git+https://github.com/alphagov/notifications-utils.git@9.1.1#egg=notifications-utils==9.1.1 diff --git a/tests/app/authentication/test_authentication.py b/tests/app/authentication/test_authentication.py index 3b9ff1009..42c6fb9c3 100644 --- a/tests/app/authentication/test_authentication.py +++ b/tests/app/authentication/test_authentication.py @@ -1,3 +1,6 @@ +import jwt +import uuid +import time from datetime import datetime import pytest @@ -41,6 +44,46 @@ def test_should_not_allow_request_with_incorrect_token(notify_api, sample_user): assert data['message'] == {"token": ['Invalid token: signature']} +def test_should_not_allow_request_with_no_iss(client): + # code copied from notifications_python_client.authentication.py::create_jwt_token + headers = { + "typ": 'JWT', + "alg": 'HS256' + } + + claims = { + # 'iss': not provided + 'iat': int(time.time()) + } + + token = jwt.encode(payload=claims, key=str(uuid.uuid4()), headers=headers).decode() + + response = client.get('/service', headers={'Authorization': 'Bearer {}'.format(token)}) + assert response.status_code == 403 + data = json.loads(response.get_data()) + assert data['message'] == {"token": ['Invalid token: iss field not provided']} + + +def test_should_not_allow_request_with_no_iat(client, sample_api_key): + # code copied from notifications_python_client.authentication.py::create_jwt_token + headers = { + "typ": 'JWT', + "alg": 'HS256' + } + + claims = { + 'iss': str(sample_api_key.service_id) + # 'iat': not provided + } + + token = jwt.encode(payload=claims, key=str(uuid.uuid4()), headers=headers).decode() + + response = client.get('/service', headers={'Authorization': 'Bearer {}'.format(token)}) + assert response.status_code == 403 + data = json.loads(response.get_data()) + assert data['message'] == {"token": ['Invalid token: signature, api token is not valid']} + + def test_should_not_allow_invalid_secret(notify_api, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: