From e887ac5e8d7eeeaa2a688427aadceff6124e55ae Mon Sep 17 00:00:00 2001 From: Antonio Lorusso Date: Wed, 17 Apr 2024 16:40:35 +0100 Subject: [PATCH] GAP-2594:encrypt Authorization secret --- tests/unit/test_app.py | 10 +++++++++- upload_function/app.py | 22 ++++++++++++++++++---- upload_function/requirements.txt | 3 ++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py index e0f3e4f..95f10e0 100644 --- a/tests/unit/test_app.py +++ b/tests/unit/test_app.py @@ -2,7 +2,7 @@ from unittest import TestCase, mock import urllib.parse -from upload_function.app import parse_s3_object_url, parse_pathname, clean_result, s3_location +from upload_function.app import parse_s3_object_url, parse_pathname, clean_result, s3_location, encrypt_secret GOOD_ENCODED_PATHNAME: str = "1/81ccea53-9d35-4acf-8cdb-883dfe22e9e9/273acbe3-c937-496e-86f8-f5a0166843c3/" \ "2022-07-08%20Grant%20Application%20Definition%20-%20Definition%20-" \ @@ -93,6 +93,14 @@ def test_not_clean_result_location_will_include_quarantine_bucket(self): location = s3_location(False, "path") self.assertIn("bad", location) +class EncryptionTests(TestCase): + + def test_encryption_returns_string(self): + secret = "secret" + key ='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwA9Z7o0z3DYfB+NiqnXCzCoPwDMARvL6gmbELeW9pmVIT1ZJY4u7PL9CGP2HTpKVVHlULRFEYWt1KZnMt0p+7zjmVwxYSVkrZNLOV0hWO6ej9EfLyIKduiNL1lmSN94yTgt0NbU8nIaUzkOWxf321ER/Ru/QMlmX+nLJfF0z1s4oarfY7mIdgPSrPcwgaHsyvuiYjZFKoph23CAu3335ZudZ//HEiWxo2+nRjltCelBLHCVpsCk+Rbfp38RNEfDvjFC4wzzosH65cQ2KyFKdyOOiqUO447zmHNh15CD/+g0kxgjyZSIWMkPFrEf+x66ruTRisYOObKdUezLpos+jXQIDAQAB'; + result = encrypt_secret(secret, key) + self.assertIsInstance(result, str) + self.assertNotEqual(secret, result) if __name__ == '__main__': unittest.main() diff --git a/upload_function/app.py b/upload_function/app.py index cdabb33..c0ab607 100644 --- a/upload_function/app.py +++ b/upload_function/app.py @@ -5,6 +5,10 @@ import urllib.parse import requests from requests.exceptions import Timeout, HTTPError, RequestException +from cryptography.hazmat.primitives import serialization, hashes +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.backends import default_backend +import base64 # useful for more indepth debugging # import http @@ -25,9 +29,19 @@ S3_DOMAIN_PATTERN = r's3(\..+)?\.amazonaws.com' API_SECRET = os.environ.get('API_SECRET') +API_PUBLIC_KEY = os.environ.get('API_PUBLIC_KEY') -HEADERS = {"Content-Type": "application/json", - "Authorization": API_SECRET} +def encrypt_secret(secret, public_key): + # Load the public key + public_key_with_begin_and_end = f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----" + public_key_bytes = public_key_with_begin_and_end.encode('utf-8') + public_key = serialization.load_pem_public_key(public_key_bytes, + backend=default_backend()) + + encrypted_bytes = public_key.encrypt(secret.encode('utf-8'), + padding.PKCS1v15()) + + return base64.b64encode(encrypted_bytes).decode('utf-8') def parse_s3_object_url(url_string) -> str: @@ -79,7 +93,8 @@ def update_attachment(subscription_id: str, question_id: str, pathname: str, is_ url: str = ATTACHMENT_URL.format(subscription_id, question_id) endpoint: str = str(ATTACHMENT_HOST) + url logger.debug("Passing request to %s", endpoint) - + HEADERS = {"Content-Type": "application/json", + "Authorization": encrypt_secret(API_SECRET, API_PUBLIC_KEY)} try: response = requests.put(endpoint, json={'uri': pathname, 'isClean': is_clean}, headers=HEADERS, timeout=ATTACHMENT_TIMEOUT) @@ -104,7 +119,6 @@ def s3_location(is_clean: bool, pathname: str) -> str: bucket = CLEAN_BUCKET if is_clean else QUARANTINE_BUCKET return "s3://" + bucket + "/" + pathname - def lambda_handler(event, context): logger.debug("Received event: %s", json.dumps(event, indent=2)) for record in event['Records']: diff --git a/upload_function/requirements.txt b/upload_function/requirements.txt index 663bd1f..ace9e84 100644 --- a/upload_function/requirements.txt +++ b/upload_function/requirements.txt @@ -1 +1,2 @@ -requests \ No newline at end of file +requests +cryptography \ No newline at end of file