Skip to content

Commit 2ba733f

Browse files
authored
Merge pull request #323 from NHSDigital/pem-update-for-podman
Added PEM file fallback for local development with podman
2 parents ef7839c + 3c7fbff commit 2ba733f

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ POSTGRES_DB=lung_cancer_screening
1212
POSTGRES_USER=lung_cancer_screening
1313
POSTGRES_PASSWORD=password
1414

15+
# If using Podman;
16+
# * Remove quotes from the variables below.
17+
# * Remove the value for OIDC_RP_CLIENT_PRIVATE_KEY
18+
# * Create a file for the PEM key and save in .secrets folder.
19+
# * Check the file path for OIDC_RP_CLIENT_PRIVATE_KEY_FILE matches the file path for your PEM key file.
20+
1521
OIDC_RP_CLIENT_PRIVATE_KEY="MYSUPERSECRETPRIVATEKEY"
22+
OIDC_RP_CLIENT_PRIVATE_KEY_FILE=/secrets/oidc_rp_client_private_key.pem
1623
OIDC_RP_CLIENT_ID="lcrc"
1724
OIDC_OP_FQDN="https://example.com"
1825
NHS_LOGIN_SETTINGS_URL="https://settings.example.com"

lung_cancer_screening/questions/tests/unit/test_auth.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
from django.conf import settings
55
from cryptography.hazmat.primitives.asymmetric import rsa
66
from cryptography.hazmat.primitives import serialization
7+
import tempfile
8+
import os
79

810
from ...auth import NHSLoginOIDCBackend
911
from ...tests.factories.user_factory import UserFactory
12+
from lung_cancer_screening.settings import pem_key_env
1013

1114
User = get_user_model()
1215

1316
@override_settings(
1417
OIDC_RP_CLIENT_PRIVATE_KEY=None, # Will be set per test
18+
OIDC_RP_CLIENT_PRIVATE_KEY_FILE=None,
1519
OIDC_OP_TOKEN_ENDPOINT='https://auth.example.com/token',
1620
OIDC_RP_CLIENT_ID='test-client-id',
1721
OIDC_RP_REDIRECT_URI='https://app.example.com/callback',
@@ -224,3 +228,21 @@ def test_get_token_nhs_login_error_response_no_json(self, mock_post):
224228
self.backend.get_token(token_payload)
225229

226230
self.assertIn('Token request failed: 500', str(context.exception))
231+
232+
def test_pem_key_file_env(self):
233+
os.environ['OIDC_RP_CLIENT_PRIVATE_KEY'] = ''
234+
temp_pem_key = self.test_private_key_pem
235+
# Create a temporary PEM key file
236+
with tempfile.NamedTemporaryFile(delete=False, suffix=".pem", mode='w') as temp_file:
237+
temp_file.write(temp_pem_key)
238+
temp_file_path = temp_file.name
239+
240+
try:
241+
os.environ['OIDC_RP_CLIENT_PRIVATE_KEY_FILE'] = temp_file_path
242+
result = pem_key_env("OIDC_RP_CLIENT_PRIVATE_KEY", "OIDC_RP_CLIENT_PRIVATE_KEY_FILE")
243+
self.assertEqual(result, temp_pem_key)
244+
245+
finally:
246+
os.environ.pop('OIDC_RP_CLIENT_PRIVATE_KEY_FILE', None)
247+
os.environ['OIDC_RP_CLIENT_PRIVATE_KEY'] = 'MYSUPERSECRETPRIVATEKEY'
248+
os.remove(temp_file_path)

lung_cancer_screening/settings.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ def list_env(key):
2626
return value.split(",") if value else []
2727

2828

29+
def pem_key_env(key, file_path_key=None):
30+
# Env var takes precedence over file path.
31+
value = environ.get(key)
32+
if value:
33+
return value
34+
35+
# Fall back to pem key file
36+
if file_path_key:
37+
file_path = environ.get(file_path_key)
38+
if file_path:
39+
return Path(file_path).read_text()
40+
41+
return None
42+
2943
# Build paths inside the project like this: BASE_DIR / 'subdir'.
3044
BASE_DIR = Path(__file__).resolve().parent
3145

@@ -225,7 +239,10 @@ def list_env(key):
225239
# Set a dummy value to satisfy mozilla-django-oidc's requirement
226240
# It w't be used since we override get_token() to use private key JWT
227241
OIDC_RP_CLIENT_SECRET = "not-used-private-key-jwt"
228-
OIDC_RP_CLIENT_PRIVATE_KEY = environ.get("OIDC_RP_CLIENT_PRIVATE_KEY")
242+
OIDC_RP_CLIENT_PRIVATE_KEY = pem_key_env(
243+
"OIDC_RP_CLIENT_PRIVATE_KEY",
244+
file_path_key="OIDC_RP_CLIENT_PRIVATE_KEY_FILE"
245+
)
229246
OIDC_OP_FQDN = environ.get("OIDC_OP_FQDN")
230247
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{OIDC_OP_FQDN}/authorize"
231248
OIDC_OP_TOKEN_ENDPOINT = f"{OIDC_OP_FQDN}/token"

0 commit comments

Comments
 (0)