Merge branch 'main' into 2085-conditional-within-the-my-activity-page-needs-to-be-fixed

This commit is contained in:
Beverly Nguyen
2025-07-29 22:27:03 -07:00
5 changed files with 25 additions and 21 deletions

View File

@@ -161,7 +161,7 @@
"filename": "app/config.py",
"hashed_secret": "577a4c667e4af8682ca431857214b3a920883efc",
"is_verified": false,
"line_number": 123,
"line_number": 121,
"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 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)

View File

@@ -19,9 +19,7 @@ class Config(object):
HEADER_COLOUR = (
"#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
# Credentials

View File

@@ -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:

View File

@@ -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)