From 3dd1042880d2b9d97370ed5827be41b15f12dfd9 Mon Sep 17 00:00:00 2001 From: nforsg Date: Fri, 4 Aug 2023 13:39:56 +0200 Subject: [PATCH 1/3] testing done --- .../csle_rest_api/resources/pgadmin/routes.py | 6 +- .../resources/prometheus/routes.py | 6 +- .../src/csle_rest_api/util/rest_api_util.py | 9 +- .../tests/test_resources_pgadmin.py | 6 +- .../tests/test_resources_prometheus.py | 6 +- .../csle-rest-api/tests/test_rest_api_util.py | 179 ++++++++++++++++++ 6 files changed, 201 insertions(+), 11 deletions(-) create mode 100644 simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py index 57017c23d..4ec2b59e8 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py @@ -1,12 +1,14 @@ """ Routes and sub-resources for the /pgadmin resource """ -from typing import Tuple import json +from typing import Tuple + import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_controller import ClusterController from csle_common.metastore.metastore_facade import MetastoreFacade -from flask import Blueprint, jsonify, request, Response +from flask import Blueprint, Response, jsonify, request + import csle_rest_api.constants.constants as api_constants import csle_rest_api.util.rest_api_util as rest_api_util diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py index cad51b750..22d1e8005 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py @@ -1,12 +1,14 @@ """ Routes and sub-resources for the /prometheus resource """ -from typing import Tuple import json +from typing import Tuple + import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_controller import ClusterController from csle_common.metastore.metastore_facade import MetastoreFacade -from flask import Blueprint, jsonify, request, Response +from flask import Blueprint, Response, jsonify, request + import csle_rest_api.constants.constants as api_constants import csle_rest_api.util.rest_api_util as rest_api_util diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py index 8df9e84b7..92e8f82f7 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py @@ -1,9 +1,12 @@ -from typing import Union, Tuple -from flask import jsonify, Response + +from typing import Tuple, Union + import csle_common.constants.constants as constants +from csle_common.dao.management.management_user import ManagementUser from csle_common.metastore.metastore_facade import MetastoreFacade +from flask import Response, jsonify + import csle_rest_api.constants.constants as api_constants -from csle_common.dao.management.management_user import ManagementUser def check_if_user_is_authorized(request, requires_admin: bool = False) -> Union[None, Tuple[Response, int]]: diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py b/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py index e528152b8..ce246aa6f 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py @@ -1,11 +1,13 @@ import json + +import csle_common.constants.constants as constants import pytest import pytest_mock -import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_manager_pb2 import NodeStatusDTO +from csle_common.dao.emulation_config.config import Config + import csle_rest_api.constants.constants as api_constants from csle_rest_api.rest_api import create_app -from csle_common.dao.emulation_config.config import Config class TestResourcespgAdminSuite(): diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py b/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py index a4c3fdc4e..643b720fc 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py @@ -1,11 +1,13 @@ import json + +import csle_common.constants.constants as constants import pytest import pytest_mock -import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_manager_pb2 import NodeStatusDTO +from csle_common.dao.emulation_config.config import Config + import csle_rest_api.constants.constants as api_constants from csle_rest_api.rest_api import create_app -from csle_common.dao.emulation_config.config import Config class TestResourcesPrometheusSuite: diff --git a/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py new file mode 100644 index 000000000..e96758797 --- /dev/null +++ b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py @@ -0,0 +1,179 @@ +import json + +import csle_common.constants.constants as constants +import numpy as np +import pytest +import pytest_mock +from csle_common.dao.management.management_user import ManagementUser +from csle_common.dao.management.session_token import SessionToken +from flask import Flask + +import csle_rest_api.constants.constants as api_constants +import csle_rest_api.util.rest_api_util as rest_api_util +from csle_rest_api.rest_api import create_app + + +class TestUtilSuite: + """ + Test suite for /experiments url + """ + + @pytest.fixture + def flask_app(self): + """ + Gets the Flask app + + :return: the flask app fixture representing the webserver + """ + return create_app(static_folder="../../../../../management-system/csle-mgmt-webapp/build") + + @pytest.fixture + def session_token(self, mocker): + """ + Pytest fixture for mocking the get_session_token_metadata method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def get_session_token_metadata(token: str) -> SessionToken: + return SessionToken(token="null", timestamp=1.5, username="JDoe") + get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) + return get_session_token_metadata_mocker + + @pytest.fixture + def session_token_none(self, mocker): + """ + Pytest fixture for mocking the get_session_token_metadata method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def get_session_token_metadata(token: str) -> None: + return None + get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) + return get_session_token_metadata_mocker + + @pytest.fixture + def session_token_exp(self, mocker): + """ + Pytest fixture for mocking the get_session_token_metadata method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def get_session_token_metadata(token: str) -> SessionToken: + ses_tok = SessionToken(token="null", timestamp=1.5, username="JDoe") + api_constants.SESSION_TOKENS.EXPIRE_TIME_HOURS = np.inf + return ses_tok + get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) + return get_session_token_metadata_mocker + + @pytest.fixture + def management_user(self, mocker): + """ + Pytest fixture for mocking the get_management_user_by_username method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def get_management_user_by_username(username: str) -> ManagementUser: + return ManagementUser(username="JDoe", password="JDoe", email="jdoe@csle.com", + first_name="John", last_name="Doe", organization="CSLE", + admin=False, salt="null") + get_management_user_by_username_mocker = mocker.MagicMock(side_effect=get_management_user_by_username) + return get_management_user_by_username_mocker + + @pytest.fixture + def remove(self, mocker): + """ + Pytest fixture for mocking the reomve_session_token method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def remove_session_token(session_token: SessionToken) -> None: + return None + remove_session_token_mocker = mocker.MagicMock(side_effect=remove_session_token) + return remove_session_token_mocker + + @staticmethod + def get_args(): + class Args(): + def __init__(self) -> None: + pass + + def get(self, token: str): + return None + return Args() + + @staticmethod + def get_synthetic_request(args): + """ + Static help method for returning a synthetic request, customized to work for testing without the use + of blueprint or flask app + """ + class SyntReq(): + def __init__(self, args): + self.args = args + return SyntReq(args) + + def test_util(self, flask_app, mocker: pytest_mock.MockFixture, + session_token, session_token_none, session_token_exp, + management_user, remove): + """ + Test method for the rest-api util + + :param flask_app: the flask_app fixture + :param mocker: the pytest mocker object + :param session_token: the session_token fixture + :param management_user: the management_user fixture + :param remove: the remove fixture + """ + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_session_token_metadata", + side_effect=session_token) + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_by_username", + side_effect=management_user) + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.remove_session_token", + side_effect=remove) + # args = TestUtilSuite.get_args() + # response = flask_app.test_client().get(api_constants.MGMT_WEBAPP.PROMETHEUS_RESOURCE) + # bp = Blueprint("bla", __name__, url_prefix="/bla") + app = Flask(__name__) + with app.app_context(): + args = TestUtilSuite.get_args() + req = TestUtilSuite.get_synthetic_request(args) + response = rest_api_util.check_if_user_is_authorized(request=req) + response_data = response[0].data.decode("utf-8") + response_data_dict = json.loads(response_data) + response_status_code = response[1] + assert response_data_dict == {} + assert response_status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_session_token_metadata", + side_effect=session_token_none) + with app.app_context(): + args = TestUtilSuite.get_args() + req = TestUtilSuite.get_synthetic_request(args) + response = rest_api_util.check_if_user_is_authorized(request=req) + response_data = response[0].data.decode("utf-8") + response_data_dict = json.loads(response_data) + response_status_code = response[1] + assert response_data_dict == {} + assert response_status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_session_token_metadata", + side_effect=session_token_exp) + with app.app_context(): + args = TestUtilSuite.get_args() + req = TestUtilSuite.get_synthetic_request(args) + response = rest_api_util.check_if_user_is_authorized(request=req) + assert response is None + + with app.app_context(): + args = TestUtilSuite.get_args() + req = TestUtilSuite.get_synthetic_request(args) + response = rest_api_util.check_if_user_is_authorized(request=req, + requires_admin=True) + response_data = response[0].data.decode("utf-8") + response_data_dict = json.loads(response_data) + response_status_code = response[1] + assert response_data_dict == {} + assert response_status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE From 4dc588e81bf6942ef41b2cf3013377522eac9358 Mon Sep 17 00:00:00 2001 From: nforsg Date: Fri, 4 Aug 2023 14:52:53 +0200 Subject: [PATCH 2/3] testing done, linter passed, mypy won't understand hinting --- .../src/csle_rest_api/util/rest_api_util.py | 8 +- .../csle-rest-api/tests/test_rest_api_util.py | 102 ++++++++++++------ 2 files changed, 74 insertions(+), 36 deletions(-) diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py index 92e8f82f7..7db120f30 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py @@ -1,4 +1,5 @@ + from typing import Tuple, Union import csle_common.constants.constants as constants @@ -39,7 +40,7 @@ def check_if_user_is_authorized(request, requires_admin: bool = False) -> Union[ return None -def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[None, ManagementUser, +def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[ManagementUser, Tuple[Response, int]]: """ Check if a user is authorized to edit another user @@ -51,7 +52,10 @@ def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[Non # Extract token and check if user is authorized token = request.args.get(api_constants.MGMT_WEBAPP.TOKEN_QUERY_PARAM) token_obj = MetastoreFacade.get_session_token_metadata(token=token) - request_user = MetastoreFacade.get_management_user_by_username(username=token_obj.username) + if token_obj is not None: + request_user = MetastoreFacade.get_management_user_by_username(username=token_obj.username) + else: + request_user = MetastoreFacade.get_management_user_by_username(username=None) if token_obj is None or token_obj.expired(valid_length_hours=api_constants.SESSION_TOKENS.EXPIRE_TIME_HOURS) \ or request_user is None or (not request_user.admin and request_user.username != user.username): if token_obj is not None: diff --git a/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py index e96758797..03754cf19 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py +++ b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py @@ -39,19 +39,6 @@ def get_session_token_metadata(token: str) -> SessionToken: return SessionToken(token="null", timestamp=1.5, username="JDoe") get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) return get_session_token_metadata_mocker - - @pytest.fixture - def session_token_none(self, mocker): - """ - Pytest fixture for mocking the get_session_token_metadata method - - :param mocker: the pytest mocker object - :return: the mocked function - """ - def get_session_token_metadata(token: str) -> None: - return None - get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) - return get_session_token_metadata_mocker @pytest.fixture def session_token_exp(self, mocker): @@ -63,7 +50,7 @@ def session_token_exp(self, mocker): """ def get_session_token_metadata(token: str) -> SessionToken: ses_tok = SessionToken(token="null", timestamp=1.5, username="JDoe") - api_constants.SESSION_TOKENS.EXPIRE_TIME_HOURS = np.inf + api_constants.SESSION_TOKENS.EXPIRE_TIME_HOURS = np.iinfo(np.int32).max return ses_tok get_session_token_metadata_mocker = mocker.MagicMock(side_effect=get_session_token_metadata) return get_session_token_metadata_mocker @@ -77,9 +64,23 @@ def management_user(self, mocker): :return: the mocked function """ def get_management_user_by_username(username: str) -> ManagementUser: - return ManagementUser(username="JDoe", password="JDoe", email="jdoe@csle.com", - first_name="John", last_name="Doe", organization="CSLE", - admin=False, salt="null") + mng_user = TestUtilSuite.get_synthetic_mng_user() + return mng_user + + get_management_user_by_username_mocker = mocker.MagicMock(side_effect=get_management_user_by_username) + return get_management_user_by_username_mocker + + @pytest.fixture + def management_user_none(self, mocker): + """ + Pytest fixture for mocking the get_management_user_by_username method + + :param mocker: the pytest mocker object + :return: the mocked function + """ + def get_management_user_by_username(username: str) -> None: + return None + get_management_user_by_username_mocker = mocker.MagicMock(side_effect=get_management_user_by_username) return get_management_user_by_username_mocker @@ -109,7 +110,7 @@ def get(self, token: str): @staticmethod def get_synthetic_request(args): """ - Static help method for returning a synthetic request, customized to work for testing without the use + Static help method for returning a synthetic/mocked request, customized to work for testing without the use of blueprint or flask app """ class SyntReq(): @@ -117,9 +118,19 @@ def __init__(self, args): self.args = args return SyntReq(args) + @staticmethod + def get_synthetic_mng_user(): + """ + static help method for returning a synthetic/mocked management user + """ + mng_user = ManagementUser(username="JDoe", password="JDoe", email="jdoe@csle.com", + first_name="John", last_name="Doe", organization="CSLE", + admin=False, salt="null") + return mng_user + def test_util(self, flask_app, mocker: pytest_mock.MockFixture, - session_token, session_token_none, session_token_exp, - management_user, remove): + session_token, session_token_exp, + management_user, management_user_none, remove): """ Test method for the rest-api util @@ -135,25 +146,40 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, side_effect=management_user) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.remove_session_token", side_effect=remove) - # args = TestUtilSuite.get_args() - # response = flask_app.test_client().get(api_constants.MGMT_WEBAPP.PROMETHEUS_RESOURCE) - # bp = Blueprint("bla", __name__, url_prefix="/bla") app = Flask(__name__) + mng_user = TestUtilSuite.get_synthetic_mng_user() + args = TestUtilSuite.get_args() + req = TestUtilSuite.get_synthetic_request(args) with app.app_context(): - args = TestUtilSuite.get_args() - req = TestUtilSuite.get_synthetic_request(args) response = rest_api_util.check_if_user_is_authorized(request=req) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, + user=mng_user) response_data = response[0].data.decode("utf-8") response_data_dict = json.loads(response_data) response_status_code = response[1] assert response_data_dict == {} assert response_status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE - mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_session_token_metadata", - side_effect=session_token_none) + response_data1 = response1[0].data.decode("utf-8") + response_data_dict1 = json.loads(response_data1) + response_status_code1 = response1[1] + assert response_data_dict1 == {} + assert response_status_code1 == constants.HTTPS.UNAUTHORIZED_STATUS_CODE + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_by_username", + side_effect=management_user_none) + with app.app_context(): + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, + user=mng_user) + response_data1 = response1[0].data.decode("utf-8") + response_data_dict1 = json.loads(response_data1) + response_status_code1 = response1[1] + assert response_data_dict1 == {} + assert response_status_code1 == constants.HTTPS.UNAUTHORIZED_STATUS_CODE + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_by_username", + side_effect=management_user) with app.app_context(): - args = TestUtilSuite.get_args() - req = TestUtilSuite.get_synthetic_request(args) response = rest_api_util.check_if_user_is_authorized(request=req) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, + user=mng_user) response_data = response[0].data.decode("utf-8") response_data_dict = json.loads(response_data) response_status_code = response[1] @@ -162,14 +188,22 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_session_token_metadata", side_effect=session_token_exp) with app.app_context(): - args = TestUtilSuite.get_args() - req = TestUtilSuite.get_synthetic_request(args) response = rest_api_util.check_if_user_is_authorized(request=req) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, + user=mng_user) assert response is None - + ex_mng_user = TestUtilSuite.get_synthetic_mng_user() + assert response1.username == ex_mng_user.username + assert response1.password == ex_mng_user.password + assert response1.admin == ex_mng_user.admin + assert response1.id == ex_mng_user.id + assert response1.salt == ex_mng_user.salt + assert response1.email == ex_mng_user.email + assert response1.first_name == ex_mng_user.first_name + assert response1.last_name == ex_mng_user.last_name + assert response1.organization == ex_mng_user.organization + assert response_status_code1 == constants.HTTPS.UNAUTHORIZED_STATUS_CODE with app.app_context(): - args = TestUtilSuite.get_args() - req = TestUtilSuite.get_synthetic_request(args) response = rest_api_util.check_if_user_is_authorized(request=req, requires_admin=True) response_data = response[0].data.decode("utf-8") From d1135d7c1b97ca93265b73ee0a05115ee9739ecd Mon Sep 17 00:00:00 2001 From: Limmen Date: Tue, 8 Aug 2023 14:31:42 +0200 Subject: [PATCH 3/3] fix mypy --- .../libs/csle-cli/src/csle_cli/cli.py | 8 +- .../csle_rest_api/resources/pgadmin/routes.py | 6 +- .../resources/prometheus/routes.py | 6 +- .../src/csle_rest_api/util/rest_api_util.py | 11 +- .../tests/test_resources_pgadmin.py | 6 +- .../tests/test_resources_prometheus.py | 4 +- .../csle-rest-api/tests/test_rest_api_util.py | 112 +++++++++++------- .../csle_system_identification/emulator.py | 2 +- 8 files changed, 86 insertions(+), 69 deletions(-) diff --git a/simulation-system/libs/csle-cli/src/csle_cli/cli.py b/simulation-system/libs/csle-cli/src/csle_cli/cli.py index f2b4bef7e..cd3116603 100755 --- a/simulation-system/libs/csle-cli/src/csle_cli/cli.py +++ b/simulation-system/libs/csle-cli/src/csle_cli/cli.py @@ -10,8 +10,8 @@ from csle_common.util.cluster_util import ClusterUtil from csle_common.util.general_util import GeneralUtil from csle_cluster.cluster_manager.cluster_controller import ClusterController -from csle_cluster.cluster_manager.cluster_manager_pb2 import DockerContainerDTO, ContainerImageDTO from typing import TYPE_CHECKING + if TYPE_CHECKING: from csle_common.dao.emulation_config.emulation_env_state import EmulationEnvState from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig @@ -643,7 +643,7 @@ def stop_shell_complete(ctx, param, incomplete) -> List[str]: emulations=MetastoreFacade.list_emulations()) emulations: List[str] = running_emulations running_containers = ContainerController.list_all_running_containers() - containers: List[Tuple[str, str ,str]] = running_containers + containers: List[Tuple[str, str, str]] = running_containers container_names: List[str] = list(map(lambda x: x[0], containers)) return ["prometheus", "node_exporter", "cadvisor", "pgadmin", "grafana", "flask", "statsmanager", "all", "emulation_executions"] + emulations + container_names @@ -1039,7 +1039,7 @@ def start_shell_complete(ctx, param, incomplete) -> List[str]: emulations=MetastoreFacade.list_emulations()) emulations = stopped_emulations stopped_containers = ContainerController.list_all_stopped_containers() - containers: List[Tuple[str, str ,str]] = stopped_containers + containers: List[Tuple[str, str, str]] = stopped_containers container_names: List[str] = list(map(lambda x: x[0], containers)) images: List[Tuple[str, str, str, str, str]] = ContainerController.list_all_images() image_names: List[str] = list(map(lambda x: x[0], images)) @@ -1313,7 +1313,7 @@ def rm_shell_complete(ctx, param, incomplete) -> List[str]: emulations = list(map(lambda x: x.name, MetastoreFacade.list_emulations())) running_containers = ContainerController.list_all_running_containers() stopped_containers = ContainerController.list_all_stopped_containers() - containers: List[Tuple[str, str ,str]] = running_containers + stopped_containers + containers: List[Tuple[str, str, str]] = running_containers + stopped_containers container_names: List[str] = list(map(lambda x: x[0], containers)) images: List[Tuple[str, str, str, str, str]] = ContainerController.list_all_images() image_names: List[str] = list(map(lambda x: x[0], images)) diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py index 4ec2b59e8..45578ed2f 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/pgadmin/routes.py @@ -1,14 +1,12 @@ """ Routes and sub-resources for the /pgadmin resource """ -import json from typing import Tuple - +import json +from flask import Blueprint, Response, jsonify, request import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_controller import ClusterController from csle_common.metastore.metastore_facade import MetastoreFacade -from flask import Blueprint, Response, jsonify, request - import csle_rest_api.constants.constants as api_constants import csle_rest_api.util.rest_api_util as rest_api_util diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py index 22d1e8005..d82189bb5 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/resources/prometheus/routes.py @@ -1,14 +1,12 @@ """ Routes and sub-resources for the /prometheus resource """ -import json from typing import Tuple - +import json +from flask import Blueprint, Response, jsonify, request import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_controller import ClusterController from csle_common.metastore.metastore_facade import MetastoreFacade -from flask import Blueprint, Response, jsonify, request - import csle_rest_api.constants.constants as api_constants import csle_rest_api.util.rest_api_util as rest_api_util diff --git a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py index 7db120f30..793a5895d 100644 --- a/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py +++ b/simulation-system/libs/csle-rest-api/src/csle_rest_api/util/rest_api_util.py @@ -1,12 +1,8 @@ - - from typing import Tuple, Union - +from flask import Response, jsonify import csle_common.constants.constants as constants from csle_common.dao.management.management_user import ManagementUser from csle_common.metastore.metastore_facade import MetastoreFacade -from flask import Response, jsonify - import csle_rest_api.constants.constants as api_constants @@ -40,7 +36,7 @@ def check_if_user_is_authorized(request, requires_admin: bool = False) -> Union[ return None -def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[ManagementUser, +def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[None, ManagementUser, Tuple[Response, int]]: """ Check if a user is authorized to edit another user @@ -52,10 +48,9 @@ def check_if_user_edit_is_authorized(request, user: ManagementUser) -> Union[Man # Extract token and check if user is authorized token = request.args.get(api_constants.MGMT_WEBAPP.TOKEN_QUERY_PARAM) token_obj = MetastoreFacade.get_session_token_metadata(token=token) + request_user = None if token_obj is not None: request_user = MetastoreFacade.get_management_user_by_username(username=token_obj.username) - else: - request_user = MetastoreFacade.get_management_user_by_username(username=None) if token_obj is None or token_obj.expired(valid_length_hours=api_constants.SESSION_TOKENS.EXPIRE_TIME_HOURS) \ or request_user is None or (not request_user.admin and request_user.username != user.username): if token_obj is not None: diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py b/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py index ce246aa6f..76e204190 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_pgadmin.py @@ -1,16 +1,14 @@ import json - -import csle_common.constants.constants as constants import pytest import pytest_mock +import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_manager_pb2 import NodeStatusDTO from csle_common.dao.emulation_config.config import Config - import csle_rest_api.constants.constants as api_constants from csle_rest_api.rest_api import create_app -class TestResourcespgAdminSuite(): +class TestResourcespgAdminSuite: """ Test suite for /pgadmin resource """ diff --git a/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py b/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py index 643b720fc..75ed1dc08 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py +++ b/simulation-system/libs/csle-rest-api/tests/test_resources_prometheus.py @@ -1,11 +1,9 @@ import json - -import csle_common.constants.constants as constants import pytest import pytest_mock +import csle_common.constants.constants as constants from csle_cluster.cluster_manager.cluster_manager_pb2 import NodeStatusDTO from csle_common.dao.emulation_config.config import Config - import csle_rest_api.constants.constants as api_constants from csle_rest_api.rest_api import create_app diff --git a/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py index 03754cf19..505c03c40 100644 --- a/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py +++ b/simulation-system/libs/csle-rest-api/tests/test_rest_api_util.py @@ -1,23 +1,52 @@ import json - -import csle_common.constants.constants as constants import numpy as np import pytest import pytest_mock +from flask import Flask +import csle_common.constants.constants as constants from csle_common.dao.management.management_user import ManagementUser from csle_common.dao.management.session_token import SessionToken -from flask import Flask - import csle_rest_api.constants.constants as api_constants import csle_rest_api.util.rest_api_util as rest_api_util from csle_rest_api.rest_api import create_app -class TestUtilSuite: +class TestRestAPIUtilSuite: """ Test suite for /experiments url """ + class SyntReq: + """ + Mock class for synt reg + """ + def __init__(self, args) -> None: + """ + Initializes the object + + :param args: the arguments for syntreg + """ + self.args = args + + class Args: + """ + Mock class for syntehtic arguments to a request + """ + def __init__(self) -> None: + """ + Initializes the object + """ + pass + + def get(self, token: str) -> None: + """ + Mocks the get method of the arguments + + :param token: the token for authentication + :return: None + """ + return None + @pytest.fixture def flask_app(self): """ @@ -28,7 +57,7 @@ def flask_app(self): return create_app(static_folder="../../../../../management-system/csle-mgmt-webapp/build") @pytest.fixture - def session_token(self, mocker): + def session_token(self, mocker: pytest_mock.MockFixture): """ Pytest fixture for mocking the get_session_token_metadata method @@ -41,7 +70,7 @@ def get_session_token_metadata(token: str) -> SessionToken: return get_session_token_metadata_mocker @pytest.fixture - def session_token_exp(self, mocker): + def session_token_exp(self, mocker: pytest_mock.MockFixture): """ Pytest fixture for mocking the get_session_token_metadata method @@ -56,7 +85,7 @@ def get_session_token_metadata(token: str) -> SessionToken: return get_session_token_metadata_mocker @pytest.fixture - def management_user(self, mocker): + def management_user(self, mocker: pytest_mock.MockFixture): """ Pytest fixture for mocking the get_management_user_by_username method @@ -64,14 +93,14 @@ def management_user(self, mocker): :return: the mocked function """ def get_management_user_by_username(username: str) -> ManagementUser: - mng_user = TestUtilSuite.get_synthetic_mng_user() + mng_user = TestRestAPIUtilSuite.get_synthetic_mng_user() return mng_user get_management_user_by_username_mocker = mocker.MagicMock(side_effect=get_management_user_by_username) return get_management_user_by_username_mocker @pytest.fixture - def management_user_none(self, mocker): + def management_user_none(self, mocker: pytest_mock.MockFixture): """ Pytest fixture for mocking the get_management_user_by_username method @@ -85,7 +114,7 @@ def get_management_user_by_username(username: str) -> None: return get_management_user_by_username_mocker @pytest.fixture - def remove(self, mocker): + def remove(self, mocker: pytest_mock.MockFixture): """ Pytest fixture for mocking the reomve_session_token method @@ -98,30 +127,31 @@ def remove_session_token(session_token: SessionToken) -> None: return remove_session_token_mocker @staticmethod - def get_args(): - class Args(): - def __init__(self) -> None: - pass + def get_args() -> Args: + """ + Returns a mock request argument - def get(self, token: str): - return None - return Args() + :return: the mocked request argument + """ + return TestRestAPIUtilSuite.Args() @staticmethod - def get_synthetic_request(args): + def get_synthetic_request(args) -> SyntReq: """ Static help method for returning a synthetic/mocked request, customized to work for testing without the use of blueprint or flask app + + :param args: the arguments for the mock request + :return: the syntethic request """ - class SyntReq(): - def __init__(self, args): - self.args = args - return SyntReq(args) + return TestRestAPIUtilSuite.SyntReq(args) @staticmethod - def get_synthetic_mng_user(): + def get_synthetic_mng_user() -> ManagementUser: """ - static help method for returning a synthetic/mocked management user + Static help method for returning a synthetic/mocked management user + + :return: the mocked management user """ mng_user = ManagementUser(username="JDoe", password="JDoe", email="jdoe@csle.com", first_name="John", last_name="Doe", organization="CSLE", @@ -144,21 +174,21 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, side_effect=session_token) mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_by_username", side_effect=management_user) - mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.remove_session_token", - side_effect=remove) + mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.remove_session_token", side_effect=remove) app = Flask(__name__) - mng_user = TestUtilSuite.get_synthetic_mng_user() - args = TestUtilSuite.get_args() - req = TestUtilSuite.get_synthetic_request(args) + mng_user = TestRestAPIUtilSuite.get_synthetic_mng_user() + args = TestRestAPIUtilSuite.get_args() + req = TestRestAPIUtilSuite.get_synthetic_request(args) with app.app_context(): response = rest_api_util.check_if_user_is_authorized(request=req) - response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, - user=mng_user) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, user=mng_user) + assert response is not None response_data = response[0].data.decode("utf-8") response_data_dict = json.loads(response_data) response_status_code = response[1] assert response_data_dict == {} assert response_status_code == constants.HTTPS.UNAUTHORIZED_STATUS_CODE + assert response1 is not None response_data1 = response1[0].data.decode("utf-8") response_data_dict1 = json.loads(response_data1) response_status_code1 = response1[1] @@ -167,8 +197,8 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, mocker.patch("csle_common.metastore.metastore_facade.MetastoreFacade.get_management_user_by_username", side_effect=management_user_none) with app.app_context(): - response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, - user=mng_user) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, user=mng_user) + assert response1 is not None response_data1 = response1[0].data.decode("utf-8") response_data_dict1 = json.loads(response_data1) response_status_code1 = response1[1] @@ -178,8 +208,7 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, side_effect=management_user) with app.app_context(): response = rest_api_util.check_if_user_is_authorized(request=req) - response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, - user=mng_user) + assert response is not None response_data = response[0].data.decode("utf-8") response_data_dict = json.loads(response_data) response_status_code = response[1] @@ -189,10 +218,11 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, side_effect=session_token_exp) with app.app_context(): response = rest_api_util.check_if_user_is_authorized(request=req) - response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, - user=mng_user) + response1 = rest_api_util.check_if_user_edit_is_authorized(request=req, user=mng_user) assert response is None - ex_mng_user = TestUtilSuite.get_synthetic_mng_user() + assert response1 is not None + assert isinstance(response1, ManagementUser) + ex_mng_user = TestRestAPIUtilSuite.get_synthetic_mng_user() assert response1.username == ex_mng_user.username assert response1.password == ex_mng_user.password assert response1.admin == ex_mng_user.admin @@ -204,8 +234,8 @@ def test_util(self, flask_app, mocker: pytest_mock.MockFixture, assert response1.organization == ex_mng_user.organization assert response_status_code1 == constants.HTTPS.UNAUTHORIZED_STATUS_CODE with app.app_context(): - response = rest_api_util.check_if_user_is_authorized(request=req, - requires_admin=True) + response = rest_api_util.check_if_user_is_authorized(request=req, requires_admin=True) + assert response is not None response_data = response[0].data.decode("utf-8") response_data_dict = json.loads(response_data) response_status_code = response[1] diff --git a/simulation-system/libs/csle-system-identification/src/csle_system_identification/emulator.py b/simulation-system/libs/csle-system-identification/src/csle_system_identification/emulator.py index fc0221dac..2edeb79ff 100644 --- a/simulation-system/libs/csle-system-identification/src/csle_system_identification/emulator.py +++ b/simulation-system/libs/csle-system-identification/src/csle_system_identification/emulator.py @@ -1,4 +1,4 @@ -from typing import List, Tuple, Optional +from typing import List, Tuple import time import os import sys