Give specifc error when service doesn’t exist

If you sign a token with a service ID that doesn’t exist (say, for
example, that you get service ID and API key mixed up) then you get
an error saying that “no API keys exist for the service”. This is wrong
because the service doesn’t even exist.

This commit adds:
- code to check if the service does exist
- a specific error message for this case

The check does mean an extra database call to look up the service.
However this only happens _after_ looping through all the API keys. So
it shouldn’t have a performance implication for anyone using a valid API
key.
This commit is contained in:
Chris Hill-Scott
2016-09-16 08:44:08 +01:00
parent 6b3c899127
commit 1ce91997e8
2 changed files with 9 additions and 1 deletions

View File

@@ -1,8 +1,11 @@
from flask import request, jsonify, _request_ctx_stack, current_app from flask import request, jsonify, _request_ctx_stack, current_app
from sqlalchemy.orm.exc import NoResultFound
from notifications_python_client.authentication import decode_jwt_token, get_token_issuer 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
from app.dao.api_key_dao import get_model_api_keys from app.dao.api_key_dao import get_model_api_keys
from app.dao.services_dao import dao_fetch_service_by_id
class AuthError(Exception): class AuthError(Exception):
@@ -48,6 +51,11 @@ def requires_auth():
_request_ctx_stack.top.api_user = api_key _request_ctx_stack.top.api_user = api_key
return return
try:
dao_fetch_service_by_id(client)
except NoResultFound:
raise AuthError("Invalid token: service not found", 403)
if not api_keys: if not api_keys:
raise AuthError("Invalid token: no api keys for service", 403) raise AuthError("Invalid token: no api keys for service", 403)
else: else:

View File

@@ -211,7 +211,7 @@ def test_authentication_returns_error_when_service_doesnt_exit(
) )
assert response.status_code == 403 assert response.status_code == 403
error_message = json.loads(response.get_data()) error_message = json.loads(response.get_data())
assert error_message['message'] == {'token': ['Invalid token: no api keys for service']} assert error_message['message'] == {'token': ['Invalid token: service not found']}
def test_authentication_returns_error_when_service_has_no_secrets(notify_api, def test_authentication_returns_error_when_service_has_no_secrets(notify_api,