Skip to content

Commit 7d5bf13

Browse files
authored
Merge pull request #234 from NHSDigital/DTOSS-10207-use-consumer-for-cmapi
DTOSS-10207: use Consumer Key for CMAPI requests
2 parents cc311d7 + 807ac2e commit 7d5bf13

5 files changed

Lines changed: 32 additions & 3 deletions

File tree

manage_breast_screening/config/.env.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ DATABASE_USER=manage
88
DATABASE_SSLMODE=allow
99
DATABASE_HOST=localhost
1010
LOG_QUERIES=0
11+
CMAPI_CONSUMER_KEY=some-consumer

manage_breast_screening/notifications/api_client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
EXPIRES_IN_MINUTES = 5
1111

12+
AUTHORIZATION_HEADER_NAME = "authorization"
13+
CONSUMER_KEY_NAME = "x-consumer-key"
14+
1215

1316
class OAuthError(Exception):
1417
pass
@@ -51,7 +54,8 @@ def headers(self) -> dict:
5154
"content-type": "application/vnd.api+json",
5255
"accept": "application/vnd.api+json",
5356
"x-correlation-id": str(uuid.uuid4()),
54-
"authorization": f"Bearer {self.bearer_token()}",
57+
AUTHORIZATION_HEADER_NAME: f"Bearer {self.bearer_token()}",
58+
CONSUMER_KEY_NAME: os.getenv("CMAPI_CONSUMER_KEY"),
5559
}
5660

5761
def bearer_token(self) -> str:

manage_breast_screening/notifications/tests/dependencies/cmapi_stub/app.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@ def token():
2121

2222
@app.route("/message/batch", methods=["POST"])
2323
def message_batches():
24-
json_data = request.json
24+
valid_headers, headers_error_message = verify_headers_for_consumers(
25+
dict(request.headers)
26+
)
2527

26-
messages = populate_message_ids(json_data["data"]["attributes"]["messages"])
28+
if not valid_headers:
29+
return json.dumps({"status": "failed", "error": headers_error_message}), 400
30+
31+
json_data = request.json
2732

2833
if not validate_with_schema(json_data):
2934
return json.dumps({"error": "Invalid body"}), 422
3035

36+
messages = populate_message_ids(json_data["data"]["attributes"]["messages"])
37+
3138
return json.dumps(
3239
{
3340
"data": {
@@ -66,6 +73,20 @@ def validate_with_schema(data: dict):
6673
return False, str(e)
6774

6875

76+
def verify_headers_for_consumers(headers: dict) -> tuple[bool, str]:
77+
lc_headers = header_keys_to_lower(headers)
78+
if lc_headers.get("authorization") is None:
79+
return False, "Missing Authorization header"
80+
if lc_headers.get("x-consumer-key") is None:
81+
return False, "Missing Consumer key header"
82+
83+
return True, ""
84+
85+
86+
def header_keys_to_lower(headers: dict) -> dict:
87+
return {k.lower(): v for k, v in headers.items()}
88+
89+
6990
def populate_message_ids(messages: list[dict]) -> list[dict]:
7091
for message in messages:
7192
message["id"] = uid(27) if not message.get("id") else message["id"]

manage_breast_screening/notifications/tests/integration/test_api_client_can_call_cmapi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def setup(self, monkeypatch):
2222
monkeypatch.setenv("OAUTH_API_KEY", "a1b2c3d4")
2323
monkeypatch.setenv("OAUTH_API_KID", "test-1")
2424
monkeypatch.setenv("PRIVATE_KEY", "test-key")
25+
monkeypatch.setenv("CMAPI_CONSUMER_KEY", "consumer-key")
2526

2627
@pytest.fixture
2728
def routing_plan_id(self):

manage_breast_screening/notifications/tests/test_api_client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def setup(self, monkeypatch):
2626
monkeypatch.setenv("OAUTH_API_KEY", "a1b2c3d4")
2727
monkeypatch.setenv("OAUTH_API_KID", "test-1")
2828
monkeypatch.setenv("PRIVATE_KEY", "test-key")
29+
monkeypatch.setenv("CMAPI_CONSUMER_KEY", "consumer-key")
2930

3031
@pytest.mark.django_db
3132
def test_send_message_batch(self, mock_jwt_encode, routing_plan_id):
@@ -54,6 +55,7 @@ def test_send_message_batch(self, mock_jwt_encode, routing_plan_id):
5455
assert request.headers["Authorization"] == "Bearer 000111"
5556
assert request.headers["Content-Type"] == "application/vnd.api+json"
5657
assert request.headers["Accept"] == "application/vnd.api+json"
58+
assert request.headers["X-Consumer-Key"] == "consumer-key"
5759

5860
assert attributes["messageBatchReference"] == str(message_batch.id)
5961
assert attributes["routingPlanId"] == message_batch.routing_plan_id

0 commit comments

Comments
 (0)