Attempt to debug SSL cert validation error

This changeset introduces a few changes:

* Removes UK Notify Logo URL and config
* Removes UK Notify API URL and replaces with Notify.gov
* Improves the error handler for HTTPErrors to provide actual exception and stack trace information

Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
This commit is contained in:
Carlo Costino
2025-07-29 17:33:13 -04:00
parent c1b071adea
commit f85efba737
4 changed files with 23 additions and 20 deletions

View File

@@ -161,7 +161,7 @@
"filename": "app/config.py", "filename": "app/config.py",
"hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc", "hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc",
"is_verified": false, "is_verified": false,
"line_number": 123, "line_number": 121,
"is_secret": false "is_secret": false
} }
], ],
@@ -634,5 +634,5 @@
} }
] ]
}, },
"generated_at": "2025-07-22T17:07:31Z" "generated_at": "2025-07-29T21:32:59Z"
} }

View File

@@ -2,6 +2,7 @@ import os
import pathlib import pathlib
import re import re
import secrets import secrets
import sys
from functools import partial from functools import partial
from time import monotonic from time import monotonic
from urllib.parse import unquote, urlparse, urlunparse from urllib.parse import unquote, urlparse, urlunparse
@@ -147,7 +148,6 @@ navigation = {
def _csp(config): def _csp(config):
asset_domain = config["ASSET_DOMAIN"] asset_domain = config["ASSET_DOMAIN"]
logo_domain = config["LOGO_CDN_DOMAIN"]
api_public_url = config["API_PUBLIC_URL"] api_public_url = config["API_PUBLIC_URL"]
api_public_ws_url = config["API_PUBLIC_WS_URL"] api_public_ws_url = config["API_PUBLIC_WS_URL"]
@@ -179,7 +179,7 @@ def _csp(config):
f"{api_public_ws_url}", f"{api_public_ws_url}",
], ],
"style-src": ["'self'", asset_domain], "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) @application.errorhandler(HTTPError)
def render_http_error(error): def render_http_error(error):
error_url = error.response.url if error.response else "unknown URL"
application.logger.warning( application.logger.warning(
"API {} failed with status {} message {}".format( f"API {error_url} failed with status {error.status_code} message {error.message}",
error.response.url if error.response else "unknown", exc_info=sys.exc_info(),
error.status_code, stack_info=True
error.message,
)
) )
error_code = error.status_code error_code = error.status_code
if error_code not in [401, 404, 403, 410]: if error_code not in [401, 404, 403, 410]:
# probably a 500 or 503. # 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 # 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. # legitimately return a 400, we should handle that within the view or the client that calls it.
application.logger.exception( application.logger.exception(
"API {} failed with status {} message {}".format( f"API {error_url} failed with status {error.status_code} message {error.message}",
error.response.url if error.response else "unknown", exc_info=sys.exc_info(),
error.status_code, stack_info=True
error.message,
)
) )
error_code = 500 error_code = 500
return _error_response(error_code) return _error_response(error_code)
@application.errorhandler(400) @application.errorhandler(400)

View File

@@ -19,9 +19,7 @@ class Config(object):
HEADER_COLOUR = ( HEADER_COLOUR = (
"#81878b" # mix of dark-grey and mid-grey "#81878b" # mix of dark-grey and mid-grey
) )
LOGO_CDN_DOMAIN = (
"static-logos.notifications.service.gov.uk" # TODO use our own CDN
)
ASSETS_DEBUG = False ASSETS_DEBUG = False
# Credentials # Credentials

View File

@@ -2,6 +2,8 @@ import json
import logging import logging
import urllib.parse import urllib.parse
from os import getenv
import requests import requests
from notifications_python_client import __version__ from notifications_python_client import __version__
@@ -10,21 +12,22 @@ from notifications_python_client.errors import HTTPError, InvalidResponse
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
API_PUBLIC_URL = getenv("API_PUBLIC_URL", "localhost")
class BaseAPIClient: class BaseAPIClient:
""" """
Base class for GOV.UK Notify API client. Base class for Notify.gov API client.
This class is not thread-safe. This class is not thread-safe.
""" """
def __init__( 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 Initialise the client
Error if either of base_url or secret missing 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 secret - application secret - used to sign the request:
:param timeout - request timeout on the client :param timeout - request timeout on the client
:return: :return: