From e8cd88420bf0f6ae10bd45a6071714041e962bfe Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 8 Jul 2022 17:05:16 +0300 Subject: [PATCH 01/17] Island: Add ConfiguredPropagationCredentials resource --- monkey/monkey_island/cc/app.py | 5 ++++ .../configured_propagation_credentials.py | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 408839b6c..df8497f65 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -28,6 +28,9 @@ from monkey_island.cc.resources.blackbox.monkey_blackbox_endpoint import MonkeyB from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import ( TelemetryBlackboxEndpoint, ) +from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( + ConfiguredPropagationCredentials, +) from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation @@ -185,6 +188,8 @@ def init_restful_endpoints(api: FlaskDIWrapper): api.add_resource(FileUpload) api.add_resource(PropagationCredentials) + api.add_resource(ConfiguredPropagationCredentials) + api.add_resource(RemoteRun) api.add_resource(VersionUpdate) api.add_resource(StopAgentCheck) diff --git a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py new file mode 100644 index 000000000..0794e979c --- /dev/null +++ b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py @@ -0,0 +1,27 @@ +import logging + +from flask import jsonify, request + +from common.credentials import Credentials +from monkey_island.cc.repository import ICredentialsRepository +from monkey_island.cc.resources.AbstractResource import AbstractResource + +logger = logging.getLogger(__name__) + + +class ConfiguredPropagationCredentials(AbstractResource): + # API Spec: Resource name should be plural + urls = ["/api/propagation-credentials/configured"] + + def __init__(self, credentials_repository: ICredentialsRepository): + self._credentials_repository = credentials_repository + + def get(self): + return jsonify(self._credentials_repository.get_configured_credentials()) + + def post(self): + credentials = Credentials.from_mapping(request.json) + self._credentials_repository.save_configured_credentials(credentials) + + def delete(self): + self._credentials_repository.remove_configured_credentials() From 90b8b3fc4e966e79d01f3a12e7a1b1e5bda45790 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 8 Jul 2022 17:09:44 +0300 Subject: [PATCH 02/17] Island: Add StolenPropagationCredentials resource --- monkey/monkey_island/cc/app.py | 4 +++ .../cc/resources/credentials/__init__.py | 0 .../stolen_propagation_credentials.py | 27 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 monkey/monkey_island/cc/resources/credentials/__init__.py create mode 100644 monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index df8497f65..d9874b460 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -31,6 +31,9 @@ from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import ( from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( ConfiguredPropagationCredentials, ) +from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( + StolenPropagationCredentials, +) from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation @@ -189,6 +192,7 @@ def init_restful_endpoints(api: FlaskDIWrapper): api.add_resource(PropagationCredentials) api.add_resource(ConfiguredPropagationCredentials) + api.add_resource(StolenPropagationCredentials) api.add_resource(RemoteRun) api.add_resource(VersionUpdate) diff --git a/monkey/monkey_island/cc/resources/credentials/__init__.py b/monkey/monkey_island/cc/resources/credentials/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py new file mode 100644 index 000000000..2ebda8302 --- /dev/null +++ b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py @@ -0,0 +1,27 @@ +import logging + +from flask import jsonify, request + +from common.credentials import Credentials +from monkey_island.cc.repository import ICredentialsRepository +from monkey_island.cc.resources.AbstractResource import AbstractResource + +logger = logging.getLogger(__name__) + + +class StolenPropagationCredentials(AbstractResource): + # API Spec: Resource name should be plural + urls = ["/api/propagation-credentials/stolen"] + + def __init__(self, credentials_repository: ICredentialsRepository): + self._credentials_repository = credentials_repository + + def get(self): + return jsonify(self._credentials_repository.get_stolen_credentials()) + + def post(self): + credentials = Credentials.from_mapping(request.json) + self._credentials_repository.save_stolen_credentials(credentials) + + def delete(self): + self._credentials_repository.remove_stolen_credentials() From 0d06f8fd003bc1d5389ca9bebb0cb1e523b5f8d4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 11 Jul 2022 10:10:09 +0300 Subject: [PATCH 03/17] Island: Remove unnecessary comments in credentials --- .../resources/credentials/configured_propagation_credentials.py | 1 - .../cc/resources/credentials/stolen_propagation_credentials.py | 1 - 2 files changed, 2 deletions(-) diff --git a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py index 0794e979c..dad2592c6 100644 --- a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py @@ -10,7 +10,6 @@ logger = logging.getLogger(__name__) class ConfiguredPropagationCredentials(AbstractResource): - # API Spec: Resource name should be plural urls = ["/api/propagation-credentials/configured"] def __init__(self, credentials_repository: ICredentialsRepository): diff --git a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py index 2ebda8302..74d509721 100644 --- a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py @@ -10,7 +10,6 @@ logger = logging.getLogger(__name__) class StolenPropagationCredentials(AbstractResource): - # API Spec: Resource name should be plural urls = ["/api/propagation-credentials/stolen"] def __init__(self, credentials_repository: ICredentialsRepository): From 872d062649463f15035dd6970801a9162c9b4040 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 11 Jul 2022 10:28:48 +0300 Subject: [PATCH 04/17] Island: Move propagation_credentials.py to credentials dir --- monkey/monkey_island/cc/app.py | 2 +- .../cc/resources/{ => credentials}/propagation_credentials.py | 0 .../monkey_island/cc/resources/test_propagation_credentials.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename monkey/monkey_island/cc/resources/{ => credentials}/propagation_credentials.py (100%) diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index d9874b460..5d3d475e5 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -48,7 +48,7 @@ from monkey_island.cc.resources.node import Node from monkey_island.cc.resources.node_states import NodeStates from monkey_island.cc.resources.pba_file_download import PBAFileDownload from monkey_island.cc.resources.pba_file_upload import FileUpload -from monkey_island.cc.resources.propagation_credentials import PropagationCredentials +from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.ransomware_report import RansomwareReport from monkey_island.cc.resources.root import Root from monkey_island.cc.resources.security_report import SecurityReport diff --git a/monkey/monkey_island/cc/resources/propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py similarity index 100% rename from monkey/monkey_island/cc/resources/propagation_credentials.py rename to monkey/monkey_island/cc/resources/credentials/propagation_credentials.py diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py index 728aef1c3..01748c215 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py @@ -9,7 +9,7 @@ from tests.unit_tests.monkey_island.conftest import get_url_for_resource from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository -from monkey_island.cc.resources.propagation_credentials import PropagationCredentials +from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials @pytest.fixture From c5ba5d444d236ef2e9b42ca07bcb426a2a36d414 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 11 Jul 2022 12:24:28 +0300 Subject: [PATCH 05/17] Island: Add returns to the post and get credential resources --- .../resources/credentials/configured_propagation_credentials.py | 2 ++ .../cc/resources/credentials/stolen_propagation_credentials.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py index dad2592c6..fcb6839b3 100644 --- a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py @@ -21,6 +21,8 @@ class ConfiguredPropagationCredentials(AbstractResource): def post(self): credentials = Credentials.from_mapping(request.json) self._credentials_repository.save_configured_credentials(credentials) + return {}, 204 def delete(self): self._credentials_repository.remove_configured_credentials() + return {}, 204 diff --git a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py index 74d509721..e733b2297 100644 --- a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py @@ -21,6 +21,8 @@ class StolenPropagationCredentials(AbstractResource): def post(self): credentials = Credentials.from_mapping(request.json) self._credentials_repository.save_stolen_credentials(credentials) + return {}, 204 def delete(self): self._credentials_repository.remove_stolen_credentials() + return {}, 204 From d437f02544ef13a6122d839fd3f35b1464ebc25c Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 11 Jul 2022 12:27:36 +0300 Subject: [PATCH 06/17] UT: Add stolen and configured credentials endpoint tests --- ...stub_propagation_credentials_repository.py | 5 ++- .../cc/resources/credentials/__init__.py | 0 .../cc/resources/credentials/conftest.py | 15 +++++++ ...test_configured_propagation_credentials.py | 43 +++++++++++++++++++ .../test_propagation_credentials.py | 0 .../test_stolen_propagation_credentials.py | 40 +++++++++++++++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py create mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py create mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py rename monkey/tests/unit_tests/monkey_island/cc/resources/{ => credentials}/test_propagation_credentials.py (100%) create mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py diff --git a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py index 237d28b85..ccf72a9ec 100644 --- a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py +++ b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py @@ -25,7 +25,10 @@ class StubPropagationCredentialsRepository(ICredentialsRepository): pass def get_stolen_credentials(self) -> Sequence[Credentials]: - pass + return [ + Credentials.from_mapping(PROPAGATION_CREDENTIALS_1, monkey_guid="some_guid"), + Credentials.from_mapping(PROPAGATION_CREDENTIALS_2, monkey_guid="second_guid"), + ] def get_all_credentials(self) -> Sequence[Credentials]: diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py new file mode 100644 index 000000000..ab1bee2af --- /dev/null +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py @@ -0,0 +1,15 @@ +import pytest +from tests.common import StubDIContainer +from tests.monkey_island import StubPropagationCredentialsRepository + +from monkey_island.cc.repository import ICredentialsRepository + + +@pytest.fixture +def flask_client(build_flask_client): + container = StubDIContainer() + + container.register(ICredentialsRepository, StubPropagationCredentialsRepository) + + with build_flask_client(container) as flask_client: + yield flask_client diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py new file mode 100644 index 000000000..03d6a2414 --- /dev/null +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py @@ -0,0 +1,43 @@ +import json + +from tests.monkey_island import PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2 +from tests.unit_tests.monkey_island.conftest import get_url_for_resource + +from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( + ConfiguredPropagationCredentials, +) +from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( + StolenPropagationCredentials, +) + + +def test_configured_propagation_credentials_endpoint_get(flask_client): + configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) + + resp = flask_client.get(configured_propagation_credentials_url) + + assert resp.status_code == 200 + actual_propagation_credentials = json.loads(resp.data) + assert len(actual_propagation_credentials) == 2 + + # TODO: delete the removal of monkey_guid key when the serialization of credentials + del actual_propagation_credentials[0]["monkey_guid"] + assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 + del actual_propagation_credentials[1]["monkey_guid"] + assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 + + +def test_configured_propagation_credentials_endpoint_post(flask_client): + configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) + + resp = flask_client.post(configured_propagation_credentials_url, json=PROPAGATION_CREDENTIALS_1) + + assert resp.status_code == 204 + + +def test_configured_propagation_credentials_endpoint_delete(flask_client): + configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) + + resp = flask_client.delete(configured_propagation_credentials_url) + + assert resp.status_code == 204 diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py similarity index 100% rename from monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py rename to monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py new file mode 100644 index 000000000..75976fb1d --- /dev/null +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py @@ -0,0 +1,40 @@ +import json + +from tests.monkey_island import PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2 +from tests.unit_tests.monkey_island.conftest import get_url_for_resource + +from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( + StolenPropagationCredentials, +) + + +def test_stolen_propagation_credentials_endpoint_get(flask_client): + stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) + + resp = flask_client.get(stolen_propagation_credentials_url) + + assert resp.status_code == 200 + actual_propagation_credentials = json.loads(resp.data) + assert len(actual_propagation_credentials) == 2 + + # TODO: delete the removal of monkey_guid key when the serialization of credentials + del actual_propagation_credentials[0]["monkey_guid"] + assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 + del actual_propagation_credentials[1]["monkey_guid"] + assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 + + +def test_stolen_propagation_credentials_endpoint_post(flask_client): + stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) + + resp = flask_client.post(stolen_propagation_credentials_url, json=PROPAGATION_CREDENTIALS_1) + + assert resp.status_code == 204 + + +def test_stolen_propagation_credentials_endpoint_delete(flask_client): + stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) + + resp = flask_client.delete(stolen_propagation_credentials_url) + + assert resp.status_code == 204 From 2a2ab52da1c333c88e8ff7c5c4cf0e8bcfc18ae6 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 13:30:14 -0400 Subject: [PATCH 07/17] Island: Remove monkey_guid from StubPropagationCredentialsRepository --- .../monkey_island/stub_propagation_credentials_repository.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py index ccf72a9ec..73cae99bf 100644 --- a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py +++ b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py @@ -25,10 +25,7 @@ class StubPropagationCredentialsRepository(ICredentialsRepository): pass def get_stolen_credentials(self) -> Sequence[Credentials]: - return [ - Credentials.from_mapping(PROPAGATION_CREDENTIALS_1, monkey_guid="some_guid"), - Credentials.from_mapping(PROPAGATION_CREDENTIALS_2, monkey_guid="second_guid"), - ] + return [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] def get_all_credentials(self) -> Sequence[Credentials]: From aaf1009504c1caa3c95e20541e38e61d970c7eb2 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 13:54:06 -0400 Subject: [PATCH 08/17] UT: Add InMemoryCredentialsRepository --- .../in_memory_credentials_repository.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 monkey/tests/monkey_island/in_memory_credentials_repository.py diff --git a/monkey/tests/monkey_island/in_memory_credentials_repository.py b/monkey/tests/monkey_island/in_memory_credentials_repository.py new file mode 100644 index 000000000..6eb8155e8 --- /dev/null +++ b/monkey/tests/monkey_island/in_memory_credentials_repository.py @@ -0,0 +1,35 @@ +from typing import Sequence + +from common.credentials import Credentials +from monkey_island.cc.repository import ICredentialsRepository + + +class InMemoryCredentialsRepository(ICredentialsRepository): + def __init__(self): + self._configured_credentials = [] + self._stolen_credentials = [] + + def get_configured_credentials(self) -> Sequence[Credentials]: + return self._configured_credentials + + def get_stolen_credentials(self) -> Sequence[Credentials]: + return self._stolen_credentials + + def get_all_credentials(self) -> Sequence[Credentials]: + return [*self._configured_credentials, *self._stolen_credentials] + + def save_configured_credentials(self, credentials: Sequence[Credentials]): + self._configured_credentials.extend(credentials) + + def save_stolen_credentials(self, credentials: Sequence[Credentials]): + self._stolen_credentials.extend(credentials) + + def remove_configured_credentials(self): + self._configured_credentials = [] + + def remove_stolen_credentials(self): + self._stolen_credentials = [] + + def remove_all_credentials(self): + self.remove_configured_credentials() + self.remove_stolen_credentials() From 1af21b372cbd00a647dd0fb216c599fed855f10c Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:10:42 -0400 Subject: [PATCH 09/17] UT: Move PROPAGATION_CREDENTIALS into data_for_tests --- .../data_for_tests/propagation_credentials.py | 18 +++++++++++++++ monkey/tests/monkey_island/__init__.py | 5 +--- ...stub_propagation_credentials_repository.py | 23 +++++-------------- ...test_configured_propagation_credentials.py | 8 +++---- .../test_stolen_propagation_credentials.py | 5 +++- 5 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 monkey/tests/data_for_tests/propagation_credentials.py diff --git a/monkey/tests/data_for_tests/propagation_credentials.py b/monkey/tests/data_for_tests/propagation_credentials.py new file mode 100644 index 000000000..5d41aca1e --- /dev/null +++ b/monkey/tests/data_for_tests/propagation_credentials.py @@ -0,0 +1,18 @@ +from common.credentials import Credentials, LMHash, NTHash, Password, Username + +username = "m0nk3y_user" +special_username = "m0nk3y.user" +nt_hash = "C1C58F96CDF212B50837BC11A00BE47C" +lm_hash = "299BD128C1101FD6299BD128C1101FD6" +password_1 = "trytostealthis" +password_2 = "password" +password_3 = "12345678" + +PROPAGATION_CREDENTIALS_1 = Credentials( + identities=(Username(username),), + secrets=(NTHash(nt_hash), LMHash(lm_hash), Password(password_1)), +) +PROPAGATION_CREDENTIALS_2 = Credentials( + identities=(Username(username), Username(special_username)), + secrets=(Password(password_1), Password(password_2), Password(password_3)), +) diff --git a/monkey/tests/monkey_island/__init__.py b/monkey/tests/monkey_island/__init__.py index ee3098390..8bf003b21 100644 --- a/monkey/tests/monkey_island/__init__.py +++ b/monkey/tests/monkey_island/__init__.py @@ -4,7 +4,4 @@ from .open_error_file_repository import OpenErrorFileRepository from .in_memory_agent_configuration_repository import InMemoryAgentConfigurationRepository from .in_memory_simulation_configuration import InMemorySimulationRepository from .stub_propagation_credentials_repository import StubPropagationCredentialsRepository -from .stub_propagation_credentials_repository import ( - PROPAGATION_CREDENTIALS_1, - PROPAGATION_CREDENTIALS_2, -) +from .in_memory_credentials_repository import InMemoryCredentialsRepository diff --git a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py index 73cae99bf..51c8964b2 100644 --- a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py +++ b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py @@ -1,23 +1,12 @@ from typing import Sequence -from common.credentials import Credentials, LMHash, NTHash, Password, Username -from monkey_island.cc.repository import ICredentialsRepository +from tests.data_for_tests.propagation_credentials import ( + PROPAGATION_CREDENTIALS_1, + PROPAGATION_CREDENTIALS_2, +) -fake_username = "m0nk3y_user" -fake_special_username = "m0nk3y.user" -fake_nt_hash = "C1C58F96CDF212B50837BC11A00BE47C" -fake_lm_hash = "299BD128C1101FD6299BD128C1101FD6" -fake_password_1 = "trytostealthis" -fake_password_2 = "password" -fake_password_3 = "12345678" -PROPAGATION_CREDENTIALS_1 = Credentials( - identities=(Username(fake_username),), - secrets=(NTHash(fake_nt_hash), LMHash(fake_lm_hash), Password(fake_password_1)), -) -PROPAGATION_CREDENTIALS_2 = Credentials( - identities=(Username(fake_username), Username(fake_special_username)), - secrets=(Password(fake_password_1), Password(fake_password_2), Password(fake_password_3)), -) +from common.credentials import Credentials +from monkey_island.cc.repository import ICredentialsRepository class StubPropagationCredentialsRepository(ICredentialsRepository): diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py index 03d6a2414..5b4844fee 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py @@ -1,14 +1,14 @@ import json -from tests.monkey_island import PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2 +from tests.data_for_tests.propagation_credentials import ( + PROPAGATION_CREDENTIALS_1, + PROPAGATION_CREDENTIALS_2, +) from tests.unit_tests.monkey_island.conftest import get_url_for_resource from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( ConfiguredPropagationCredentials, ) -from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( - StolenPropagationCredentials, -) def test_configured_propagation_credentials_endpoint_get(flask_client): diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py index 75976fb1d..138849085 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py @@ -1,6 +1,9 @@ import json -from tests.monkey_island import PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2 +from tests.data_for_tests.propagation_credentials import ( + PROPAGATION_CREDENTIALS_1, + PROPAGATION_CREDENTIALS_2, +) from tests.unit_tests.monkey_island.conftest import get_url_for_resource from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( From 4a4c4324fb92c705261f76585abcdf8c7a4b86b2 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:13:24 -0400 Subject: [PATCH 10/17] UT: Add more propagation credentials --- monkey/tests/data_for_tests/propagation_credentials.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/monkey/tests/data_for_tests/propagation_credentials.py b/monkey/tests/data_for_tests/propagation_credentials.py index 5d41aca1e..df6c213cf 100644 --- a/monkey/tests/data_for_tests/propagation_credentials.py +++ b/monkey/tests/data_for_tests/propagation_credentials.py @@ -16,3 +16,11 @@ PROPAGATION_CREDENTIALS_2 = Credentials( identities=(Username(username), Username(special_username)), secrets=(Password(password_1), Password(password_2), Password(password_3)), ) +PROPAGATION_CREDENTIALS_3 = Credentials( + identities=(Username(username),), + secrets=(Password(password_1),), +) +PROPAGATION_CREDENTIALS_4 = Credentials( + identities=(Username(username),), + secrets=(Password(password_2),), +) From a684b12dc3c93602d986d413e5a46b9e73c372d2 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:31:04 -0400 Subject: [PATCH 11/17] Island: Combine PropagationCredentials and StolenPropagationCredentials --- monkey/monkey_island/cc/app.py | 6 +- .../credentials/propagation_credentials.py | 33 ++++++- .../stolen_propagation_credentials.py | 28 ------ .../test_propagation_credentials.py | 94 +++++++++++++++++-- .../test_stolen_propagation_credentials.py | 43 --------- 5 files changed, 115 insertions(+), 89 deletions(-) delete mode 100644 monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py delete mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 5d3d475e5..7d053fa25 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -31,9 +31,7 @@ from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import ( from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( ConfiguredPropagationCredentials, ) -from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( - StolenPropagationCredentials, -) +from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation @@ -48,7 +46,6 @@ from monkey_island.cc.resources.node import Node from monkey_island.cc.resources.node_states import NodeStates from monkey_island.cc.resources.pba_file_download import PBAFileDownload from monkey_island.cc.resources.pba_file_upload import FileUpload -from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.ransomware_report import RansomwareReport from monkey_island.cc.resources.root import Root from monkey_island.cc.resources.security_report import SecurityReport @@ -192,7 +189,6 @@ def init_restful_endpoints(api: FlaskDIWrapper): api.add_resource(PropagationCredentials) api.add_resource(ConfiguredPropagationCredentials) - api.add_resource(StolenPropagationCredentials) api.add_resource(RemoteRun) api.add_resource(VersionUpdate) diff --git a/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py index 8d72fe427..0c8b65988 100644 --- a/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py @@ -1,4 +1,6 @@ -from flask import make_response +from http import HTTPStatus + +from flask import make_response, request from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository @@ -6,12 +8,35 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource class PropagationCredentials(AbstractResource): - urls = ["/api/propagation-credentials"] + urls = ["/api/propagation-credentials", "/api/propagation-credentials/stolen-credentials"] def __init__(self, credentials_repository: ICredentialsRepository): self._credentials_repository = credentials_repository def get(self): - propagation_credentials = self._credentials_repository.get_all_credentials() + propagation_credentials = [] - return make_response(Credentials.to_json_array(propagation_credentials), 200) + if request.url.endswith("/stolen-credentials"): + propagation_credentials = self._credentials_repository.get_stolen_credentials() + else: + propagation_credentials = self._credentials_repository.get_all_credentials() + + return make_response(Credentials.to_json_array(propagation_credentials), HTTPStatus.OK) + + def post(self): + credentials = [Credentials.from_json(c) for c in request.json] + + if request.url.endswith("/stolen-credentials"): + self._credentials_repository.save_stolen_credentials(credentials) + else: + return {}, HTTPStatus.METHOD_NOT_ALLOWED + + return {}, HTTPStatus.NO_CONTENT + + def delete(self): + if request.url.endswith("/stolen-credentials"): + self._credentials_repository.remove_stolen_credentials() + else: + return {}, HTTPStatus.METHOD_NOT_ALLOWED + + return {}, HTTPStatus.NO_CONTENT diff --git a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py deleted file mode 100644 index e733b2297..000000000 --- a/monkey/monkey_island/cc/resources/credentials/stolen_propagation_credentials.py +++ /dev/null @@ -1,28 +0,0 @@ -import logging - -from flask import jsonify, request - -from common.credentials import Credentials -from monkey_island.cc.repository import ICredentialsRepository -from monkey_island.cc.resources.AbstractResource import AbstractResource - -logger = logging.getLogger(__name__) - - -class StolenPropagationCredentials(AbstractResource): - urls = ["/api/propagation-credentials/stolen"] - - def __init__(self, credentials_repository: ICredentialsRepository): - self._credentials_repository = credentials_repository - - def get(self): - return jsonify(self._credentials_repository.get_stolen_credentials()) - - def post(self): - credentials = Credentials.from_mapping(request.json) - self._credentials_repository.save_stolen_credentials(credentials) - return {}, 204 - - def delete(self): - self._credentials_repository.remove_stolen_credentials() - return {}, 204 diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py index 01748c215..a6750b80d 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py @@ -1,34 +1,110 @@ +import json +from http import HTTPStatus + import pytest from tests.common import StubDIContainer -from tests.monkey_island import ( +from tests.data_for_tests.propagation_credentials import ( PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2, - StubPropagationCredentialsRepository, + PROPAGATION_CREDENTIALS_3, + PROPAGATION_CREDENTIALS_4, ) -from tests.unit_tests.monkey_island.conftest import get_url_for_resource +from tests.monkey_island import InMemoryCredentialsRepository from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials +ALL_CREDENTIALS_URL = PropagationCredentials.urls[0] +STOLEN_CREDENTIALS_URL = PropagationCredentials.urls[1] + @pytest.fixture -def flask_client(build_flask_client): +def credentials_repository(): + return InMemoryCredentialsRepository() + + +@pytest.fixture +def flask_client(build_flask_client, credentials_repository): container = StubDIContainer() - container.register(ICredentialsRepository, StubPropagationCredentialsRepository) + container.register_instance(ICredentialsRepository, credentials_repository) with build_flask_client(container) as flask_client: yield flask_client -def test_propagation_credentials_endpoint_get(flask_client): - propagation_credentials_url = get_url_for_resource(PropagationCredentials) +def test_propagation_credentials_endpoint_get(flask_client, credentials_repository): + credentials_repository.save_configured_credentials( + [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_3] + ) + credentials_repository.save_stolen_credentials( + [PROPAGATION_CREDENTIALS_2, PROPAGATION_CREDENTIALS_4] + ) - resp = flask_client.get(propagation_credentials_url) + resp = flask_client.get(ALL_CREDENTIALS_URL) actual_propagation_credentials = Credentials.from_json_array(resp.text) - assert resp.status_code == 200 + assert resp.status_code == HTTPStatus.OK + assert len(actual_propagation_credentials) == 4 + assert PROPAGATION_CREDENTIALS_1 in actual_propagation_credentials + assert PROPAGATION_CREDENTIALS_2 in actual_propagation_credentials + assert PROPAGATION_CREDENTIALS_3 in actual_propagation_credentials + assert PROPAGATION_CREDENTIALS_4 in actual_propagation_credentials + + +def test_propagation_credentials_endpoint__get_stolen(flask_client, credentials_repository): + credentials_repository.save_stolen_credentials( + [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] + ) + + resp = flask_client.get(STOLEN_CREDENTIALS_URL) + actual_propagation_credentials = Credentials.from_json_array(resp.text) + + assert resp.status_code == HTTPStatus.OK assert len(actual_propagation_credentials) == 2 assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 + + +def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials_repository): + credentials_repository.save_stolen_credentials([PROPAGATION_CREDENTIALS_1]) + + resp = flask_client.post( + STOLEN_CREDENTIALS_URL, + json=[ + Credentials.to_json(PROPAGATION_CREDENTIALS_2), + Credentials.to_json(PROPAGATION_CREDENTIALS_3), + ], + ) + assert resp.status_code == HTTPStatus.NO_CONTENT + + resp = flask_client.get(STOLEN_CREDENTIALS_URL) + retrieved_propagation_credentials = Credentials.from_json_array(resp.text) + + assert resp.status_code == HTTPStatus.OK + assert len(retrieved_propagation_credentials) == 3 + assert PROPAGATION_CREDENTIALS_1 in retrieved_propagation_credentials + assert PROPAGATION_CREDENTIALS_2 in retrieved_propagation_credentials + assert PROPAGATION_CREDENTIALS_3 in retrieved_propagation_credentials + + +def test_stolen_propagation_credentials_endpoint_delete(flask_client, credentials_repository): + credentials_repository.save_stolen_credentials( + [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] + ) + resp = flask_client.delete(STOLEN_CREDENTIALS_URL) + assert resp.status_code == HTTPStatus.NO_CONTENT + + resp = flask_client.get(STOLEN_CREDENTIALS_URL) + assert len(json.loads(resp.text)) == 0 + + +def test_propagation_credentials_endpoint__propagation_credentials_post_not_allowed(flask_client): + resp = flask_client.post(ALL_CREDENTIALS_URL, json=[]) + assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED + + +def test_propagation_credentials_endpoint__propagation_credentials_delete_not_allowed(flask_client): + resp = flask_client.delete(ALL_CREDENTIALS_URL) + assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py deleted file mode 100644 index 138849085..000000000 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_stolen_propagation_credentials.py +++ /dev/null @@ -1,43 +0,0 @@ -import json - -from tests.data_for_tests.propagation_credentials import ( - PROPAGATION_CREDENTIALS_1, - PROPAGATION_CREDENTIALS_2, -) -from tests.unit_tests.monkey_island.conftest import get_url_for_resource - -from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( - StolenPropagationCredentials, -) - - -def test_stolen_propagation_credentials_endpoint_get(flask_client): - stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) - - resp = flask_client.get(stolen_propagation_credentials_url) - - assert resp.status_code == 200 - actual_propagation_credentials = json.loads(resp.data) - assert len(actual_propagation_credentials) == 2 - - # TODO: delete the removal of monkey_guid key when the serialization of credentials - del actual_propagation_credentials[0]["monkey_guid"] - assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 - del actual_propagation_credentials[1]["monkey_guid"] - assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 - - -def test_stolen_propagation_credentials_endpoint_post(flask_client): - stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) - - resp = flask_client.post(stolen_propagation_credentials_url, json=PROPAGATION_CREDENTIALS_1) - - assert resp.status_code == 204 - - -def test_stolen_propagation_credentials_endpoint_delete(flask_client): - stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials) - - resp = flask_client.delete(stolen_propagation_credentials_url) - - assert resp.status_code == 204 From 7b1b9053e45b163efb57999db1e4dc57c81b2569 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:49:06 -0400 Subject: [PATCH 12/17] Island: Combine PropCredentials and ConfiguredPropagationCredentials --- monkey/monkey_island/cc/app.py | 4 -- .../configured_propagation_credentials.py | 28 ------------ .../credentials/propagation_credentials.py | 18 ++++++-- ...test_configured_propagation_credentials.py | 43 ------------------- .../test_propagation_credentials.py | 42 ++++++++++++------ 5 files changed, 42 insertions(+), 93 deletions(-) delete mode 100644 monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py delete mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 7d053fa25..590d86f18 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -28,9 +28,6 @@ from monkey_island.cc.resources.blackbox.monkey_blackbox_endpoint import MonkeyB from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import ( TelemetryBlackboxEndpoint, ) -from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( - ConfiguredPropagationCredentials, -) from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation @@ -188,7 +185,6 @@ def init_restful_endpoints(api: FlaskDIWrapper): api.add_resource(FileUpload) api.add_resource(PropagationCredentials) - api.add_resource(ConfiguredPropagationCredentials) api.add_resource(RemoteRun) api.add_resource(VersionUpdate) diff --git a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py deleted file mode 100644 index fcb6839b3..000000000 --- a/monkey/monkey_island/cc/resources/credentials/configured_propagation_credentials.py +++ /dev/null @@ -1,28 +0,0 @@ -import logging - -from flask import jsonify, request - -from common.credentials import Credentials -from monkey_island.cc.repository import ICredentialsRepository -from monkey_island.cc.resources.AbstractResource import AbstractResource - -logger = logging.getLogger(__name__) - - -class ConfiguredPropagationCredentials(AbstractResource): - urls = ["/api/propagation-credentials/configured"] - - def __init__(self, credentials_repository: ICredentialsRepository): - self._credentials_repository = credentials_repository - - def get(self): - return jsonify(self._credentials_repository.get_configured_credentials()) - - def post(self): - credentials = Credentials.from_mapping(request.json) - self._credentials_repository.save_configured_credentials(credentials) - return {}, 204 - - def delete(self): - self._credentials_repository.remove_configured_credentials() - return {}, 204 diff --git a/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py b/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py index 0c8b65988..e60478930 100644 --- a/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py @@ -8,7 +8,11 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource class PropagationCredentials(AbstractResource): - urls = ["/api/propagation-credentials", "/api/propagation-credentials/stolen-credentials"] + urls = [ + "/api/propagation-credentials", + "/api/propagation-credentials/configured-credentials", + "/api/propagation-credentials/stolen-credentials", + ] def __init__(self, credentials_repository: ICredentialsRepository): self._credentials_repository = credentials_repository @@ -16,7 +20,9 @@ class PropagationCredentials(AbstractResource): def get(self): propagation_credentials = [] - if request.url.endswith("/stolen-credentials"): + if request.url.endswith("/configured-credentials"): + propagation_credentials = self._credentials_repository.get_configured_credentials() + elif request.url.endswith("/stolen-credentials"): propagation_credentials = self._credentials_repository.get_stolen_credentials() else: propagation_credentials = self._credentials_repository.get_all_credentials() @@ -26,7 +32,9 @@ class PropagationCredentials(AbstractResource): def post(self): credentials = [Credentials.from_json(c) for c in request.json] - if request.url.endswith("/stolen-credentials"): + if request.url.endswith("/configured-credentials"): + self._credentials_repository.save_configured_credentials(credentials) + elif request.url.endswith("/stolen-credentials"): self._credentials_repository.save_stolen_credentials(credentials) else: return {}, HTTPStatus.METHOD_NOT_ALLOWED @@ -34,7 +42,9 @@ class PropagationCredentials(AbstractResource): return {}, HTTPStatus.NO_CONTENT def delete(self): - if request.url.endswith("/stolen-credentials"): + if request.url.endswith("/configured-credentials"): + self._credentials_repository.remove_configured_credentials() + elif request.url.endswith("/stolen-credentials"): self._credentials_repository.remove_stolen_credentials() else: return {}, HTTPStatus.METHOD_NOT_ALLOWED diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py deleted file mode 100644 index 5b4844fee..000000000 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_configured_propagation_credentials.py +++ /dev/null @@ -1,43 +0,0 @@ -import json - -from tests.data_for_tests.propagation_credentials import ( - PROPAGATION_CREDENTIALS_1, - PROPAGATION_CREDENTIALS_2, -) -from tests.unit_tests.monkey_island.conftest import get_url_for_resource - -from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( - ConfiguredPropagationCredentials, -) - - -def test_configured_propagation_credentials_endpoint_get(flask_client): - configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) - - resp = flask_client.get(configured_propagation_credentials_url) - - assert resp.status_code == 200 - actual_propagation_credentials = json.loads(resp.data) - assert len(actual_propagation_credentials) == 2 - - # TODO: delete the removal of monkey_guid key when the serialization of credentials - del actual_propagation_credentials[0]["monkey_guid"] - assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 - del actual_propagation_credentials[1]["monkey_guid"] - assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 - - -def test_configured_propagation_credentials_endpoint_post(flask_client): - configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) - - resp = flask_client.post(configured_propagation_credentials_url, json=PROPAGATION_CREDENTIALS_1) - - assert resp.status_code == 204 - - -def test_configured_propagation_credentials_endpoint_delete(flask_client): - configured_propagation_credentials_url = get_url_for_resource(ConfiguredPropagationCredentials) - - resp = flask_client.delete(configured_propagation_credentials_url) - - assert resp.status_code == 204 diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py index a6750b80d..cf70edcfc 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py @@ -1,5 +1,6 @@ import json from http import HTTPStatus +from typing import Sequence import pytest from tests.common import StubDIContainer @@ -16,7 +17,8 @@ from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials ALL_CREDENTIALS_URL = PropagationCredentials.urls[0] -STOLEN_CREDENTIALS_URL = PropagationCredentials.urls[1] +CONFIGURED_CREDENTIALS_URL = PropagationCredentials.urls[1] +STOLEN_CREDENTIALS_URL = PropagationCredentials.urls[2] @pytest.fixture @@ -53,12 +55,22 @@ def test_propagation_credentials_endpoint_get(flask_client, credentials_reposito assert PROPAGATION_CREDENTIALS_4 in actual_propagation_credentials -def test_propagation_credentials_endpoint__get_stolen(flask_client, credentials_repository): - credentials_repository.save_stolen_credentials( - [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] +def pre_populate_repository( + url: str, credentials_repository: ICredentialsRepository, credentials: Sequence[Credentials] +): + if "configured" in url: + credentials_repository.save_configured_credentials(credentials) + else: + credentials_repository.save_stolen_credentials(credentials) + + +@pytest.mark.parametrize("url", [CONFIGURED_CREDENTIALS_URL, STOLEN_CREDENTIALS_URL]) +def test_propagation_credentials_endpoint__get_stolen(flask_client, credentials_repository, url): + pre_populate_repository( + url, credentials_repository, [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] ) - resp = flask_client.get(STOLEN_CREDENTIALS_URL) + resp = flask_client.get(url) actual_propagation_credentials = Credentials.from_json_array(resp.text) assert resp.status_code == HTTPStatus.OK @@ -67,11 +79,12 @@ def test_propagation_credentials_endpoint__get_stolen(flask_client, credentials_ assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 -def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials_repository): - credentials_repository.save_stolen_credentials([PROPAGATION_CREDENTIALS_1]) +@pytest.mark.parametrize("url", [CONFIGURED_CREDENTIALS_URL, STOLEN_CREDENTIALS_URL]) +def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials_repository, url): + pre_populate_repository(url, credentials_repository, [PROPAGATION_CREDENTIALS_1]) resp = flask_client.post( - STOLEN_CREDENTIALS_URL, + url, json=[ Credentials.to_json(PROPAGATION_CREDENTIALS_2), Credentials.to_json(PROPAGATION_CREDENTIALS_3), @@ -79,7 +92,7 @@ def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials ) assert resp.status_code == HTTPStatus.NO_CONTENT - resp = flask_client.get(STOLEN_CREDENTIALS_URL) + resp = flask_client.get(url) retrieved_propagation_credentials = Credentials.from_json_array(resp.text) assert resp.status_code == HTTPStatus.OK @@ -89,14 +102,15 @@ def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials assert PROPAGATION_CREDENTIALS_3 in retrieved_propagation_credentials -def test_stolen_propagation_credentials_endpoint_delete(flask_client, credentials_repository): - credentials_repository.save_stolen_credentials( - [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] +@pytest.mark.parametrize("url", [CONFIGURED_CREDENTIALS_URL, STOLEN_CREDENTIALS_URL]) +def test_stolen_propagation_credentials_endpoint_delete(flask_client, credentials_repository, url): + pre_populate_repository( + url, credentials_repository, [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] ) - resp = flask_client.delete(STOLEN_CREDENTIALS_URL) + resp = flask_client.delete(url) assert resp.status_code == HTTPStatus.NO_CONTENT - resp = flask_client.get(STOLEN_CREDENTIALS_URL) + resp = flask_client.get(url) assert len(json.loads(resp.text)) == 0 From db74ea013dfe8513d13c72d150af12d19d7505e9 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:51:20 -0400 Subject: [PATCH 13/17] Island: Remove unnecessary resources/credentials subpackage --- monkey/monkey_island/cc/app.py | 3 +-- monkey/monkey_island/cc/resources/__init__.py | 1 + .../cc/resources/credentials/__init__.py | 0 .../{credentials => }/propagation_credentials.py | 0 .../cc/resources/credentials/__init__.py | 0 .../cc/resources/credentials/conftest.py | 15 --------------- .../test_propagation_credentials.py | 2 +- 7 files changed, 3 insertions(+), 18 deletions(-) delete mode 100644 monkey/monkey_island/cc/resources/credentials/__init__.py rename monkey/monkey_island/cc/resources/{credentials => }/propagation_credentials.py (100%) delete mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py delete mode 100644 monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py rename monkey/tests/unit_tests/monkey_island/cc/resources/{credentials => }/test_propagation_credentials.py (97%) diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 590d86f18..52b6bd30b 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -13,6 +13,7 @@ from monkey_island.cc.database import database, mongo from monkey_island.cc.resources import ( AgentBinaries, ClearSimulationData, + PropagationCredentials, RemoteRun, ResetAgentConfiguration, ) @@ -28,7 +29,6 @@ from monkey_island.cc.resources.blackbox.monkey_blackbox_endpoint import MonkeyB from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import ( TelemetryBlackboxEndpoint, ) -from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation @@ -185,7 +185,6 @@ def init_restful_endpoints(api: FlaskDIWrapper): api.add_resource(FileUpload) api.add_resource(PropagationCredentials) - api.add_resource(RemoteRun) api.add_resource(VersionUpdate) api.add_resource(StopAgentCheck) diff --git a/monkey/monkey_island/cc/resources/__init__.py b/monkey/monkey_island/cc/resources/__init__.py index 7f0385c32..bd0ed0d18 100644 --- a/monkey/monkey_island/cc/resources/__init__.py +++ b/monkey/monkey_island/cc/resources/__init__.py @@ -2,3 +2,4 @@ from .remote_run import RemoteRun from .agent_binaries import AgentBinaries from .clear_simulation_data import ClearSimulationData from .reset_agent_configuration import ResetAgentConfiguration +from .propagation_credentials import PropagationCredentials diff --git a/monkey/monkey_island/cc/resources/credentials/__init__.py b/monkey/monkey_island/cc/resources/credentials/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monkey/monkey_island/cc/resources/credentials/propagation_credentials.py b/monkey/monkey_island/cc/resources/propagation_credentials.py similarity index 100% rename from monkey/monkey_island/cc/resources/credentials/propagation_credentials.py rename to monkey/monkey_island/cc/resources/propagation_credentials.py diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py b/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py deleted file mode 100644 index ab1bee2af..000000000 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/conftest.py +++ /dev/null @@ -1,15 +0,0 @@ -import pytest -from tests.common import StubDIContainer -from tests.monkey_island import StubPropagationCredentialsRepository - -from monkey_island.cc.repository import ICredentialsRepository - - -@pytest.fixture -def flask_client(build_flask_client): - container = StubDIContainer() - - container.register(ICredentialsRepository, StubPropagationCredentialsRepository) - - with build_flask_client(container) as flask_client: - yield flask_client diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py similarity index 97% rename from monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py rename to monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py index cf70edcfc..d34a45a25 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/credentials/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py @@ -14,7 +14,7 @@ from tests.monkey_island import InMemoryCredentialsRepository from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository -from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials +from monkey_island.cc.resources import PropagationCredentials ALL_CREDENTIALS_URL = PropagationCredentials.urls[0] CONFIGURED_CREDENTIALS_URL = PropagationCredentials.urls[1] From 037e6619dd38fad49fe152d4c9acfe55c7661be6 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 11 Jul 2022 14:57:16 -0400 Subject: [PATCH 14/17] UT: Remove disused StubPropagationCredentialsRepository --- monkey/tests/monkey_island/__init__.py | 1 - ...stub_propagation_credentials_repository.py | 36 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 monkey/tests/monkey_island/stub_propagation_credentials_repository.py diff --git a/monkey/tests/monkey_island/__init__.py b/monkey/tests/monkey_island/__init__.py index 8bf003b21..f7033842d 100644 --- a/monkey/tests/monkey_island/__init__.py +++ b/monkey/tests/monkey_island/__init__.py @@ -3,5 +3,4 @@ from .mock_file_repository import MockFileRepository, FILE_CONTENTS, FILE_NAME from .open_error_file_repository import OpenErrorFileRepository from .in_memory_agent_configuration_repository import InMemoryAgentConfigurationRepository from .in_memory_simulation_configuration import InMemorySimulationRepository -from .stub_propagation_credentials_repository import StubPropagationCredentialsRepository from .in_memory_credentials_repository import InMemoryCredentialsRepository diff --git a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py b/monkey/tests/monkey_island/stub_propagation_credentials_repository.py deleted file mode 100644 index 51c8964b2..000000000 --- a/monkey/tests/monkey_island/stub_propagation_credentials_repository.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import Sequence - -from tests.data_for_tests.propagation_credentials import ( - PROPAGATION_CREDENTIALS_1, - PROPAGATION_CREDENTIALS_2, -) - -from common.credentials import Credentials -from monkey_island.cc.repository import ICredentialsRepository - - -class StubPropagationCredentialsRepository(ICredentialsRepository): - def get_configured_credentials(self) -> Sequence[Credentials]: - pass - - def get_stolen_credentials(self) -> Sequence[Credentials]: - return [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] - - def get_all_credentials(self) -> Sequence[Credentials]: - - return [PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2] - - def save_configured_credentials(self, credentials: Sequence[Credentials]): - pass - - def save_stolen_credentials(self, credentials: Sequence[Credentials]): - pass - - def remove_configured_credentials(self): - pass - - def remove_stolen_credentials(self): - pass - - def remove_all_credentials(self): - pass From a9e2dd2d3deca3e8e7068a3354bbd8db121d09c2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 12 Jul 2022 12:39:16 +0300 Subject: [PATCH 15/17] Island: Use collection url placeholder for propagation credentials --- .../cc/resources/propagation_credentials.py | 31 +++++++++---------- .../resources/test_propagation_credentials.py | 14 ++++----- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/monkey/monkey_island/cc/resources/propagation_credentials.py b/monkey/monkey_island/cc/resources/propagation_credentials.py index e60478930..97e8ecc3c 100644 --- a/monkey/monkey_island/cc/resources/propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/propagation_credentials.py @@ -6,47 +6,44 @@ from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.resources.AbstractResource import AbstractResource +_configured_collection = "configured-credentials" +_stolen_collection = "stolen-credentials" + class PropagationCredentials(AbstractResource): - urls = [ - "/api/propagation-credentials", - "/api/propagation-credentials/configured-credentials", - "/api/propagation-credentials/stolen-credentials", - ] + urls = ["/api/propagation-credentials/", "/api/propagation-credentials/"] def __init__(self, credentials_repository: ICredentialsRepository): self._credentials_repository = credentials_repository - def get(self): - propagation_credentials = [] - - if request.url.endswith("/configured-credentials"): + def get(self, collection=None): + if collection == _configured_collection: propagation_credentials = self._credentials_repository.get_configured_credentials() - elif request.url.endswith("/stolen-credentials"): + elif collection == _stolen_collection: propagation_credentials = self._credentials_repository.get_stolen_credentials() else: propagation_credentials = self._credentials_repository.get_all_credentials() return make_response(Credentials.to_json_array(propagation_credentials), HTTPStatus.OK) - def post(self): + def post(self, collection=None): credentials = [Credentials.from_json(c) for c in request.json] - if request.url.endswith("/configured-credentials"): + if collection == _configured_collection: self._credentials_repository.save_configured_credentials(credentials) - elif request.url.endswith("/stolen-credentials"): + elif collection == _stolen_collection: self._credentials_repository.save_stolen_credentials(credentials) else: return {}, HTTPStatus.METHOD_NOT_ALLOWED return {}, HTTPStatus.NO_CONTENT - def delete(self): - if request.url.endswith("/configured-credentials"): + def delete(self, collection=None): + if collection == _configured_collection: self._credentials_repository.remove_configured_credentials() - elif request.url.endswith("/stolen-credentials"): + elif collection == _stolen_collection: self._credentials_repository.remove_stolen_credentials() else: - return {}, HTTPStatus.METHOD_NOT_ALLOWED + self._credentials_repository.remove_all_credentials() return {}, HTTPStatus.NO_CONTENT diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py index d34a45a25..f717fd032 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py @@ -1,6 +1,7 @@ import json from http import HTTPStatus from typing import Sequence +from urllib.parse import urljoin import pytest from tests.common import StubDIContainer @@ -15,10 +16,14 @@ from tests.monkey_island import InMemoryCredentialsRepository from common.credentials import Credentials from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.resources import PropagationCredentials +from monkey_island.cc.resources.propagation_credentials import ( + _configured_collection, + _stolen_collection, +) ALL_CREDENTIALS_URL = PropagationCredentials.urls[0] -CONFIGURED_CREDENTIALS_URL = PropagationCredentials.urls[1] -STOLEN_CREDENTIALS_URL = PropagationCredentials.urls[2] +CONFIGURED_CREDENTIALS_URL = urljoin(ALL_CREDENTIALS_URL, _configured_collection) +STOLEN_CREDENTIALS_URL = urljoin(ALL_CREDENTIALS_URL, _stolen_collection) @pytest.fixture @@ -117,8 +122,3 @@ def test_stolen_propagation_credentials_endpoint_delete(flask_client, credential def test_propagation_credentials_endpoint__propagation_credentials_post_not_allowed(flask_client): resp = flask_client.post(ALL_CREDENTIALS_URL, json=[]) assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED - - -def test_propagation_credentials_endpoint__propagation_credentials_delete_not_allowed(flask_client): - resp = flask_client.delete(ALL_CREDENTIALS_URL) - assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED From bcd94773a0aa6f5bca818f568269f35eeabbb8e8 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 12 Jul 2022 13:33:37 +0300 Subject: [PATCH 16/17] Island: Add a check for unimplemented credential collections --- .../cc/resources/propagation_credentials.py | 12 +++++++++--- .../resources/test_propagation_credentials.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/resources/propagation_credentials.py b/monkey/monkey_island/cc/resources/propagation_credentials.py index 97e8ecc3c..9fb59ad0e 100644 --- a/monkey/monkey_island/cc/resources/propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/propagation_credentials.py @@ -21,8 +21,10 @@ class PropagationCredentials(AbstractResource): propagation_credentials = self._credentials_repository.get_configured_credentials() elif collection == _stolen_collection: propagation_credentials = self._credentials_repository.get_stolen_credentials() - else: + elif collection is None: propagation_credentials = self._credentials_repository.get_all_credentials() + else: + return {}, HTTPStatus.NOT_FOUND return make_response(Credentials.to_json_array(propagation_credentials), HTTPStatus.OK) @@ -33,8 +35,10 @@ class PropagationCredentials(AbstractResource): self._credentials_repository.save_configured_credentials(credentials) elif collection == _stolen_collection: self._credentials_repository.save_stolen_credentials(credentials) - else: + elif collection is None: return {}, HTTPStatus.METHOD_NOT_ALLOWED + else: + return {}, HTTPStatus.NOT_FOUND return {}, HTTPStatus.NO_CONTENT @@ -43,7 +47,9 @@ class PropagationCredentials(AbstractResource): self._credentials_repository.remove_configured_credentials() elif collection == _stolen_collection: self._credentials_repository.remove_stolen_credentials() - else: + elif collection is None: self._credentials_repository.remove_all_credentials() + else: + return {}, HTTPStatus.NOT_FOUND return {}, HTTPStatus.NO_CONTENT diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py index f717fd032..ee78e7a72 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py @@ -122,3 +122,22 @@ def test_stolen_propagation_credentials_endpoint_delete(flask_client, credential def test_propagation_credentials_endpoint__propagation_credentials_post_not_allowed(flask_client): resp = flask_client.post(ALL_CREDENTIALS_URL, json=[]) assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED + + +def test_propagation_credentials_endpoint__not_found(flask_client): + non_existent_collection_url = urljoin(ALL_CREDENTIALS_URL, "bogus-credentials") + + resp = flask_client.get(non_existent_collection_url) + assert resp.status_code == HTTPStatus.NOT_FOUND + + resp = flask_client.post( + non_existent_collection_url, + json=[ + Credentials.to_json(PROPAGATION_CREDENTIALS_2), + Credentials.to_json(PROPAGATION_CREDENTIALS_3), + ], + ) + assert resp.status_code == HTTPStatus.NOT_FOUND + + resp = flask_client.delete(non_existent_collection_url) + assert resp.status_code == HTTPStatus.NOT_FOUND From d2e4fe613611bab046d1eddd8b031d114dbc3f73 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 12 Jul 2022 06:44:16 -0400 Subject: [PATCH 17/17] UT: Break up large unit test into smaller tests --- .../cc/resources/test_propagation_credentials.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py index ee78e7a72..111ad7e30 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py +++ b/monkey/tests/unit_tests/monkey_island/cc/resources/test_propagation_credentials.py @@ -124,14 +124,17 @@ def test_propagation_credentials_endpoint__propagation_credentials_post_not_allo assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED -def test_propagation_credentials_endpoint__not_found(flask_client): - non_existent_collection_url = urljoin(ALL_CREDENTIALS_URL, "bogus-credentials") +NON_EXISTENT_COLLECTION_URL = urljoin(ALL_CREDENTIALS_URL, "bogus-credentials") - resp = flask_client.get(non_existent_collection_url) + +def test_propagation_credentials_endpoint__get_not_found(flask_client): + resp = flask_client.get(NON_EXISTENT_COLLECTION_URL) assert resp.status_code == HTTPStatus.NOT_FOUND + +def test_propagation_credentials_endpoint__post_not_found(flask_client): resp = flask_client.post( - non_existent_collection_url, + NON_EXISTENT_COLLECTION_URL, json=[ Credentials.to_json(PROPAGATION_CREDENTIALS_2), Credentials.to_json(PROPAGATION_CREDENTIALS_3), @@ -139,5 +142,7 @@ def test_propagation_credentials_endpoint__not_found(flask_client): ) assert resp.status_code == HTTPStatus.NOT_FOUND - resp = flask_client.delete(non_existent_collection_url) + +def test_propagation_credentials_endpoint__delete_not_found(flask_client): + resp = flask_client.delete(NON_EXISTENT_COLLECTION_URL) assert resp.status_code == HTTPStatus.NOT_FOUND