From 282a62e636947ee7a9f8e6213abe5b665ead8f76 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Thu, 14 Apr 2016 18:12:33 +0100 Subject: [PATCH 1/2] Use the new version of the notifications-python-client. This version no longer adds the req and pay to the claims of the jwt. The change is backward compatible so an older client that sends a jwt with the extra claims will pass authentication. Once all the clients have been updated to not include the extra claims some updates to exclude them from the method signatures will happen as well. --- app/authentication/auth.py | 6 +--- requirements.txt | 3 +- .../app/authentication/test_authentication.py | 28 ++++++++----------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/app/authentication/auth.py b/app/authentication/auth.py index 1903c2e1d..69ed4fc5f 100644 --- a/app/authentication/auth.py +++ b/app/authentication/auth.py @@ -1,6 +1,6 @@ from flask import request, jsonify, _request_ctx_stack, current_app from notifications_python_client.authentication import decode_jwt_token, get_token_issuer -from notifications_python_client.errors import TokenDecodeError, TokenRequestError, TokenExpiredError, TokenPayloadError +from notifications_python_client.errors import TokenDecodeError, TokenExpiredError from werkzeug.exceptions import abort from app.dao.api_key_dao import get_unsigned_secrets from app import api_user @@ -43,12 +43,8 @@ def requires_auth(): ) _request_ctx_stack.top.api_user = api_client return - except TokenRequestError: - errors_resp = authentication_response("Invalid token: request", 403) except TokenExpiredError: errors_resp = authentication_response("Invalid token: expired", 403) - except TokenPayloadError: - errors_resp = authentication_response("Invalid token: payload", 403) except TokenDecodeError: errors_resp = authentication_response("Invalid token: signature", 403) diff --git a/requirements.txt b/requirements.txt index 842233fc7..29d92855e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ twilio==4.6.0 monotonic==0.3 -git+https://github.com/alphagov/notifications-python-client.git@0.2.6#egg=notifications-python-client==0.2.6 +git+https://github.com/alphagov/notifications-python-client.git@0.5.0#egg=notifications-python-client==0.5.0 + git+https://github.com/alphagov/notifications-utils.git@4.1.1#egg=notifications-utils==4.1.1 diff --git a/tests/app/authentication/test_authentication.py b/tests/app/authentication/test_authentication.py index bbf706db4..bd15313ac 100644 --- a/tests/app/authentication/test_authentication.py +++ b/tests/app/authentication/test_authentication.py @@ -1,5 +1,6 @@ from datetime import datetime, timedelta +import pytest from notifications_python_client.authentication import create_jwt_token from flask import json, url_for, current_app from app.dao.api_key_dao import get_unsigned_secrets, save_model_api_key, get_unsigned_secret @@ -37,7 +38,7 @@ def test_should_not_allow_request_with_incorrect_token(notify_api, sample_user): assert data['message'] == 'Invalid token: signature' -def test_should_not_allow_incorrect_path(notify_api, sample_api_key): +def test_should_ignore_path(notify_api, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: token = create_jwt_token( @@ -49,12 +50,10 @@ def test_should_not_allow_incorrect_path(notify_api, sample_api_key): response = client.get( '/service', headers={'Authorization': "Bearer {}".format(token)}) - assert response.status_code == 403 - data = json.loads(response.get_data()) - assert data['message'] == 'Invalid token: request' + assert response.status_code == 200 -def test_should_not_allow_incorrect_method(notify_api, sample_api_key): +def test_should_ignore_request(notify_api, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: token = __create_post_token(sample_api_key.service_id, {}) @@ -62,9 +61,7 @@ def test_should_not_allow_incorrect_method(notify_api, sample_api_key): '/service', headers={'Authorization': "Bearer {}".format(token)} ) - assert response.status_code == 403 - data = json.loads(response.get_data()) - assert data['message'] == 'Invalid token: request' + assert response.status_code == 200 def test_should_not_allow_invalid_secret(notify_api, sample_api_key): @@ -152,17 +149,16 @@ def test_should_allow_valid_token_with_post_body(notify_api, sample_api_key): assert response.status_code == 200 -def test_should_not_allow_valid_token_with_invalid_post_body(notify_api, notify_db, notify_db_session, sample_api_key): +def test_should_allow_valid_token_with_invalid_post_body_but_fail_at_endpoint(notify_api, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: token = __create_post_token(str(sample_api_key.service_id), JSON_BODY) - response = client.post( - '/service', - data="spurious", - headers={'Authorization': 'Bearer {}'.format(token)}) - assert response.status_code == 403 - data = json.loads(response.get_data()) - assert data['message'] == 'Invalid token: payload' + with pytest.raises(AttributeError): + response = client.post( + '/service', + data="spurious", + headers={'Authorization': 'Bearer {}'.format(token)}) + assert response.status_code == 400 def test_authentication_passes_admin_client_token(notify_api, From c9761cd58a1a6d32d851f26df6fb50aaa88c8dc4 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Fri, 15 Apr 2016 10:59:00 +0100 Subject: [PATCH 2/2] remove unused import --- tests/app/authentication/test_authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/authentication/test_authentication.py b/tests/app/authentication/test_authentication.py index bd15313ac..408338f03 100644 --- a/tests/app/authentication/test_authentication.py +++ b/tests/app/authentication/test_authentication.py @@ -2,7 +2,7 @@ from datetime import datetime, timedelta import pytest from notifications_python_client.authentication import create_jwt_token -from flask import json, url_for, current_app +from flask import json, current_app from app.dao.api_key_dao import get_unsigned_secrets, save_model_api_key, get_unsigned_secret from app.models import ApiKey, Service