diff --git a/app/__init__.py b/app/__init__.py index 024c7bff7..fe6ba515d 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -2,6 +2,7 @@ import os import pathlib import re import secrets +import sys from functools import partial from time import monotonic from urllib.parse import unquote, urlparse, urlunparse @@ -147,7 +148,6 @@ navigation = { def _csp(config): asset_domain = config["ASSET_DOMAIN"] - logo_domain = config["LOGO_CDN_DOMAIN"] api_public_url = config["API_PUBLIC_URL"] api_public_ws_url = config["API_PUBLIC_WS_URL"] @@ -179,7 +179,7 @@ def _csp(config): f"{api_public_ws_url}", ], "style-src": ["'self'", asset_domain], - "img-src": ["'self'", asset_domain, logo_domain], + "img-src": ["'self'", asset_domain], } @@ -545,26 +545,28 @@ def register_errorhandlers(application): # noqa (C901 too complex) @application.errorhandler(HTTPError) def render_http_error(error): + error_url = error.response.url if error.response else "unknown URL" + application.logger.warning( - "API {} failed with status {} message {}".format( - error.response.url if error.response else "unknown", - error.status_code, - error.message, - ) + f"API {error_url} failed with status {error.status_code} message {error.message}", + exc_info=sys.exc_info(), + stack_info=True ) + error_code = error.status_code + if error_code not in [401, 404, 403, 410]: # probably a 500 or 503. # it might be a 400, which we should handle as if it's an internal server error. If the API might # legitimately return a 400, we should handle that within the view or the client that calls it. application.logger.exception( - "API {} failed with status {} message {}".format( - error.response.url if error.response else "unknown", - error.status_code, - error.message, - ) + f"API {error_url} failed with status {error.status_code} message {error.message}", + exc_info=sys.exc_info(), + stack_info=True ) + error_code = 500 + return _error_response(error_code) @application.errorhandler(400) diff --git a/notifications_python_client/base.py b/notifications_python_client/base.py index 32f76808d..6312416ea 100644 --- a/notifications_python_client/base.py +++ b/notifications_python_client/base.py @@ -2,6 +2,8 @@ import json import logging import urllib.parse +from os import getenv + import requests from notifications_python_client import __version__ @@ -10,21 +12,23 @@ from notifications_python_client.errors import HTTPError, InvalidResponse logger = logging.getLogger(__name__) +API_PUBLIC_URL = getenv("API_PUBLIC_URL", "localhost") + class BaseAPIClient: """ - Base class for GOV.UK Notify API client. + Base class for Notify.gov API client. This class is not thread-safe. """ def __init__( - self, api_key, base_url="https://api.notifications.service.gov.uk", timeout=30 + self, api_key, base_url=API_PUBLIC_URL, timeout=30 ): """ Initialise the client Error if either of base_url or secret missing - :param base_url - base URL of GOV.UK Notify API: + :param base_url - base URL of Notify.gov API: :param secret - application secret - used to sign the request: :param timeout - request timeout on the client :return: diff --git a/tests/app/main/views/test_headers.py b/tests/app/main/views/test_headers.py index 5551d9035..33ef2c540 100644 --- a/tests/app/main/views/test_headers.py +++ b/tests/app/main/views/test_headers.py @@ -49,4 +49,4 @@ def test_owasp_useful_headers_set( expected_sources <= actual_sources ), f"Missing sources in connect-src: {expected_sources - actual_sources}" assert search(r"style-src 'self' static\.example\.com 'nonce-.*';", csp) - assert search(r"img-src 'self' static\.example\.com static-logos\.test\.com", csp) + assert search(r"img-src 'self' static\.example\.com", csp)