From 968636252040fd03ab1301938272c5829979ca8c Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Thu, 4 Jul 2024 09:49:34 +1000 Subject: [PATCH 1/2] Remove temporary key check bypass --- src/live_data_server/plots/view_util.py | 4 +--- tests/test_post_get.py | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/live_data_server/plots/view_util.py b/src/live_data_server/plots/view_util.py index 5071c23..d65858e 100644 --- a/src/live_data_server/plots/view_util.py +++ b/src/live_data_server/plots/view_util.py @@ -45,9 +45,7 @@ def request_processor(request, instrument, run_id): try: client_key = request.GET.get("key", None) server_key = generate_key(instrument, run_id) - # Temporary bypass during testing - # Remove client_key is None condition when we deploy - if client_key is None or server_key is None or client_key == server_key: + if server_key is None or client_key == server_key: return fn(request, instrument, run_id) return HttpResponse(status=401) except: # noqa: E722 diff --git a/tests/test_post_get.py b/tests/test_post_get.py index 9a06bd0..8c13e3b 100644 --- a/tests/test_post_get.py +++ b/tests/test_post_get.py @@ -104,10 +104,9 @@ def test_get_request(self, data_server): assert http_request.text == "No data available for REF_M 12346" # test GET request - no key - # TODO: this should return 401 unauthorized url = base_url http_request = requests.get(url) - assert http_request.status_code == HTTP_OK + assert http_request.status_code == HTTP_UNAUTHORIZED # test GET request - wrong key url = f"{base_url}?key=WRONG-KEY" From e754bee25e7031f3431045feb8b8c4bb716993bb Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Thu, 4 Jul 2024 13:39:36 +1000 Subject: [PATCH 2/2] Add ability to supply secret key via HTTP Authorization request header This will fall back to checking for the query string for key which should be remove after WebMon/WebRef support the new method. --- src/live_data_server/plots/view_util.py | 19 +++++++++++++------ tests/test_post_get.py | 21 ++++++++++++++------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/live_data_server/plots/view_util.py b/src/live_data_server/plots/view_util.py index d65858e..2d128a9 100644 --- a/src/live_data_server/plots/view_util.py +++ b/src/live_data_server/plots/view_util.py @@ -24,10 +24,8 @@ def generate_key(instrument, run_id): secret_key = settings.LIVE_PLOT_SECRET_KEY if len(secret_key) == 0: return None - else: - h = hashlib.sha1() - h.update(("%s%s%s" % (instrument.upper(), secret_key, run_id)).encode("utf-8")) - return h.hexdigest() + + return hashlib.sha1(f"{instrument.upper()}{secret_key}{run_id}".encode("utf-8")).hexdigest() def check_key(fn): @@ -43,9 +41,18 @@ def request_processor(request, instrument, run_id): Decorator function """ try: - client_key = request.GET.get("key", None) server_key = generate_key(instrument, run_id) - if server_key is None or client_key == server_key: + if server_key is None: + return fn(request, instrument, run_id) + + client_key = request.META.get("HTTP_AUTHORIZATION") + + # getting the client_key from request.GET.get("key") should be + # removed after WebMon/WebRef supports Authorization request header + if client_key is None: + client_key = request.GET.get("key") + + if client_key == server_key: return fn(request, instrument, run_id) return HttpResponse(status=401) except: # noqa: E722 diff --git a/tests/test_post_get.py b/tests/test_post_get.py index 8c13e3b..43f3256 100644 --- a/tests/test_post_get.py +++ b/tests/test_post_get.py @@ -113,6 +113,13 @@ def test_get_request(self, data_server): http_request = requests.get(url) assert http_request.status_code == HTTP_UNAUTHORIZED + # test GET request - wrong key + http_request = requests.get( + base_url, + headers={"Authorization": "WRONG-KEY"}, + ) + assert http_request.status_code == HTTP_UNAUTHORIZED + def test_upload_plot_data_json(self): # test that when you upload json you can get back the same stuff instrument = "instrument0" @@ -145,7 +152,8 @@ def test_upload_plot_data_json(self): # now get the data as json response = requests.get( - f"{TEST_URL}/plots/{instrument}/{run_number}/update/json/?key={_generate_key(instrument, run_number)}" + f"{TEST_URL}/plots/{instrument}/{run_number}/update/json/", + headers={"Authorization": _generate_key(instrument, run_number)}, ) assert response.status_code == HTTP_OK assert response.headers["Content-Type"] == "application/json" @@ -153,7 +161,8 @@ def test_upload_plot_data_json(self): # now try getting it as html, should fail response = requests.get( - f"{TEST_URL}/plots/{instrument}/{run_number}/update/html/?key={_generate_key(instrument, run_number)}" + f"{TEST_URL}/plots/{instrument}/{run_number}/update/html/", + headers={"Authorization": _generate_key(instrument, run_number)}, ) assert response.status_code == HTTP_NOT_FOUND assert response.text == "No data available for instrument0 123" @@ -234,9 +243,7 @@ def _generate_key(instrument, run_id): @param run_id: run number """ secret_key = os.environ.get("LIVE_PLOT_SECRET_KEY") - if len(secret_key) == 0: + if secret_key is None or len(secret_key) == 0: return None - else: - h = hashlib.sha1() - h.update(("%s%s%s" % (instrument.upper(), secret_key, run_id)).encode("utf-8")) - return h.hexdigest() + + return hashlib.sha1(f"{instrument.upper()}{secret_key}{run_id}".encode("utf-8")).hexdigest()