diff --git a/.github/workflows/python-csle-rest-api-build.yml b/.github/workflows/python-csle-rest-api-build.yml new file mode 100644 index 000000000..22fde86a7 --- /dev/null +++ b/.github/workflows/python-csle-rest-api-build.yml @@ -0,0 +1,35 @@ +name: python-csle-rest-api-build +run-name: ${{ github.actor }} python-csle-rest-api-build +on: + push: + branches: + - "master" +# pull_request: +# branches: +# - "master" + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: ['3.9'] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install python build dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + - name: Tox tests csle-rest-api + run: cd simulation-system/libs/csle-rest-api; tox + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + files: simulation-system/libs/csle-rest-api/coverage.yml \ No newline at end of file diff --git a/README.md b/README.md index 291201ef0..97dd322b0 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,10 @@ features. We currently support each release for a window of 6 months.

+## Datasets + +A dataset of 6400 intrusion traces can be found [here](https://zenodo.org/records/10234379). + ## Maintainer @@ -168,6 +172,7 @@ Thanks go to these people! +
Yan Wang
Yan Wang
Aws Jaber
Aws Jaber
diff --git a/docs/_docs/contributing.md b/docs/_docs/contributing.md index 2ecef8c9e..b8c599bb5 100644 --- a/docs/_docs/contributing.md +++ b/docs/_docs/contributing.md @@ -36,4 +36,5 @@ should be on the list but is not): - Nils Forsgren, software development. - Bength Roland Pappila, software development. - Yu Hu, software development. -- Yan Wang, software development. \ No newline at end of file +- Yan Wang, software development. +- Aws Jaber, software development. \ No newline at end of file diff --git a/examples/eval/cyborg_scenario_two/eval_on_base_env.py b/examples/eval/cyborg_scenario_two/eval_on_base_env.py index 68a6151bc..754683087 100644 --- a/examples/eval/cyborg_scenario_two/eval_on_base_env.py +++ b/examples/eval/cyborg_scenario_two/eval_on_base_env.py @@ -13,22 +13,29 @@ maximum_steps=100, red_agent_distribution=[1.0], reduced_action_space=True, decoy_state=True, scanned_state=True, decoy_optimization=False, cache_visited_states=False) csle_cyborg_env = CyborgScenarioTwoDefender(config=config) - num_evaluations = 10000 - max_horizon = 100 + num_evaluations = 1 + max_horizon = 20 returns = [] seed = 215125 random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) - print("Starting policy evaluation") + # print(csle_cyborg_env.action_id_to_type_and_host) + # import sys + # sys.exit(0) + # print("Starting policy evaluation") for i in range(num_evaluations): o, _ = csle_cyborg_env.reset() R = 0 t = 0 while t < max_horizon: - a = ppo_policy.action(o=o) + # a = ppo_policy.action(o=o) + a = 4 o, r, done, _, info = csle_cyborg_env.step(a) + table = csle_cyborg_env.get_true_table() + print(table) + print(r) R += r t += 1 returns.append(R) - print(f"{i}/{num_evaluations}, avg R: {np.mean(returns)}, R: {R}") + # print(f"{i}/{num_evaluations}, avg R: {np.mean(returns)}, R: {R}") diff --git a/examples/eval/cyborg_scenario_two/evaluate_on_wrapper_env.py b/examples/eval/cyborg_scenario_two/evaluate_on_wrapper_env.py index 85895544b..da39cea81 100644 --- a/examples/eval/cyborg_scenario_two/evaluate_on_wrapper_env.py +++ b/examples/eval/cyborg_scenario_two/evaluate_on_wrapper_env.py @@ -3,12 +3,14 @@ import random from csle_common.metastore.metastore_facade import MetastoreFacade from gym_csle_cyborg.envs.cyborg_scenario_two_wrapper import CyborgScenarioTwoWrapper +from gym_csle_cyborg.dao.red_agent_type import RedAgentType from gym_csle_cyborg.dao.csle_cyborg_wrapper_config import CSLECyborgWrapperConfig if __name__ == '__main__': ppo_policy = MetastoreFacade.get_ppo_policy(id=58) config = CSLECyborgWrapperConfig(maximum_steps=100, gym_env_name="", - save_trace=False, reward_shaping=False, scenario=2) + save_trace=False, reward_shaping=False, scenario=2, + red_agent_type=RedAgentType.B_LINE_AGENT) env = CyborgScenarioTwoWrapper(config=config) num_evaluations = 10000 max_horizon = 100 @@ -25,6 +27,7 @@ while t < max_horizon: a = ppo_policy.action(o=o) o, r, done, _, info = env.step(a) + env.show R += r t += 1 returns.append(R) diff --git a/management-system/csle-mgmt-webapp/package.json b/management-system/csle-mgmt-webapp/package.json index abf8324ac..2f3425b3b 100644 --- a/management-system/csle-mgmt-webapp/package.json +++ b/management-system/csle-mgmt-webapp/package.json @@ -62,6 +62,7 @@ "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@testing-library/react": "^14.0.0", + "ajv": "^7.2.4", "eslint": "^8.28.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard": "^17.0.0", diff --git a/simulation-system/libs/csle-common/tests/test_cluster_util.py b/simulation-system/libs/csle-common/tests/test_cluster_util.py new file mode 100644 index 000000000..1d400a66f --- /dev/null +++ b/simulation-system/libs/csle-common/tests/test_cluster_util.py @@ -0,0 +1,140 @@ +import os +from unittest.mock import patch, MagicMock +import csle_common.constants.constants as constants +from csle_common.util.cluster_util import ClusterUtil + + +class TestClusterUtilSuite: + """ + Test suite for cluster util + """ + + def test_am_i_leader(self) -> None: + """ + Test function that checks if a given IP is a leader or not + """ + config = MagicMock() + config.cluster_config.cluster_nodes.ip = "192.168.1.1" + config.cluster_config.cluster_nodes.leader = False + config.cluster_config.cluster_nodes.cpus = 1 + config.cluster_config.cluster_nodes.gpus = 2 + config.cluster_config.cluster_nodes.RAM = 8 + assert not ClusterUtil.am_i_leader("192.168.1.1", config) + + @patch("psycopg.connect") + @patch("csle_common.util.cluster_util.ClusterUtil.get_config") + @patch.dict(os.environ, {"CSLE_HOME": "/mock/csle/home"}) + def test_get_config(self, mock_get_config, mock_connect) -> None: + """ + Test function that gets the current cluster config from the metastore or from disk + depending on if it is the leader node or not + + :param mock_get_config: mock_get_config + :param mock_connect: mock_connect + + :return: None + """ + mock_config = MagicMock() + mock_get_config.return_value = mock_config + from csle_common.util.cluster_util import ClusterUtil + + result = ClusterUtil.get_config() + assert result == mock_config + + @patch.dict(os.environ, {"CSLE_HOME": "/mock/csle/home"}) + @patch("csle_common.util.cluster_util.ClusterUtil.get_config") + def test_set_config_parameters_from_config_file(self, mock_get_config) -> None: + """ + Test function that reads the config file from $CSLE_HOME/config.json and initializes certain config parameters + + :param mock_get_config: mock_get_config + + :return: None + """ + mock_config = MagicMock() + mock_config.management_admin_username_default = "admin" + mock_config.management_admin_password_default = "admin_pw" + mock_config.management_admin_email_default = "admin@example.com" + mock_config.management_admin_organization_default = "Example Org" + mock_config.management_admin_first_name_default = "Admin" + mock_config.management_admin_last_name_default = "User" + mock_config.ssh_admin_username = "ssh_admin" + mock_config.ssh_admin_password = "ssh_pw" + mock_config.management_guest_username_default = "guest" + mock_config.management_guest_password_default = "guest_pw" + mock_config.management_guest_email_default = "guest@example.com" + mock_config.management_guest_organization_default = "Example Org" + mock_config.management_guest_first_name_default = "Guest" + mock_config.management_guest_last_name_default = "User" + mock_config.ssh_agent_username = "agent" + mock_config.ssh_agent_password = "agent_pw" + mock_config.metastore_user = "metastore_user" + mock_config.metastore_password = "metastore_pw" + mock_config.metastore_database_name = "metastore_db" + mock_config.pgadmin_username = "pgadmin" + mock_config.pgadmin_password = "pgadmin_pw" + mock_config.grafana_username = "grafana" + mock_config.grafana_password = "grafana_pw" + mock_config.node_exporter_port = 9100 + mock_config.grafana_port = 3000 + mock_config.management_system_port = 8000 + mock_config.cadvisor_port = 8080 + mock_config.pgadmin_port = 5050 + mock_config.prometheus_port = 9090 + mock_config.node_exporter_pid_file = "/var/run/node_exporter.pid" + mock_config.csle_mgmt_webapp_pid_file = "/var/run/csle_mgmt_webapp.pid" + mock_config.node_exporter_log_file = "/var/log/node_exporter.log" + mock_config.docker_stats_manager_outfile = "/var/log/docker_stats.out" + mock_config.docker_stats_manager_pidfile = "/var/run/docker_stats.pid" + mock_config.prometheus_pid_file = "/var/run/prometheus.pid" + mock_config.prometheus_log_file = "/var/log/prometheus.log" + mock_config.postgresql_log_dir = "/var/log/postgresql" + mock_config.nginx_log_dir = "/var/log/nginx" + mock_config.flask_log_file = "/var/log/flask.log" + mock_config.default_log_dir = "/var/log" + + mock_get_config.return_value = mock_config + + ClusterUtil.set_config_parameters_from_config_file() + + assert constants.CONFIG_FILE.PARSED_CONFIG == mock_config + assert constants.CSLE_ADMIN.MANAGEMENT_USER == "admin" + assert constants.CSLE_ADMIN.MANAGEMENT_PW == "admin_pw" + assert constants.CSLE_ADMIN.MANAGEMENT_EMAIL == "admin@example.com" + assert constants.CSLE_ADMIN.MANAGEMENT_ORGANIZATION == "Example Org" + assert constants.CSLE_ADMIN.MANAGEMENT_FIRST_NAME == "Admin" + assert constants.CSLE_ADMIN.MANAGEMENT_LAST_NAME == "User" + assert constants.CSLE_ADMIN.SSH_USER == "ssh_admin" + assert constants.CSLE_ADMIN.SSH_PW == "ssh_pw" + assert constants.CSLE_GUEST.MANAGEMENT_USER == "guest" + assert constants.CSLE_GUEST.MANAGEMENT_PW == "guest_pw" + assert constants.CSLE_GUEST.MANAGEMENT_EMAIL == "guest@example.com" + assert constants.CSLE_GUEST.MANAGEMENT_ORGANIZATION == "Example Org" + assert constants.CSLE_GUEST.MANAGEMENT_FIRST_NAME == "Guest" + assert constants.CSLE_GUEST.MANAGEMENT_LAST_NAME == "User" + assert constants.AGENT.USER == "agent" + assert constants.AGENT.PW == "agent_pw" + assert constants.METADATA_STORE.USER == "metastore_user" + assert constants.METADATA_STORE.PASSWORD == "metastore_pw" + assert constants.METADATA_STORE.DBNAME == "metastore_db" + assert constants.COMMANDS.PGADMIN_USERNAME == "pgadmin" + assert constants.COMMANDS.PGADMIN_PW == "pgadmin_pw" + assert constants.COMMANDS.GRAFANA_USERNAME == "grafana" + assert constants.COMMANDS.GRAFANA_PW == "grafana_pw" + assert constants.COMMANDS.NODE_EXPORTER_PORT == 9100 + assert constants.COMMANDS.GRAFANA_PORT == 3000 + assert constants.COMMANDS.MANAGEMENT_SYSTEM_PORT == 8000 + assert constants.COMMANDS.CADVISOR_PORT == 8080 + assert constants.COMMANDS.PGADMIN_PORT == 5050 + assert constants.COMMANDS.PROMETHEUS_PORT == 9090 + assert constants.COMMANDS.NODE_EXPORTER_PID_FILE == "/var/run/node_exporter.pid" + assert constants.COMMANDS.CSLE_MGMT_WEBAPP_PID_FILE == "/var/run/csle_mgmt_webapp.pid" + assert constants.COMMANDS.NODE_EXPORTER_LOG_FILE == "/var/log/node_exporter.log" + assert constants.COMMANDS.DOCKER_STATS_MANAGER_OUTFILE == "/var/log/docker_stats.out" + assert constants.COMMANDS.DOCKER_STATS_MANAGER_PIDFILE == "/var/run/docker_stats.pid" + assert constants.COMMANDS.PROMETHEUS_PID_FILE == "/var/run/prometheus.pid" + assert constants.COMMANDS.PROMETHEUS_LOG_FILE == "/var/log/prometheus.log" + assert constants.COMMANDS.POSTGRESQL_LOG_DIR == "/var/log/postgresql" + assert constants.COMMANDS.NGINX_LOG_DIR == "/var/log/nginx" + assert constants.COMMANDS.FLASK_LOG_FILE == "/var/log/flask.log" + assert constants.LOGGING.DEFAULT_LOG_DIR == "/var/log" diff --git a/simulation-system/libs/csle-common/tests/test_docker_util.py b/simulation-system/libs/csle-common/tests/test_docker_util.py new file mode 100644 index 000000000..1983170b5 --- /dev/null +++ b/simulation-system/libs/csle-common/tests/test_docker_util.py @@ -0,0 +1,209 @@ +from unittest.mock import patch, MagicMock +from csle_common.util.docker_util import DockerUtil +import csle_common.constants.constants as constants +import json + + +class TestDockerUtilSuite: + """ + Test suite for docker util + """ + + @patch("docker.from_env") + @patch("docker.APIClient") + @patch("csle_common.util.docker_util.DockerUtil.parse_running_containers") + @patch("csle_common.util.docker_util.DockerUtil.parse_running_emulation_envs") + def test_parse_running_emulation_infos( + self, mock_parse_running_emulation_envs, mock_parse_running_containers, mock_APIClient, mock_from_env + ) -> None: + """ + Test method that queries docker to get a list of all running emulation environments + + :param mock_parse_running_emulation_envs: mock_parse_running_emulation_envs + :param mock_parse_running_containers: mock_parse_running_containers + :param mock_APIClient: mock_APIClient + :param mock_from_env: mock_from_env + + :return: None + """ + mock_client_1 = MagicMock() + mock_client_2 = MagicMock() + mock_from_env.return_value = mock_client_1 + mock_APIClient.return_value = mock_client_2 + mock_parsed_containers = [MagicMock()] + mock_parse_running_containers.return_value = mock_parsed_containers + mock_parsed_envs = [MagicMock()] + mock_parse_running_emulation_envs.return_value = mock_parsed_envs + result = DockerUtil.parse_runnning_emulation_infos() + mock_from_env.assert_called() + mock_APIClient.assert_called() + mock_parse_running_containers.assert_called() + mock_parse_running_emulation_envs.assert_called() + assert result == mock_parsed_envs + + @patch("docker.from_env") + @patch("docker.APIClient") + @patch("csle_common.util.docker_util.DockerUtil.parse_running_containers") + def test_get_container_hex_id(self, mock_parse_running_containers, mock_APIClient, mock_from_env) -> None: + """ + Test method that queries the docker engine for the id of a container with a given name + + :param mock_parse_running_containers: mock_parse_running_containers + :param mock_APIClient: mock_APIClient + :param mock_from_env: mock_from_env + + :return: None + """ + mock_client_1 = MagicMock() + mock_client_2 = MagicMock() + mock_from_env.return_value = mock_client_1 + mock_APIClient.return_value = mock_client_2 + container_1 = MagicMock() + container_1.name = "container_1" + container_1.id = "1" + container_2 = MagicMock() + container_2.name = "container_2" + container_2.id = "2" + mock_parse_running_containers.return_value = [container_1, container_2] + result = DockerUtil.get_container_hex_id("container_1") + assert result == "1" + + @patch("csle_common.util.docker_util.DockerUtil.parse_containers") + def test_parse_running_container(self, mock_parse_containers) -> None: + """ + Test method that queries docker to get a list of all running containers + + :param mock_parse_containers: mock_parse_containers + + :return: None + """ + mock_client_1 = MagicMock() + mock_client_2 = MagicMock() + container_1 = MagicMock() + container_2 = MagicMock() + mock_client_1.containers.list.return_value = [container_1, container_2] + mock_parsed_container_1 = MagicMock() + mock_parsed_container_2 = MagicMock() + mock_parse_containers.return_value = [mock_parsed_container_1, mock_parsed_container_2] + result = DockerUtil.parse_running_containers(client_1=mock_client_1, client_2=mock_client_2) + mock_client_1.containers.list.assert_called() + mock_parse_containers.assert_called() + assert result == [mock_parsed_container_1, mock_parsed_container_2] + + @patch("csle_common.util.docker_util.DockerUtil.parse_containers") + def test_parse_stopped_container(self, mock_parse_containers) -> None: + """ + Test method that queries docker to get a list of all stopped csle containers + + :param mock_parse_containers: mock_parse_containers + + :return: None + """ + mock_client_1 = MagicMock() + mock_client_2 = MagicMock() + container_1 = MagicMock() + container_1.status = constants.DOCKER.CONTAINER_EXIT_STATUS + container_2 = MagicMock() + container_2.status = constants.DOCKER.CONTAINER_CREATED_STATUS + mock_client_1.containers.list.return_value = [container_1, container_2] + mock_parsed_container_1 = MagicMock() + mock_parsed_container_2 = MagicMock() + mock_parse_containers.return_value = [mock_parsed_container_1, mock_parsed_container_2] + result = DockerUtil.parse_stopped_containers(client_1=mock_client_1, client2=mock_client_2) + mock_client_1.containers.list.assert_called() + mock_parse_containers.assert_called() + assert result == [mock_parsed_container_1, mock_parsed_container_2] + + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_by_name") + def test_parse_running_emulation_envs(self, mock_get_emulation_by_name) -> None: + """ + Test method that queries docker to get a list of all active emulation environments + + :param mock_get_emulation_by_name: mock_get_emulation_by_name + + :return: None + """ + container_1 = MagicMock() + container_1.emulation = "emulation1" + container_1.ip = "192.168.1.2" + container_1.ip_prefix_len = 24 + container_1.level = "level1" + + container_2 = MagicMock() + container_2.emulation = "emulation1" + container_2.ip = "192.168.1.3" + container_2.ip_prefix_len = 24 + container_2.level = "level1" + + containers = [container_1, container_2] + emulations = ["emulation1"] + + mock_em_record = MagicMock() + mock_get_emulation_by_name.return_value = mock_em_record + + result = DockerUtil.parse_running_emulation_envs(emulations=emulations, containers=containers) + mock_get_emulation_by_name.assert_called() + assert result + + @patch("docker.APIClient.inspect_container") + def test_parse_containers(self, mock_inspect_container) -> None: + """ + Test method that queries docker to get a list of running or stopped csle containers + + :param mock_inspect_container: mock_inspect_container + + :return: None + """ + mock_client2 = MagicMock() + mock_inspect_info = { + constants.DOCKER.NETWORK_SETTINGS: { + constants.DOCKER.NETWORKS: { + "net": { + constants.DOCKER.IP_ADDRESS_INFO: "192.168.1.2", + constants.DOCKER.NETWORK_ID_INFO: "network_1", + constants.DOCKER.GATEWAY_INFO: "192.168.1.1", + constants.DOCKER.MAC_ADDRESS_INFO: "02:42:ac:11:00:02", + constants.DOCKER.IP_PREFIX_LEN_INFO: 24, + } + } + }, + constants.DOCKER.CREATED_INFO: "2021-01-01T00:00:00Z", + constants.DOCKER.CONFIG: {constants.DOCKER.HOSTNAME_INFO: "container_1", constants.DOCKER.IMAGE: "image_1"}, + } + mock_inspect_container.return_value = mock_inspect_info + + container_1 = MagicMock() + container_1.name = "csle_container_1-level1-1" + container_1.status = "running" + container_1.short_id = "1" + container_1.image.short_id = "image1" + container_1.image.tags = ["latest"] + container_1.id = "container_id_1" + container_1.labels = { + constants.DOCKER.CFG: "/path/to/config", + constants.DOCKER.CONTAINER_CONFIG_DIR: "/path/to/dir", + constants.DOCKER.EMULATION: "emulation_1", + constants.DOCKER.KAFKA_CONFIG: "kafka_config_1", + } + containers = [container_1] + result = DockerUtil.parse_containers(containers=containers, client2=mock_client2) + # mock_inspect_container.assert_called_once_with("container_id_1") + assert result + + @patch("os.popen") + def test_get_docker_gw_bridge_ip(self, mock_popen) -> None: + """ + Test method that gets the docker gw bridge ip of a container + + :param mock_popen: mock_popen + + :return: None + """ + mock_json_output = json.dumps( + [{constants.DOCKER.CONTAINERS_KEY: {"container_id_1": {constants.DOCKER.IPV4_KEY: "192.168.1.2/24"}}}] + ) + mock_stream = MagicMock() + mock_stream.read.return_value = mock_json_output + mock_popen.return_value = mock_stream + result = DockerUtil.get_docker_gw_bridge_ip("container_id_1") + assert result == "192.168.1.2" diff --git a/simulation-system/libs/csle-common/tests/test_grpc_util.py b/simulation-system/libs/csle-common/tests/test_grpc_util.py index 645f56fb2..b9b885f57 100644 --- a/simulation-system/libs/csle-common/tests/test_grpc_util.py +++ b/simulation-system/libs/csle-common/tests/test_grpc_util.py @@ -5,7 +5,7 @@ class TestGrpcUtilSuite: """ - Test suite for grpc util + Test suite for grpc_util """ @patch("grpc.channel_ready_future") @@ -14,7 +14,6 @@ def test_grpc_server_on(self, mock_channel_ready_future) -> None: Test utility function to test if a given gRPC channel is working or not :param mock_channel_ready_future: mock_channel_ready_future - :return: None """ mock_future = MagicMock() @@ -26,10 +25,9 @@ def test_grpc_server_on(self, mock_channel_ready_future) -> None: @patch("grpc.channel_ready_future") def test_grpc_server_on_timeout(self, mock_channel_ready_future) -> None: """ - Test utility function to test if a given gRPC channel is working or not + Test utility function to test if a given gRPC channel is not working :param mock_channel_ready_future: mock_channel_ready_future - :return: None """ mock_future = MagicMock() diff --git a/simulation-system/libs/csle-common/tests/test_management_util.py b/simulation-system/libs/csle-common/tests/test_management_util.py new file mode 100644 index 000000000..1815e3b62 --- /dev/null +++ b/simulation-system/libs/csle-common/tests/test_management_util.py @@ -0,0 +1,80 @@ +import csle_common.constants.constants as constants +from csle_common.util.management_util import ManagementUtil +from unittest.mock import patch + +class TestManagementUtilSuite: + """ + Test suite for management util + """ + + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_management_users") + @patch("bcrypt.gensalt") + @patch("bcrypt.hashpw") + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.save_management_user") + def test_create_default_management_admin_account( + self, mock_save_management_user, mock_hashpw, mock_gensalt, mock_list_management_users + ) -> None: + """ + Test the method that creates the default management admin account + + :param mock_save_management_user: mock_save_management_user + :param mock_hashpw: mock_hashpw + :param mock_gensalt: mock_gensalt + :param mock_list_management_users: mock_list_management_users + + :return: None + """ + mock_list_management_users.return_value = [] + mock_salt = b"salt" + mock_gensalt.return_value = mock_salt + mock_hash = b"hashed_password" + mock_hashpw.return_value = mock_hash + + constants.CSLE_ADMIN.MANAGEMENT_USER = "admin" + constants.CSLE_ADMIN.MANAGEMENT_PW = "password" + constants.CSLE_ADMIN.MANAGEMENT_FIRST_NAME = "first" + constants.CSLE_ADMIN.MANAGEMENT_LAST_NAME = "last" + constants.CSLE_ADMIN.MANAGEMENT_ORGANIZATION = "organization" + constants.CSLE_ADMIN.MANAGEMENT_EMAIL = "admin@email.com" + + ManagementUtil.create_default_management_admin_account() + mock_list_management_users.assert_called_once() + mock_gensalt.assert_called_once() + mock_hashpw.assert_called_once_with(constants.CSLE_ADMIN.MANAGEMENT_PW.encode("utf-8"), mock_salt) + mock_save_management_user.assert_called_once() + + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_management_users") + @patch("bcrypt.gensalt") + @patch("bcrypt.hashpw") + @patch("csle_common.metastore.metastore_facade.MetastoreFacade.save_management_user") + def test_create_default_management_guest_account( + self, mock_save_management_user, mock_hashpw, mock_gensalt, mock_list_management_users + ) -> None: + """ + Test the method that creates the default management guest account + + :param mock_save_management_user: mock_save_management_user + :param mock_hashpw: mock_hashpw + :param mock_gensalt: mock_gensalt + :param mock_list_management_users: mock_list_management_users + + :return: None + """ + mock_list_management_users.return_value = [] + mock_salt = b"salt" + mock_gensalt.return_value = mock_salt + mock_hash = b"hashed_password" + mock_hashpw.return_value = mock_hash + + constants.CSLE_GUEST.MANAGEMENT_USER = "user" + constants.CSLE_GUEST.MANAGEMENT_PW = "password" + constants.CSLE_GUEST.MANAGEMENT_FIRST_NAME = "guest_first" + constants.CSLE_GUEST.MANAGEMENT_LAST_NAME = "guest_last" + constants.CSLE_GUEST.MANAGEMENT_ORGANIZATION = "guest_organization" + constants.CSLE_GUEST.MANAGEMENT_EMAIL = "guest@email.com" + + ManagementUtil.create_default_management_guest_account() + mock_list_management_users.assert_called_once() + mock_gensalt.assert_called_once() + mock_hashpw.assert_called_once_with(constants.CSLE_GUEST.MANAGEMENT_PW.encode("utf-8"), mock_salt) + mock_save_management_user.assert_called_once() diff --git a/simulation-system/libs/csle-common/tests/test_snort_ids_controller.py b/simulation-system/libs/csle-common/tests/test_snort_ids_controller.py index b077c15d6..70d1ebdae 100644 --- a/simulation-system/libs/csle-common/tests/test_snort_ids_controller.py +++ b/simulation-system/libs/csle-common/tests/test_snort_ids_controller.py @@ -418,6 +418,7 @@ def test_get_snort_managers_info( :param mock_get_ports:mock_get_ports :param mock_get_ips: mock_get_ips + :return: None """ mock_get_ips.return_value = ["10.0.0.1", "10.0.0.2"] diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_emulation_traces.py b/simulation-system/libs/csle-rest-api/tests/test_resources_emulation_traces.py index d836ac27f..9bdc78e75 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_emulation_traces.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_emulation_traces.py @@ -309,7 +309,7 @@ def test_emulation_traces_ids_delete(self, mocker: pytest_mock.MockFixture, flas :param list_em_trac: the list_em_trac fixture :param remove: the remove fixture """ - mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_emulation_traces_ids", + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_trace", side_effect=get_em_tr) mocker.patch("csle_rest_api.util.rest_api_util.check_if_user_is_authorized", side_effect=not_logged_in) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.remove_emulation_trace", diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_emulations_executions.py b/simulation-system/libs/csle-rest-api/tests/test_resources_emulations_executions.py index a79683a75..4b97e0923 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_emulations_executions.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_emulations_executions.py @@ -2168,7 +2168,7 @@ def test_emulation_execution_ids_c_prod_post(self, mocker: pytest_mock.MockFixtu def test_emulation_execution_ids_dcm_post(self, mocker: pytest_mock.MockFixture, flask_app, not_logged_in, logged_in, logged_in_as_admin, get_em_ex, - merged_info, start_dcm, stop_dcm) -> None: + merged_info, start_dcm, stop_dcm, config) -> None: """ Testing the HTTPS GET method for the /emulation-executions/id/docker-stats-manager resource @@ -2182,9 +2182,11 @@ def test_emulation_execution_ids_dcm_post(self, mocker: pytest_mock.MockFixture, :param get_ex_exec: the get_ex_exec fixture :param start_dcm: the start_dcm fixture :param stop_dcm: the stop_dcm fixture + :param config: the config fixture :return: None """ mocker.patch('time.sleep', return_value=None) + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_config", side_effect=config) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_emulation_execution", side_effect=get_em_ex) mocker.patch("csle_cluster.cluster_manager.cluster_controller.ClusterController.get_merged_execution_info", diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_users.py b/simulation-system/libs/csle-rest-api/tests/test_resources_users.py index 31bcc9f28..4e432f735 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_users.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_users.py @@ -325,7 +325,7 @@ def test_users_id_get(self, flask_app, mocker: pytest_mock.MockFixture, manageme assert response.status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE def test_users_id_put(self, flask_app, mocker: pytest_mock.MockFixture, management_users, not_logged_in, - logged_in, authorized, unauthorized, management_config) -> None: + logged_in, authorized, unauthorized, management_config, update) -> None: """ Testing the PUT HTTPS method for the /users/id resource @@ -338,9 +338,12 @@ def test_users_id_put(self, flask_app, mocker: pytest_mock.MockFixture, manageme :param remove: the remove fixture :param logged_in: the logged_in fixture :param authorized: the athourized fixture - :param unauthorized: the unathourized fixture + :param unauthorized: the unauthorized fixture + :param update: the update fixture :return: None """ + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.update_management_user", + side_effect=update) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.list_management_users", side_effect=management_users) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_config",