From 1d993327c0cef64ff62802b081023e6f9758f2b8 Mon Sep 17 00:00:00 2001 From: ekneg54 Date: Mon, 26 Aug 2024 14:03:04 +0200 Subject: [PATCH] fix and refactor http input tests --- CHANGELOG.md | 4 ++ logprep/connector/http/input.py | 2 + tests/unit/connector/test_http_input.py | 70 +++++++++++++++++++------ 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 130a14d77..e74ccbfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ ### Bugfix +## 13.1.1 + +### Bugfix + * fixes a bug in the `http_output` used by the http generator, where the timeout parameter does only set the read_timeout not the write_timeout * fixes a bug in the `http_input` not handling decode errors diff --git a/logprep/connector/http/input.py b/logprep/connector/http/input.py index 09388cde4..96e26b112 100644 --- a/logprep/connector/http/input.py +++ b/logprep/connector/http/input.py @@ -141,6 +141,8 @@ async def func_wrapper(*args, **kwargs): return else: raise HTTPMethodNotAllowed(["POST"]) + except HTTPUnauthorized as error: + raise error from error except queue.Full as error: raise HTTPTooManyRequests(description="Logprep Message Queue is full.") from error except Exception as error: # pylint: disable=broad-except diff --git a/tests/unit/connector/test_http_input.py b/tests/unit/connector/test_http_input.py index 249419d55..b2e9c88b7 100644 --- a/tests/unit/connector/test_http_input.py +++ b/tests/unit/connector/test_http_input.py @@ -4,6 +4,7 @@ import gzip import json import multiprocessing +import queue import random import re from copy import deepcopy @@ -116,16 +117,10 @@ def test_get_method_returns_200_with_authentication(self): def test_get_error_code_too_many_requests(self): data = {"message": "my log message"} + self.object.messages.put = mock.MagicMock() + self.object.messages.put.side_effect = queue.Full() session = requests.Session() - for _ in range(100): - resp = session.post(url=f"{self.target}/json", json=data, timeout=0.5) - assert self.object.messages.qsize() == 100 - resp = requests.post(url=f"{self.target}/json", json=data, timeout=0.5) - assert self.object.messages._maxsize == 100 - assert resp.status_code == 429 - for _ in range(100): - resp = session.post(url=f"{self.target}/json", json=data, timeout=0.5) - resp = requests.get(url=f"{self.target}/json", json=data, timeout=0.5) + resp = session.post(url=f"{self.target}/json", json=data, timeout=0.5) assert resp.status_code == 429 def test_json_endpoint_accepts_post_request(self): @@ -322,26 +317,71 @@ def test_get_next_with_hmac_of_raw_message(self): connector_next_msg, _ = connector.get_next(1) assert connector_next_msg == expected_event, "Output event with hmac is not as expected" - def test_endpoint_has_basic_auth(self, credentials_file_path): + def test_endpoint_returns_401_if_authorization_not_provided(self, credentials_file_path): mock_env = {ENV_NAME_LOGPREP_CREDENTIALS_FILE: credentials_file_path} + data = {"message": "my log message"} with mock.patch.dict("os.environ", mock_env): new_connector = Factory.create({"test connector": self.CONFIG}) new_connector.pipeline_index = 1 new_connector.setup() - resp = requests.post(url=f"{self.target}/auth-json-file", timeout=0.5) + resp = requests.post( + url=f"{self.target}/auth-json-file", timeout=0.5, data=json.dumps(data) + ) assert resp.status_code == 401 + + def test_endpoint_returns_401_on_wrong_authorization(self, credentials_file_path): + mock_env = {ENV_NAME_LOGPREP_CREDENTIALS_FILE: credentials_file_path} + data = {"message": "my log message"} + with mock.patch.dict("os.environ", mock_env): + new_connector = Factory.create({"test connector": self.CONFIG}) + new_connector.pipeline_index = 1 + new_connector.setup() basic = HTTPBasicAuth("wrong", "credentials") - resp = requests.post(url=f"{self.target}/auth-json-file", auth=basic, timeout=0.5) + resp = requests.post( + url=f"{self.target}/auth-json-file", auth=basic, timeout=0.5, json=data + ) assert resp.status_code == 401 + + def test_endpoint_returns_200_on_correct_authorization_with_password_from_file( + self, credentials_file_path + ): + mock_env = {ENV_NAME_LOGPREP_CREDENTIALS_FILE: credentials_file_path} + data = {"message": "my log message"} + with mock.patch.dict("os.environ", mock_env): + new_connector = Factory.create({"test connector": self.CONFIG}) + new_connector.pipeline_index = 1 + new_connector.setup() basic = HTTPBasicAuth("user", "file_password") - resp = requests.post(url=f"{self.target}/auth-json-file", auth=basic, timeout=0.5) + resp = requests.post( + url=f"{self.target}/auth-json-file", auth=basic, timeout=0.5, json=data + ) assert resp.status_code == 200 + + def test_endpoint_returns_200_on_correct_authorization_with_password_within_credentials_file( + self, credentials_file_path + ): + mock_env = {ENV_NAME_LOGPREP_CREDENTIALS_FILE: credentials_file_path} + data = {"message": "my log message"} + with mock.patch.dict("os.environ", mock_env): + new_connector = Factory.create({"test connector": self.CONFIG}) + new_connector.pipeline_index = 1 + new_connector.setup() basic = HTTPBasicAuth("user", "secret_password") - resp = requests.post(url=f"{self.target}/auth-json-secret", auth=basic, timeout=0.5) + resp = requests.post( + url=f"{self.target}/auth-json-secret", auth=basic, timeout=0.5, json=data + ) assert resp.status_code == 200 + + def test_endpoint_returns_200_on_correct_authorization_for_subpath(self, credentials_file_path): + mock_env = {ENV_NAME_LOGPREP_CREDENTIALS_FILE: credentials_file_path} + data = {"message": "my log message"} + with mock.patch.dict("os.environ", mock_env): + new_connector = Factory.create({"test connector": self.CONFIG}) + new_connector.pipeline_index = 1 + new_connector.setup() basic = HTTPBasicAuth("user", "password") resp = requests.post( - url=f"{self.target}/auth-json-secret/AB/json", auth=basic, timeout=0.5 + url=f"{self.target}/auth-json-secret/AB/json", auth=basic, timeout=0.5, json=data ) assert resp.status_code == 200